Run from the extracted example folder. Each line is a separate command, in order. All exports refuse overwrite (-n). FFmpeg and ffprobe must be on PATH. Make the first cut ffmpeg -n -loop 1 -framerate 30 -i picture-01.webp -loop 1 -framerate 30 -i picture-02.webp -loop 1 -framerate 30 -i picture-03.webp -loop 1 -framerate 30 -i picture-04.webp -loop 1 -framerate 30 -i picture-05.webp -loop 1 -framerate 30 -i picture-06.webp -i narration.mp3 -filter_complex_script first-cut.filter.txt -map "[picture]" -map 6:a:0 -af "apad=pad_dur=4" -t 56.800000 -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart -metadata comment="Renaissance Solutions; artwork: OpenAI; voice: Speechify George. See CREDITS.txt." first-cut.mp4 Expected: 56.800 seconds; six still pictures, finished narration and about four seconds of ending silence. Image boundaries are rounded to the nearest 30 fps frame. Move picture two one second later ffmpeg -n -loop 1 -framerate 30 -i picture-01.webp -loop 1 -framerate 30 -i picture-02.webp -loop 1 -framerate 30 -i picture-03.webp -loop 1 -framerate 30 -i picture-04.webp -loop 1 -framerate 30 -i picture-05.webp -loop 1 -framerate 30 -i picture-06.webp -i narration.mp3 -filter_complex_script revised.filter.txt -map "[picture]" -map 6:a:0 -af "apad=pad_dur=4" -t 56.800000 -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart -metadata comment="Renaissance Solutions; artwork: OpenAI; voice: Speechify George. See CREDITS.txt." revised.mp4 Expected: 56.800 seconds; six still pictures, finished narration and about four seconds of ending silence. Image boundaries are rounded to the nearest 30 fps frame. Keep selectable captions inside the movie ffmpeg -n -i first-cut.mp4 -i captions.srt -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -c:a copy -c:s mov_text -metadata:s:s:0 language=eng -movflags +faststart story-captioned.mp4 Expected: Video and audio are copied unchanged. Switch captions on in a supporting player; keep the SRT and transcript for players without subtitle support. Extract a listening copy ffmpeg -n -i first-cut.mp4 -map 0:a:0 -c:a pcm_s16le listening-copy.wav Expected: A WAV audio file, including the ending silence; the movie is unchanged. Trim practice take 1 ffmpeg -n -i narration.mp3 -ss 0.000000 -t 11.500000 -map 0:a:0 -ar 48000 -ac 2 -c:a pcm_s16le take-01.wav Expected: A practice excerpt from the existing finished mix. Your own takes can be separate recordings; retain the originals. Trim practice take 2 ffmpeg -n -i narration.mp3 -ss 11.500000 -t 7.138000 -map 0:a:0 -ar 48000 -ac 2 -c:a pcm_s16le take-02.wav Expected: A practice excerpt from the existing finished mix. Your own takes can be separate recordings; retain the originals. Trim practice take 3 ffmpeg -n -i narration.mp3 -ss 18.638000 -t 10.700000 -map 0:a:0 -ar 48000 -ac 2 -c:a pcm_s16le take-03.wav Expected: A practice excerpt from the existing finished mix. Your own takes can be separate recordings; retain the originals. Trim practice take 4 ffmpeg -n -i narration.mp3 -ss 29.338000 -t 6.843000 -map 0:a:0 -ar 48000 -ac 2 -c:a pcm_s16le take-04.wav Expected: A practice excerpt from the existing finished mix. Your own takes can be separate recordings; retain the originals. Trim practice take 5 ffmpeg -n -i narration.mp3 -ss 36.181000 -t 8.314000 -map 0:a:0 -ar 48000 -ac 2 -c:a pcm_s16le take-05.wav Expected: A practice excerpt from the existing finished mix. Your own takes can be separate recordings; retain the originals. Trim practice take 6 ffmpeg -n -i narration.mp3 -ss 44.495000 -t 8.281009 -map 0:a:0 -ar 48000 -ac 2 -c:a pcm_s16le take-06.wav Expected: A practice excerpt from the existing finished mix. Your own takes can be separate recordings; retain the originals. Join six chosen takes in order ffmpeg -n -i take-01.wav -i take-02.wav -i take-03.wav -i take-04.wav -i take-05.wav -i take-06.wav -filter_complex "[0:a:0][1:a:0][2:a:0][3:a:0][4:a:0][5:a:0]concat=n=6:v=0:a=1[a]" -map "[a]" -c:a pcm_s16le joined-takes.wav Expected: The six practice WAV takes reassembled. Use the completed listening copy as the input to your picture sequence; do not add its existing effects again. Trim a video and mute its original sound ffmpeg -n -i practice-landscape.mp4 -f lavfi -i anullsrc=r=48000:cl=stereo -filter_complex "[0:v]trim=start=1:end=4,setpts=PTS-STARTPTS,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v]" -map "[v]" -map 1:a:0 -t 3 -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart clip-a.mp4 Expected: Three seconds, padded to 1080p, with a silent audio track. Adding silence makes later joins predictable. Trim another video and retain its sound ffmpeg -n -i practice-portrait.mp4 -filter_complex "[0:v]trim=start=0:end=3,setpts=PTS-STARTPTS,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v];[0:a]atrim=start=0:end=3,asetpts=PTS-STARTPTS,aresample=48000[a]" -map "[v]" -map "[a]" -t 3 -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart clip-b.mp4 Expected: Three seconds of portrait video with side padding and its quiet practice tone retained. Join the normalized clips ffmpeg -n -i clip-a.mp4 -i clip-b.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart joined-clips.mp4 Expected: Six seconds: the cut is at three seconds. This re-encodes for consistent output; arbitrary camera clips are not safe to join with stream copy. Turn a picture into a short silent clip ffmpeg -n -loop 1 -framerate 30 -i picture-06.webp -f lavfi -i anullsrc=r=48000:cl=stereo -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p" -t 2 -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart still-clip.mp4 Expected: Two seconds, including a silent audio track. Combine still and moving clips ffmpeg -n -i still-clip.mp4 -i joined-clips.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart mixed.mp4 Expected: Eight seconds: a still picture followed by the two practice clips. Place a quiet bed and a cue across a cut ffmpeg -n -i joined-clips.mp4 -i practice-bed.wav -i practice-cue.wav -filter_complex "[0:a]volume=0.5[original];[1:a]volume=0.18,afade=t=in:d=0.5,afade=t=out:st=5:d=1[bed];[2:a]volume=0.35,adelay=2500:all=1[cue];[original][bed][cue]amix=inputs=3:duration=first:normalize=0,alimiter=limit=0.95:level=0[a]" -map 0:v:0 -map "[a]" -c:v copy -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart sound-across-cut.mp4 Expected: The cue begins at 2.5 seconds and lasts one second, crossing the cut at 3 seconds. Bed and clip sound stay separate until this export. These are synthetic practice tones, not a music recommendation. Try a bed under one narration excerpt ffmpeg -n -i take-01.wav -i practice-bed.wav -filter_complex "[1:a]volume=0.10,afade=t=in:d=0.5,afade=t=out:st=5:d=1[bed];[0:a][bed]amix=inputs=2:duration=first:normalize=0,alimiter=limit=0.95:level=0[a]" -map "[a]" -c:a pcm_s16le speech-with-bed.wav Expected: The six-second bed ends before the narration; every word should remain clear. Listen and lower the bed further if needed. This is an optional comparison, not an instruction to remix the finished Story Studio narration. Export a smaller viewing copy ffmpeg -n -i first-cut.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1" -c:v libx264 -crf 23 -pix_fmt yuv420p -c:a aac -movflags +faststart viewing-720p.mp4 Expected: A 720p derivative. Keep the 1080p export and originals.