fix: remove audio during intermediate processing and mux original audio back during final concatenation to prevent sync issues
This commit is contained in:
parent
d99da42a2e
commit
97a9c929c0
15
cut_head.py
15
cut_head.py
|
|
@ -58,25 +58,30 @@ def smart_cut(input_video, output_video, cut_timestamp):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 1. Re-encode the tiny segment (from exact cut to next keyframe)
|
# 1. Re-encode the tiny segment (from exact cut to next keyframe)
|
||||||
|
# Audio is removed (-an) to prevent sync/overlap issues during concatenation
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'ffmpeg', '-y', '-v', 'error', '-i', input_video,
|
'ffmpeg', '-y', '-v', 'error', '-i', input_video,
|
||||||
'-ss', str(cut_timestamp), '-to', str(next_keyframe),
|
'-ss', str(cut_timestamp), '-to', str(next_keyframe),
|
||||||
'-c:v', 'libx264', '-crf', '18', '-c:a', 'copy', part1
|
'-c:v', 'libx264', '-crf', '18', '-an', part1
|
||||||
], check=True)
|
], check=True)
|
||||||
|
|
||||||
# 2. Copy the rest of the video (from next keyframe to the end)
|
# 2. Copy the rest of the video (from next keyframe to the end)
|
||||||
|
# Audio is removed (-an) here too
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'ffmpeg', '-y', '-v', 'error', '-ss', str(next_keyframe), '-i', input_video,
|
'ffmpeg', '-y', '-v', 'error', '-ss', str(next_keyframe), '-i', input_video,
|
||||||
'-c:v', 'copy', '-c:a', 'copy', part2
|
'-c:v', 'copy', '-an', part2
|
||||||
], check=True)
|
], check=True)
|
||||||
|
|
||||||
# 3. Concatenate them using a text list (Forced UTF-8 encoding for emojis/special chars)
|
# 3. Concatenate video parts and cleanly mux with the original extracted audio
|
||||||
with open(concat_list, 'w', encoding='utf-8') as f:
|
with open(concat_list, 'w', encoding='utf-8') as f:
|
||||||
f.write(f"file '{part1}'\nfile '{part2}'\n")
|
f.write(f"file '{part1}'\nfile '{part2}'\n")
|
||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'ffmpeg', '-y', '-v', 'error', '-f', 'concat', '-safe', '0',
|
'ffmpeg', '-y', '-v', 'error',
|
||||||
'-i', concat_list, '-c', 'copy', output_video
|
'-f', 'concat', '-safe', '0', '-i', concat_list,
|
||||||
|
'-ss', str(cut_timestamp), '-i', input_video,
|
||||||
|
'-map', '0:v', '-map', '1:a?',
|
||||||
|
'-c:v', 'copy', '-c:a', 'copy', output_video
|
||||||
], check=True)
|
], check=True)
|
||||||
print(f"Success! Saved to {output_video}")
|
print(f"Success! Saved to {output_video}")
|
||||||
|
|
||||||
|
|
|
||||||
30
cut_tail.py
30
cut_tail.py
|
|
@ -71,31 +71,39 @@ def smart_cut_tail(input_video, output_video, tail_duration):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 3. Copy the bulk of the video (from 0 to the preceding keyframe)
|
# 3. Copy the bulk of the video (from 0 to the preceding keyframe)
|
||||||
|
# Audio is removed (-an) to prevent sync/overlap issues
|
||||||
if prev_keyframe > 0.0:
|
if prev_keyframe > 0.0:
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'ffmpeg', '-y', '-v', 'error', '-i', input_video,
|
'ffmpeg', '-y', '-v', 'error', '-i', input_video,
|
||||||
'-t', str(prev_keyframe),
|
'-t', str(prev_keyframe),
|
||||||
'-c:v', 'copy', '-c:a', 'copy', part1
|
'-c:v', 'copy', '-an', part1
|
||||||
], check=True)
|
], check=True)
|
||||||
|
|
||||||
# 4. Re-encode the tiny tip (from the preceding keyframe to the exact cut timestamp)
|
# 4. Re-encode the tiny tip (from the preceding keyframe to the exact cut timestamp)
|
||||||
|
# Audio is removed (-an) here too
|
||||||
tiny_duration = cut_timestamp - prev_keyframe
|
tiny_duration = cut_timestamp - prev_keyframe
|
||||||
subprocess.run([
|
if tiny_duration > 0.0:
|
||||||
'ffmpeg', '-y', '-v', 'error',
|
subprocess.run([
|
||||||
'-ss', str(prev_keyframe), '-i', input_video,
|
'ffmpeg', '-y', '-v', 'error',
|
||||||
'-t', str(tiny_duration),
|
'-ss', str(prev_keyframe), '-i', input_video,
|
||||||
'-c:v', 'libx264', '-crf', '18', '-c:a', 'copy', part2
|
'-t', str(tiny_duration),
|
||||||
], check=True)
|
'-c:v', 'libx264', '-crf', '18', '-an', part2
|
||||||
|
], check=True)
|
||||||
|
|
||||||
# 5. Concatenate them using a text list (Forced UTF-8 encoding for emojis/special chars)
|
# 5. Concatenate video parts and cleanly mux with the original extracted audio
|
||||||
with open(concat_list, 'w', encoding='utf-8') as f:
|
with open(concat_list, 'w', encoding='utf-8') as f:
|
||||||
if prev_keyframe > 0.0:
|
if prev_keyframe > 0.0:
|
||||||
f.write(f"file '{part1}'\n")
|
f.write(f"file '{part1}'\n")
|
||||||
f.write(f"file '{part2}'\n")
|
if tiny_duration > 0.0:
|
||||||
|
f.write(f"file '{part2}'\n")
|
||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'ffmpeg', '-y', '-v', 'error', '-f', 'concat', '-safe', '0',
|
'ffmpeg', '-y', '-v', 'error',
|
||||||
'-i', concat_list, '-c', 'copy', output_video
|
'-f', 'concat', '-safe', '0', '-i', concat_list,
|
||||||
|
'-i', input_video,
|
||||||
|
'-map', '0:v', '-map', '1:a?',
|
||||||
|
'-c:v', 'copy', '-c:a', 'copy',
|
||||||
|
'-t', str(cut_timestamp), output_video
|
||||||
], check=True)
|
], check=True)
|
||||||
print(f"Success! Saved to {output_video}")
|
print(f"Success! Saved to {output_video}")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue