diff --git a/cut_head.py b/cut_head.py index 434c38f..f0f71f3 100644 --- a/cut_head.py +++ b/cut_head.py @@ -58,25 +58,30 @@ def smart_cut(input_video, output_video, cut_timestamp): try: # 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([ 'ffmpeg', '-y', '-v', 'error', '-i', input_video, '-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) # 2. Copy the rest of the video (from next keyframe to the end) + # Audio is removed (-an) here too subprocess.run([ '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) - # 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: f.write(f"file '{part1}'\nfile '{part2}'\n") subprocess.run([ - 'ffmpeg', '-y', '-v', 'error', '-f', 'concat', '-safe', '0', - '-i', concat_list, '-c', 'copy', output_video + 'ffmpeg', '-y', '-v', 'error', + '-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) print(f"Success! Saved to {output_video}") diff --git a/cut_tail.py b/cut_tail.py index 55b28f9..5c47e13 100644 --- a/cut_tail.py +++ b/cut_tail.py @@ -71,31 +71,39 @@ def smart_cut_tail(input_video, output_video, tail_duration): try: # 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: subprocess.run([ 'ffmpeg', '-y', '-v', 'error', '-i', input_video, '-t', str(prev_keyframe), - '-c:v', 'copy', '-c:a', 'copy', part1 + '-c:v', 'copy', '-an', part1 ], check=True) # 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 - subprocess.run([ - 'ffmpeg', '-y', '-v', 'error', - '-ss', str(prev_keyframe), '-i', input_video, - '-t', str(tiny_duration), - '-c:v', 'libx264', '-crf', '18', '-c:a', 'copy', part2 - ], check=True) + if tiny_duration > 0.0: + subprocess.run([ + 'ffmpeg', '-y', '-v', 'error', + '-ss', str(prev_keyframe), '-i', input_video, + '-t', str(tiny_duration), + '-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: if prev_keyframe > 0.0: 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([ - 'ffmpeg', '-y', '-v', 'error', '-f', 'concat', '-safe', '0', - '-i', concat_list, '-c', 'copy', output_video + 'ffmpeg', '-y', '-v', 'error', + '-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) print(f"Success! Saved to {output_video}")