Fix a bug where transitions past the first are not timed correctly

The video offset is timed relative to the full video up until that point, not the previous range.
pull/401/head
Mike Lang 1 month ago
parent 69bfa79e24
commit e50adbf2da

@ -926,6 +926,9 @@ def full_cut_segments(segment_ranges, ranges, transitions, encode_args, stream=F
inputs.append((segments, args)) inputs.append((segments, args))
filters = [] filters = []
# We need to keep track of the full video length so transitions start at the correct time.
# This variable tracks the start of prev_range relative to the start of the output video.
prev_video_start_offset = 0
# with no additional ranges, the output stream is just the first input stream # with no additional ranges, the output stream is just the first input stream
output_video_stream = "0:v" output_video_stream = "0:v"
output_audio_stream = "0:a" output_audio_stream = "0:a"
@ -947,6 +950,7 @@ def full_cut_segments(segment_ranges, ranges, transitions, encode_args, stream=F
kwargs = ":".join(f"{k}={v}" for k, v in kwargs.items()) kwargs = ":".join(f"{k}={v}" for k, v in kwargs.items())
filters.append(f"{inputs}{name}={kwargs}{outputs}") filters.append(f"{inputs}{name}={kwargs}{outputs}")
prev_length = (prev_range[1] - prev_range[0]).total_seconds()
if transition is None: if transition is None:
input_streams = [ input_streams = [
prev_video_stream, prev_video_stream,
@ -956,14 +960,16 @@ def full_cut_segments(segment_ranges, ranges, transitions, encode_args, stream=F
] ]
output_streams = [output_video_stream, output_audio_stream] output_streams = [output_video_stream, output_audio_stream]
add_filter("concat", input_streams, output_streams, n=2, v=1, a=1) add_filter("concat", input_streams, output_streams, n=2, v=1, a=1)
prev_video_start_offset += prev_length
else: else:
video_type, duration = transition video_type, duration = transition
# transition should start at DURATION seconds before prev_range ends, # Transition should start at DURATION seconds before prev_range ends.
# which is timed relative to prev_range start. So if prev_range is 60s long # We know when prev_range begins from prev_video_start_offset.
# So if prev_range is 40s long, prev_range starts at 20s,
# and duration is 2s, we should start at 58s. # and duration is 2s, we should start at 58s.
prev_length = (prev_range[1] - prev_range[0]).total_seconds() # This is also the start time of the next range.
offset = prev_length - duration offset = prev_video_start_offset + prev_length - duration
kwargs = { kwargs = {
"duration": duration, "duration": duration,
"offset": offset, "offset": offset,
@ -980,6 +986,8 @@ def full_cut_segments(segment_ranges, ranges, transitions, encode_args, stream=F
# audio cross-fade across the same period # audio cross-fade across the same period
add_filter("acrossfade", [prev_audio_stream, next_audio_stream], [output_audio_stream], duration=duration) add_filter("acrossfade", [prev_audio_stream, next_audio_stream], [output_audio_stream], duration=duration)
prev_video_start_offset = offset
if stream: if stream:
# When streaming, we can just use a pipe # When streaming, we can just use a pipe
output_file = subprocess.PIPE output_file = subprocess.PIPE

Loading…
Cancel
Save