B-roll guide real test - run: 2026-10-25 (UTC), host: Linux 6.8.0-139-generic x86_64 ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers Browser: headless Chromium (Playwright) against the live tools at https://koldflux.com/tools/video/trim, /merge and /add-audio. Input footage: real free-licence clip, not made by us. Steam_Engine_Pulling_into_Virginia_City_Station.webm, Wikimedia Commons, licence CC0 (read via the Commons API on 2026-10-25), https://commons.wikimedia.org/wiki/File:Steam_Engine_Pulling_into_Virginia_City_Station.webm Voiceover: our own synthetic voice (Kokoro, am_michael), text written by us (see below). === 1. source clip === $ ffprobe -v error -show_entries format=duration,size -show_entries stream=codec_name,codec_type,width,height,r_frame_rate -of csv=p=0 src/steam.webm vp9,video,1920,1080,30000/1001 opus,audio,0/0 35.848000,28207570 (VP9 1920x1080 29.97 fps, Opus audio, 35.848 s, 28,207,570 bytes) === 2. working file (H.264, sound removed because B-roll is usually muted) === $ ffmpeg -i src/steam.webm -an -c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p steam.mp4 $ ffprobe -v error -show_entries format=duration,size -show_entries stream=codec_name,width,height,r_frame_rate,nb_frames -of csv=p=0 steam.mp4 h264,1920,1080,30000/1001,1074 35.835800,20469669 === 3. voiceover (A-roll), 4 sentences, one per shot === Text: "A steam locomotive rolls into the station. Its wheels and rods turn slowly in the sun. On the cab the number is twenty nine, and the crew looks out. Then the whole train slides past the camera." $ cd ~/kokoro && venv/bin/python say.py "" am_michael voice.wav duration: 12.885333 s $ ffmpeg -i voice.wav -af silencedetect=noise=-35dB:d=0.12 -f null - sentence starts (end of each silence): 0.000, 3.040, 6.490, 10.236 s === 4. Koldflux trim tool, four runs (steam.mp4, start-end in seconds) === Each run: node scenario-trim.cjs steam.mp4 out/tN.mp4 ; the page said "Processing complete", console errors: none. t1 0 to 3 t2 14.5 to 18 t3 20 to 23.75 t4 30 to 32.65 $ ffprobe (codec,width,height,r_frame_rate,nb_frames / duration,size) of each download: out/t1.mp4: h264,1920,1080,30000/1001,90 3.003000,1112913 out/t2.mp4: h264,1920,1080,30000/1001,105 3.503500,2045708 out/t3.mp4: h264,1920,1080,30000/1001,112 3.737067,2013681 out/t4.mp4: h264,1920,1080,30000/1001,79 2.635967,988535 === 5. Koldflux merge tool, 4 clips, horizontal 16:9 === Run: node merge4.cjs out/merged.mp4 out/t1.mp4 out/t2.mp4 out/t3.mp4 out/t4.mp4 ; button "Merge 4 videos"; errors: none; took about 80 s in headless Chromium on this server. h264,1920,1080,2997/100,386 12.879546,5761146 Sum of the four trimmed durations: 12.8795 s. Merged duration: 12.879546 s (no length lost at the joins). === 6. Koldflux add audio tool, mode "Replace it with the new audio" === Run: node addaudio.cjs out/merged.mp4 voice.wav out/final.mp4 ; errors: none; took about 4 s. h264,video,1920,1080,12.879546,386 aac,audio,12.971000,305 12.971000,5947003 Picture check (md5 of the decoded video stream), merged.mp4 vs final.mp4: MD5=f46b4ef656ba2b6f07c95e85a9847e88 MD5=f46b4ef656ba2b6f07c95e85a9847e88 Result: the picture was copied untouched. The audio stream is 12.971 s against a 12.880 s picture, so the container is 0.092 s longer than the picture (the tool page says it copies the picture and the result is as long as the video; we measured 0.092 s of extra tail). === 7. Where are the seams? (frame to frame difference, ffmpeg tblend + signalstats, average luminance) === $ ffmpeg -i out/final.mp4 -vf "tblend=all_mode=difference,signalstats,metadata=print:key=lavfi.signalstats.YAVG:file=pf-final.txt" -f null - Three largest values: 3.003 s = 67.86, 10.244 s = 41.61, 6.507 s = 28.38. Next largest: 8.141 s = 10.76. Median of all frames: 5.13 (the source clip is handheld, so every frame moves a little). So the 3 seams are the 3 largest changes in the file, at 3.003, 6.507 and 10.244 s, exactly the cumulative durations of the trimmed clips. === 8. Does the voice survive the cuts? === $ ffmpeg -i out/final.mp4 -af silencedetect=noise=-35dB:d=0.12 -f null - silence_start: 2.4765 silence_duration: 0.563208 silence_start: 5.83933 silence_duration: 0.651042 silence_start: 9.58529 silence_duration: 0.650917 silence_start: 12.7541 silence_duration: 0.216583 Silences in the final file match the silences of voice.wav to within 0.001 s: the cuts did not move or break the voice track. Seam versus start of the next sentence: seam 3.003 vs sentence 3.040 (picture 0.037 s early); 6.507 vs 6.490 (0.017 s late); 10.244 vs 10.236 (0.008 s late). === 9. Real-input check: the tool on the original webm (VP9 + Opus) === $ node scenario-trim.cjs src/steam.webm 0 3 out/webm-t1.mp4 ; errors: none h264,video,1920,1080,90 aac,audio,142 3.003000,1211463 The trim tool accepts the webm directly and returns H.264 plus AAC; the source sound is kept unless you mute it first. === 10. Numbers used on the page === Shots: 3.003, 3.5035, 3.737, 2.636 s. Mean shot length 3.22 s. Used 12.88 s of a 35.85 s source = 35.9% (shooting ratio 2.8 to 1). Not tested: a person speaking to camera (A-roll here is a voiceover), phone footage, vertical video, a clip near the 100 MB limit, other editors.