Detect embedded subtitle tracks in analyzers
Add a subtitle branch to the ffprobe/avprobe stream loops that collects each embedded subtitle track (index, codec, language, title, default/ forced flags) and classifies it as text or image by codec. This is the basis for letting the user pick a track to burn into the picture. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
75aa10e4c8
commit
a158119d41
3 changed files with 48 additions and 0 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
src/devedeng/data/locale/
|
||||||
|
|
@ -90,6 +90,8 @@ class avprobe(devedeng.avbase.avbase):
|
||||||
self.original_fps = 0
|
self.original_fps = 0
|
||||||
self.original_aspect_ratio = None
|
self.original_aspect_ratio = None
|
||||||
self.prerotation = 0
|
self.prerotation = 0
|
||||||
|
# embedded subtitle tracks (see ffprobe.process_json for the schema)
|
||||||
|
self.subtitle_tracks = []
|
||||||
|
|
||||||
self.config.append_static_log(
|
self.config.append_static_log(
|
||||||
"Getting data for {:s} with avprobe".format(file_name))
|
"Getting data for {:s} with avprobe".format(file_name))
|
||||||
|
|
@ -136,6 +138,23 @@ class avprobe(devedeng.avbase.avbase):
|
||||||
self.original_audiorate_uncompressed = int(
|
self.original_audiorate_uncompressed = int(
|
||||||
float(element["sample_rate"]))
|
float(element["sample_rate"]))
|
||||||
|
|
||||||
|
elif (element["codec_type"] == "subtitle"):
|
||||||
|
codec = element.get("codec_name", "")
|
||||||
|
image_codecs = ("hdmv_pgs_subtitle", "pgssub", "dvd_subtitle",
|
||||||
|
"dvdsub", "xsub")
|
||||||
|
kind = "image" if codec in image_codecs else "text"
|
||||||
|
tags = element.get("tags", {})
|
||||||
|
disposition = element.get("disposition", {})
|
||||||
|
self.subtitle_tracks.append({
|
||||||
|
"index": element["index"],
|
||||||
|
"codec": codec,
|
||||||
|
"language": tags.get("language", ""),
|
||||||
|
"title": tags.get("title", ""),
|
||||||
|
"default": bool(disposition.get("default", 0)),
|
||||||
|
"forced": bool(disposition.get("forced", 0)),
|
||||||
|
"kind": kind,
|
||||||
|
})
|
||||||
|
|
||||||
self.original_size = str(self.original_width) + "x" + str(self.original_height)
|
self.original_size = str(self.original_width) + "x" + str(self.original_height)
|
||||||
if (self.original_aspect_ratio is None):
|
if (self.original_aspect_ratio is None):
|
||||||
if (self.original_height != 0):
|
if (self.original_height != 0):
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,9 @@ class ffprobe(devedeng.executor.executor):
|
||||||
self.audio_streams = 0
|
self.audio_streams = 0
|
||||||
self.video_list = []
|
self.video_list = []
|
||||||
self.video_streams = 0
|
self.video_streams = 0
|
||||||
|
# embedded subtitle tracks: list of dicts with index, codec, language,
|
||||||
|
# title, default/forced flags, and "kind" ("text" or "image")
|
||||||
|
self.subtitle_tracks = []
|
||||||
self.original_width = 0
|
self.original_width = 0
|
||||||
self.original_height = 0
|
self.original_height = 0
|
||||||
self.original_length = -1
|
self.original_length = -1
|
||||||
|
|
@ -135,6 +138,25 @@ class ffprobe(devedeng.executor.executor):
|
||||||
self.original_audiorate_uncompressed = int(
|
self.original_audiorate_uncompressed = int(
|
||||||
float(element["sample_rate"]))
|
float(element["sample_rate"]))
|
||||||
|
|
||||||
|
elif (element["codec_type"] == "subtitle"):
|
||||||
|
codec = element.get("codec_name", "")
|
||||||
|
# bitmap (image) subtitles can't be burned with the text
|
||||||
|
# `subtitles` filter; they must be overlaid instead
|
||||||
|
image_codecs = ("hdmv_pgs_subtitle", "pgssub", "dvd_subtitle",
|
||||||
|
"dvdsub", "xsub")
|
||||||
|
kind = "image" if codec in image_codecs else "text"
|
||||||
|
tags = element.get("tags", {})
|
||||||
|
disposition = element.get("disposition", {})
|
||||||
|
self.subtitle_tracks.append({
|
||||||
|
"index": element["index"],
|
||||||
|
"codec": codec,
|
||||||
|
"language": tags.get("language", ""),
|
||||||
|
"title": tags.get("title", ""),
|
||||||
|
"default": bool(disposition.get("default", 0)),
|
||||||
|
"forced": bool(disposition.get("forced", 0)),
|
||||||
|
"kind": kind,
|
||||||
|
})
|
||||||
|
|
||||||
self.original_size = str(self.original_width) + "x" + str(self.original_height)
|
self.original_size = str(self.original_width) + "x" + str(self.original_height)
|
||||||
if (self.original_aspect_ratio is None):
|
if (self.original_aspect_ratio is None):
|
||||||
if (self.original_height != 0):
|
if (self.original_height != 0):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue