Adjust long video caption timing to start after 2s and show for 6s
This commit is contained in:
parent
2ae7c75f91
commit
7d23a71947
1 changed files with 51 additions and 9 deletions
60
movmaker.py
60
movmaker.py
|
|
@ -60,6 +60,9 @@ CLIP_AUDIO_SIDECHAIN_THRESHOLD = 0.04
|
||||||
CLIP_AUDIO_SIDECHAIN_RATIO = 8.0
|
CLIP_AUDIO_SIDECHAIN_RATIO = 8.0
|
||||||
CLIP_AUDIO_SIDECHAIN_ATTACK = 5.0
|
CLIP_AUDIO_SIDECHAIN_ATTACK = 5.0
|
||||||
CLIP_AUDIO_SIDECHAIN_RELEASE = 250.0
|
CLIP_AUDIO_SIDECHAIN_RELEASE = 250.0
|
||||||
|
CAPTION_LONG_VIDEO_MIN_DURATION = 10.0
|
||||||
|
CAPTION_LONG_VIDEO_DELAY = 2.0
|
||||||
|
CAPTION_LONG_VIDEO_SHOW = 6.0
|
||||||
|
|
||||||
|
|
||||||
ORDER_FILENAME = "order.json"
|
ORDER_FILENAME = "order.json"
|
||||||
|
|
@ -988,6 +991,7 @@ def build_video(
|
||||||
video_intro_duration: float | None = None,
|
video_intro_duration: float | None = None,
|
||||||
intro_visible_lead: float = 0.0,
|
intro_visible_lead: float = 0.0,
|
||||||
skip_video_fade_out: bool = False,
|
skip_video_fade_out: bool = False,
|
||||||
|
clip_kinds: list[str] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Assemble normalized clips, overlays, and audio into the final MP4."""
|
"""Assemble normalized clips, overlays, and audio into the final MP4."""
|
||||||
output.parent.mkdir(parents=True, exist_ok=True)
|
output.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
@ -1132,17 +1136,26 @@ def build_video(
|
||||||
if not caption:
|
if not caption:
|
||||||
continue
|
continue
|
||||||
if n == 1:
|
if n == 1:
|
||||||
start = intro_duration
|
base_start = intro_duration
|
||||||
end = total_duration
|
base_end = total_duration
|
||||||
elif idx == 0:
|
elif idx == 0:
|
||||||
start = intro_duration
|
base_start = intro_duration
|
||||||
end = intro_duration + transition_offsets[0]
|
base_end = intro_duration + transition_offsets[0]
|
||||||
elif idx == n - 1:
|
elif idx == n - 1:
|
||||||
start = intro_duration + transition_offsets[idx - 1] + fade
|
base_start = intro_duration + transition_offsets[idx - 1] + fade
|
||||||
end = total_duration
|
base_end = total_duration
|
||||||
else:
|
else:
|
||||||
start = intro_duration + transition_offsets[idx - 1] + fade
|
base_start = intro_duration + transition_offsets[idx - 1] + fade
|
||||||
end = intro_duration + transition_offsets[idx]
|
base_end = intro_duration + transition_offsets[idx]
|
||||||
|
|
||||||
|
start = base_start
|
||||||
|
end = base_end
|
||||||
|
clip_kind = clip_kinds[idx] if clip_kinds and idx < len(clip_kinds) else ""
|
||||||
|
clip_duration = durations[idx] if idx < len(durations) else 0.0
|
||||||
|
if clip_kind == "video" and clip_duration > CAPTION_LONG_VIDEO_MIN_DURATION:
|
||||||
|
start = base_start + CAPTION_LONG_VIDEO_DELAY
|
||||||
|
end = min(base_end, start + CAPTION_LONG_VIDEO_SHOW)
|
||||||
|
|
||||||
if end <= start:
|
if end <= start:
|
||||||
continue
|
continue
|
||||||
caption_fade = min(1.0, max(0.0, (end - start) / 2))
|
caption_fade = min(1.0, max(0.0, (end - start) / 2))
|
||||||
|
|
@ -1411,6 +1424,7 @@ def main(argv: list[str] | None = None) -> int:
|
||||||
# Use probed normalized duration for accuracy.
|
# Use probed normalized duration for accuracy.
|
||||||
durations = [ffprobe_duration(out) for out in clips]
|
durations = [ffprobe_duration(out) for out in clips]
|
||||||
captions = [data.captions.get(item.path.name, data.captions.get(str(item.path), "")) for item in media]
|
captions = [data.captions.get(item.path.name, data.captions.get(str(item.path), "")) for item in media]
|
||||||
|
clip_kinds = [item.kind for item in media]
|
||||||
video_audio = data.video_audio or set()
|
video_audio = data.video_audio or set()
|
||||||
clip_audio_paths = []
|
clip_audio_paths = []
|
||||||
for item in media:
|
for item in media:
|
||||||
|
|
@ -1451,6 +1465,7 @@ def main(argv: list[str] | None = None) -> int:
|
||||||
intro_clip_path = intro_clip
|
intro_clip_path = intro_clip
|
||||||
intro_clip_duration = intro_item.duration
|
intro_clip_duration = intro_item.duration
|
||||||
captions = ["", *captions]
|
captions = ["", *captions]
|
||||||
|
clip_kinds = ["image", *clip_kinds]
|
||||||
clip_audio_paths = [None, *clip_audio_paths]
|
clip_audio_paths = [None, *clip_audio_paths]
|
||||||
clip_stamps = ["", *clip_stamps]
|
clip_stamps = ["", *clip_stamps]
|
||||||
intro_visible_lead = min(intro_item.duration, INTRO_LOGO_FADE_OFFSET)
|
intro_visible_lead = min(intro_item.duration, INTRO_LOGO_FADE_OFFSET)
|
||||||
|
|
@ -1460,10 +1475,37 @@ def main(argv: list[str] | None = None) -> int:
|
||||||
clips.append(intro_clip_path)
|
clips.append(intro_clip_path)
|
||||||
durations.append(intro_clip_duration)
|
durations.append(intro_clip_duration)
|
||||||
captions.append("")
|
captions.append("")
|
||||||
|
clip_kinds.append("image")
|
||||||
clip_audio_paths.append(None)
|
clip_audio_paths.append(None)
|
||||||
clip_stamps.append("")
|
clip_stamps.append("")
|
||||||
outro_added = True
|
outro_added = True
|
||||||
build_video(clips, durations, audio, clip_audio_paths, output, data, first_media_date, captions, clip_stamps, fade, audio_fade, audio_fade_in, video_fade, args.intro_logo, intro_logo_alpha, width, height, fps, preset, crf, tmp, video_intro_duration, intro_visible_lead=intro_visible_lead, skip_video_fade_out=outro_added)
|
build_video(
|
||||||
|
clips,
|
||||||
|
durations,
|
||||||
|
audio,
|
||||||
|
clip_audio_paths,
|
||||||
|
output,
|
||||||
|
data,
|
||||||
|
first_media_date,
|
||||||
|
captions,
|
||||||
|
clip_stamps,
|
||||||
|
fade,
|
||||||
|
audio_fade,
|
||||||
|
audio_fade_in,
|
||||||
|
video_fade,
|
||||||
|
args.intro_logo,
|
||||||
|
intro_logo_alpha,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fps,
|
||||||
|
preset,
|
||||||
|
crf,
|
||||||
|
tmp,
|
||||||
|
video_intro_duration,
|
||||||
|
intro_visible_lead=intro_visible_lead,
|
||||||
|
skip_video_fade_out=outro_added,
|
||||||
|
clip_kinds=clip_kinds,
|
||||||
|
)
|
||||||
|
|
||||||
console(f"Done: {output}")
|
console(f"Done: {output}")
|
||||||
return 0
|
return 0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue