zeta-ball: mux narration per scene and concatenate
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FAqjv3n4yABxvJPJHFRhVA
This commit is contained in:
1 parent
07127dfaa0
commit
13ccacf4fd
1 file changed
+20
@@ -0,0 +1,20 @@
|
||||
import json, subprocess
|
||||
FF, FP = '/opt/homebrew/bin/ffmpeg', '/opt/homebrew/bin/ffprobe'
|
||||
D = json.load(open('durations.json')); GAP = 0.6
|
||||
pcm = open('zb.pcm', 'rb').read()
|
||||
V = 'media/videos/zb/720p30'
|
||||
off, parts = 0.0, []
|
||||
for i, d in enumerate(D):
|
||||
a = int(round(off * 24000)) * 2; n = int(round(d * 24000)) * 2
|
||||
open(f'seg_{i}.pcm', 'wb').write(pcm[a:a + n])
|
||||
off += d + GAP
|
||||
vd = float(subprocess.run([FP, '-v', 'error', '-show_entries', 'format=duration', '-of', 'csv=p=0', f'{V}/S{i}.mp4'], capture_output=True, text=True).stdout)
|
||||
print(f'S{i}: video {vd:.2f}s narration {d:.2f}s slack {vd - d:.2f}s')
|
||||
out = f'part_{i}.mp4'
|
||||
subprocess.run([FF, '-v', 'error', '-y', '-i', f'{V}/S{i}.mp4', '-f', 's16le', '-ar', '24000', '-ac', '1', '-i', f'seg_{i}.pcm',
|
||||
'-filter_complex', '[1:a]apad[a]', '-map', '0:v', '-map', '[a]', '-c:v', 'copy', '-c:a', 'aac', '-b:a', '128k',
|
||||
'-ar', '48000', '-shortest', out], check=True)
|
||||
parts.append(out)
|
||||
open('list.txt', 'w').write(''.join(f"file '{p}'\n" for p in parts))
|
||||
subprocess.run([FF, '-v', 'error', '-y', '-f', 'concat', '-safe', '0', '-i', 'list.txt', '-c:v', 'libx264', '-crf', '20', '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-b:a', '128k', 'zeta-ball.mp4'], check=True)
|
||||
print(subprocess.run([FP, '-v', 'error', '-show_entries', 'format=duration,size', '-of', 'default=noprint_wrappers=1', 'zeta-ball.mp4'], capture_output=True, text=True).stdout)
|
||||
Reference in new issue
Block a user