index streams and file size
This commit is contained in:
parent
a4d42573ef
commit
a17f05ef21
|
@ -146,6 +146,9 @@
|
|||
"type": "keyword",
|
||||
"index": false
|
||||
},
|
||||
"media_size": {
|
||||
"type": "long"
|
||||
},
|
||||
"tags": {
|
||||
"type": "text",
|
||||
"analyzer": "english",
|
||||
|
@ -239,6 +242,30 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"streams": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "keyword",
|
||||
"index": false
|
||||
},
|
||||
"index": {
|
||||
"type": "short",
|
||||
"index": false
|
||||
},
|
||||
"codec": {
|
||||
"type": "text"
|
||||
},
|
||||
"width": {
|
||||
"type": "short"
|
||||
},
|
||||
"height": {
|
||||
"type": "short"
|
||||
},
|
||||
"bitrate": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sponsorblock": {
|
||||
"properties": {
|
||||
"last_refresh": {
|
||||
|
|
|
@ -16,7 +16,10 @@ from home.src.index import playlist as ta_playlist
|
|||
from home.src.index.generic import YouTubeItem
|
||||
from home.src.index.subtitle import YoutubeSubtitle
|
||||
from home.src.index.video_constants import VideoTypeEnum
|
||||
from home.src.index.video_streams import DurationConverter
|
||||
from home.src.index.video_streams import (
|
||||
DurationConverter,
|
||||
MediaStreamExtractor,
|
||||
)
|
||||
from home.src.ta.helper import clean_string, randomizor
|
||||
from home.src.ta.ta_redis import RedisArchivist
|
||||
from ryd_client import ryd_client
|
||||
|
@ -153,6 +156,7 @@ class YoutubeVideo(YouTubeItem, YoutubeSubtitle):
|
|||
self._add_stats()
|
||||
self.add_file_path()
|
||||
self.add_player(media_path)
|
||||
self.add_streams(media_path)
|
||||
if self.config["downloads"]["integrate_ryd"]:
|
||||
self._get_ryd_stats()
|
||||
|
||||
|
@ -254,6 +258,17 @@ class YoutubeVideo(YouTubeItem, YoutubeSubtitle):
|
|||
}
|
||||
)
|
||||
|
||||
def add_streams(self, media_path=False):
|
||||
"""add stream metadata"""
|
||||
vid_path = self._get_vid_path(media_path)
|
||||
media = MediaStreamExtractor(vid_path)
|
||||
self.json_data.update(
|
||||
{
|
||||
"streams": media.extract_metadata(),
|
||||
"media_size": media.get_file_size(),
|
||||
}
|
||||
)
|
||||
|
||||
def _get_vid_path(self, media_path=False):
|
||||
"""get path of media file"""
|
||||
if media_path:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"""extract metadata from video streams"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from os import stat
|
||||
|
||||
|
||||
class DurationConverter:
|
||||
|
@ -52,3 +54,79 @@ class DurationConverter:
|
|||
duration_str = duration_str + "00:"
|
||||
duration_str = duration_str + str(secs).zfill(2)
|
||||
return duration_str
|
||||
|
||||
|
||||
class MediaStreamExtractor:
|
||||
"""extract stream metadata"""
|
||||
|
||||
def __init__(self, media_path):
|
||||
self.media_path = media_path
|
||||
self.metadata = []
|
||||
|
||||
def extract_metadata(self):
|
||||
"""entry point to extract metadata"""
|
||||
|
||||
cmd = [
|
||||
"ffprobe",
|
||||
"-v",
|
||||
"quiet",
|
||||
"-print_format",
|
||||
"json",
|
||||
"-show_streams",
|
||||
"-show_format",
|
||||
self.media_path,
|
||||
]
|
||||
result = subprocess.run(
|
||||
cmd, capture_output=True, text=True, check=False
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
return self.metadata
|
||||
|
||||
streams = json.loads(result.stdout).get("streams")
|
||||
for stream in streams:
|
||||
self.process_stream(stream)
|
||||
|
||||
return self.metadata
|
||||
|
||||
def process_stream(self, stream):
|
||||
"""parse stream to metadata"""
|
||||
codec_type = stream.get("codec_type")
|
||||
if codec_type == "video":
|
||||
self._extract_video_metadata(stream)
|
||||
elif codec_type == "audio":
|
||||
self._extract_audio_metadata(stream)
|
||||
else:
|
||||
return
|
||||
|
||||
def _extract_video_metadata(self, stream):
|
||||
"""parse video metadata"""
|
||||
if "bit_rate" not in stream:
|
||||
# is probably thumbnail
|
||||
return
|
||||
|
||||
self.metadata.append(
|
||||
{
|
||||
"type": "video",
|
||||
"index": stream["index"],
|
||||
"codec": stream["codec_name"],
|
||||
"width": stream["width"],
|
||||
"height": stream["height"],
|
||||
"bitrate": int(stream["bit_rate"]),
|
||||
}
|
||||
)
|
||||
|
||||
def _extract_audio_metadata(self, stream):
|
||||
"""extract audio metadata"""
|
||||
self.metadata.append(
|
||||
{
|
||||
"type": "audio",
|
||||
"index": stream["index"],
|
||||
"codec": stream["codec_name"],
|
||||
"bitrate": int(stream["bit_rate"]),
|
||||
}
|
||||
)
|
||||
|
||||
def get_file_size(self):
|
||||
"""get filesize in bytes"""
|
||||
return stat(self.media_path).st_size
|
||||
|
|
|
@ -56,20 +56,6 @@
|
|||
{% else %}
|
||||
<p>Youtube: Deactivated</p>
|
||||
{% endif %}
|
||||
{% if reindex %}
|
||||
<p>Reindex scheduled</p>
|
||||
{% else %}
|
||||
<div id="reindex-button" class="button-box">
|
||||
<button data-id="{{ video.youtube_id }}" data-type="video" onclick="reindex(this)" title="Reindex {{ video.title }}">Reindex</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="button-box">
|
||||
<a download="" href="/media/{{ video.media_url }}"><button id="download-item">Download File</button></a>
|
||||
<button onclick="deleteConfirm()" id="delete-item">Delete Video</button>
|
||||
<div class="delete-confirm" id="delete-button">
|
||||
<span>Are you sure? </span><button class="danger-button" onclick="deleteVideo(this)" data-id="{{ video.youtube_id }}" data-redirect = "{{ video.channel.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box-item">
|
||||
|
@ -89,6 +75,34 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box info-box-2">
|
||||
<div class="info-box-item">
|
||||
<div class="button-box">
|
||||
{% if reindex %}
|
||||
<p>Reindex scheduled</p>
|
||||
{% else %}
|
||||
<div id="reindex-button" class="button-box">
|
||||
<button data-id="{{ video.youtube_id }}" data-type="video" onclick="reindex(this)" title="Reindex {{ video.title }}">Reindex</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<a download="" href="/media/{{ video.media_url }}"><button id="download-item">Download File</button></a>
|
||||
<button onclick="deleteConfirm()" id="delete-item">Delete Video</button>
|
||||
<div class="delete-confirm" id="delete-button">
|
||||
<span>Are you sure? </span><button class="danger-button" onclick="deleteVideo(this)" data-id="{{ video.youtube_id }}" data-redirect = "{{ video.channel.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box-item">
|
||||
{% if video.media_size %}
|
||||
<p>File size: {{ video.media_size|filesizeformat }}</p>
|
||||
{% endif %}
|
||||
{% if video.streams %}
|
||||
{% for stream in video.streams %}
|
||||
<p>{{ stream.type|title }}: {{ stream.codec }} {{ stream.bitrate|filesizeformat }}/s{% if stream.width %} <span class="space-carrot">|</span> {{ stream.width }}x{{ stream.height}}{% endif %}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if video.tags %}
|
||||
<div class="description-box">
|
||||
<div class="video-tag-box">
|
||||
|
|
|
@ -660,6 +660,10 @@ video:-webkit-full-screen {
|
|||
background-color: var(--highlight-bg);
|
||||
}
|
||||
|
||||
.info-box-item p {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue