Add DVD encode profiles and subtitle hardsub burn-in
Introduce three project-level DVD encode profiles (Compatibility 4500k / High quality VBR / Custom) via new config keys, and burn a chosen embedded subtitle track into the picture: - file_movie carries the hardsub selection (index/kind), persists it, and builds a subtitle-picker combobox in its properties page; set_final_rates maps the profile to the final video/audio bitrate. - ffmpeg burns text subs with the subtitles= filter after scaling and image subs with an overlay filtergraph before scaling; NTSC DVD audio is now AC3 for all profiles. A start_offset (-ss) is threaded through for segmenting. - avconv gets the text-sub path and start_offset for parity. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a158119d41
commit
8b041f0725
4 changed files with 310 additions and 13 deletions
|
|
@ -112,8 +112,9 @@ class avconv(devedeng.avbase.avbase):
|
|||
self.config = devedeng.configuration_data.configuration.get_config()
|
||||
self.check_version(["avconv", "-version"])
|
||||
|
||||
def convert_file(self, file_project, output_file, video_length, pass2=False):
|
||||
def convert_file(self, file_project, output_file, video_length, pass2=False, start_offset=0):
|
||||
|
||||
self.start_offset = start_offset
|
||||
if file_project.two_pass_encoding:
|
||||
if pass2:
|
||||
self.text = _("Converting %(X)s (pass 2)") % {
|
||||
|
|
@ -123,7 +124,8 @@ class avconv(devedeng.avbase.avbase):
|
|||
"X": file_project.title_name}
|
||||
# Prepare the converting process for the second pass
|
||||
tmp = devedeng.avconv.avconv()
|
||||
tmp.convert_file(file_project, output_file, video_length, True)
|
||||
tmp.convert_file(file_project, output_file, video_length, True,
|
||||
start_offset)
|
||||
# it deppends of this process
|
||||
tmp.add_dependency(self)
|
||||
# add it as a child process of this one
|
||||
|
|
@ -147,6 +149,9 @@ class avconv(devedeng.avbase.avbase):
|
|||
self.final_length = video_length
|
||||
self.command_var = []
|
||||
self.command_var.append("avconv")
|
||||
if start_offset and start_offset > 0:
|
||||
self.command_var.append("-ss")
|
||||
self.command_var.append(str(start_offset))
|
||||
self.command_var.append("-i")
|
||||
self.command_var.append(file_project.file_name)
|
||||
|
||||
|
|
@ -159,6 +164,9 @@ class avconv(devedeng.avbase.avbase):
|
|||
self.command_var.append("-itsoffset")
|
||||
self.command_var.append(str(file_project.audio_delay))
|
||||
|
||||
if start_offset and start_offset > 0:
|
||||
self.command_var.append("-ss")
|
||||
self.command_var.append(str(start_offset))
|
||||
self.command_var.append("-i")
|
||||
self.command_var.append(file_project.file_name)
|
||||
self.command_var.append("-map")
|
||||
|
|
@ -243,6 +251,16 @@ class avconv(devedeng.avbase.avbase):
|
|||
str(file_project.width_final) + ":h=" + \
|
||||
str(file_project.height_final)
|
||||
|
||||
# text subtitle burn-in (hardsub) as the last filter, after scaling.
|
||||
# Image-based subs need an overlay filtergraph and are only handled
|
||||
# by the ffmpeg backend; avconv users get text subs burned in.
|
||||
if second_pass:
|
||||
text_filter = self._avconv_text_subtitle_filter(file_project)
|
||||
if text_filter is not None:
|
||||
if (cmd_line != ""):
|
||||
cmd_line += ",fifo,"
|
||||
cmd_line += text_filter
|
||||
|
||||
if cmd_line != "":
|
||||
self.command_var.append("-vf")
|
||||
self.command_var.append(cmd_line)
|
||||
|
|
@ -519,6 +537,27 @@ class avconv(devedeng.avbase.avbase):
|
|||
return a
|
||||
return 384
|
||||
|
||||
def _avconv_text_subtitle_filter(self, file_project):
|
||||
""" Build a `subtitles=` filter to burn a text-based embedded subtitle
|
||||
track into the picture, or None. Image-based subs are not handled by
|
||||
the avconv backend (use the ffmpeg backend for those). """
|
||||
if getattr(file_project, "hardsub_kind", "text") != "text":
|
||||
return None
|
||||
index = getattr(file_project, "hardsub_index", -1)
|
||||
if index is None or index < 0:
|
||||
return None
|
||||
subs = getattr(file_project, "embedded_subtitles", []) or []
|
||||
rel = None
|
||||
for i, track in enumerate(subs):
|
||||
if track["index"] == index:
|
||||
rel = i
|
||||
break
|
||||
if rel is None:
|
||||
return None
|
||||
path = file_project.file_name.replace("\\", "\\\\").replace(":", "\\:")
|
||||
path = path.replace("'", "\\'")
|
||||
return "subtitles='%s':si=%d" % (path, rel)
|
||||
|
||||
def create_menu_mpeg(self, n_page, background_music, sound_length, pal, video_rate, audio_rate, output_path, use_mp2, widescreen):
|
||||
|
||||
self.n_page = n_page
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue