Batch-Transcoding and Renaming a Whole Shoot With a Few Lines of FFmpeg | Cutroom AI
Home Automation & Pipelines Batch-Transcoding and Renaming a Whole Shoot With a Few Lines of FFmpeg

Batch-Transcoding and Renaming a Whole Shoot With a Few Lines of FFmpeg

Turn a memory card full of cryptic camera clips into editor-ready proxies with consistent names, using shell loops and FFmpeg.

By Sam Delacroix, an editing-pipeline engineer · Published 24 May 2026 · 8 min read · Reviewed against our editorial standards

ADVERTISEMENT

Every shoot lands the same way. A card full of files named C0042.MP4, DJI_0198.MOV, and A001_08151530_C003.mov, all in different codecs, some in 10-bit H.265 that makes your timeline stutter, none of them telling you which scene they belong to. You can spend twenty minutes clicking through Resolve's clip attributes, or you can spend one line of shell and get on with editing.

FFmpeg is the tool underneath almost everything in this pipeline. Resolve, Premiere, and every web transcoder shell out to something like it. Learning to call it directly is the difference between waiting on a GUI and processing 300 clips while you make coffee. This is the ingest step I run on every job before an NLE ever opens.

Why transcode at ingest instead of editing native

Modern camera codecs are built for storage efficiency, not playback. Long-GOP H.265 from a Sony FX3 or a drone forces your machine to decode a chunk of frames just to show you one, which is why scrubbing feels like wading through mud. Editing proxies solve this by re-encoding to an all-intra codec where every frame stands alone.

The two proxy formats worth knowing in 2026 are DNxHR (Avid's codec, rock solid on Windows and Linux) and ProRes (Apple's, now encodable by FFmpeg on any platform without Apple hardware). Both cut cleanly and both relink to your camera originals at export time. For a talking-head or run-and-gun shoot, DNxHR LB or ProRes Proxy at 1080p is plenty.

The one-clip version first

Always test on a single file before you loop. Here is a clean DNxHR proxy:

ffmpeg -i C0042.MP4 \
  -c:v dnxhd -profile:v dnxhr_lb \
  -vf "scale=1920:1080,format=yuv422p" \
  -c:a pcm_s16le \
  C0042_proxy.mov

A few things are load-bearing here. The format=yuv422p tells DNxHR which pixel layout to use; leave it out and FFmpeg will often refuse the encode with a cryptic "incompatible pixel format" error. Audio goes to uncompressed PCM because editors want sample-accurate scrubbing, not AAC. And the container is .mov, which both DNxHR and ProRes expect.

For ProRes, swap the video codec block:

ffmpeg -i C0042.MP4 \
  -c:v prores_ks -profile:v 0 \
  -vf "scale=1920:1080" \
  -c:a pcm_s16le \
  C0042_proxy.mov

Profile 0 is Proxy, 1 is LT, 2 is standard 422. Start at Proxy and only move up if the image looks too soft to make editorial decisions.

Looping over the whole card

Once the single file works, wrap it in a loop. On macOS or Linux (or Git Bash on Windows, which Kevin-style setups often have installed):

mkdir -p proxies
for f in *.MP4 *.MOV; do
  [ -e "$f" ] || continue
  ffmpeg -i "$f" \
    -c:v dnxhd -profile:v dnxhr_lb \
    -vf "scale=1920:1080,format=yuv422p" \
    -c:a pcm_s16le \
    "proxies/${f%.*}_proxy.mov"
done

The ${f%.*} strips the original extension so C0042.MP4 becomes C0042_proxy.mov. The [ -e "$f" ] || continue guard skips the pattern harmlessly if, say, there are no .MOV files on the card. Quote every variable, always, because camera files and folders love spaces and parentheses.

On native Windows PowerShell the same idea reads:

New-Item -ItemType Directory -Force proxies | Out-Null
Get-ChildItem -Include *.MP4,*.MOV -Recurse | ForEach-Object {
  $out = "proxies/$($_.BaseName)_proxy.mov"
  ffmpeg -i $_.FullName `
    -c:v dnxhd -profile:v dnxhr_lb `
    -vf "scale=1920:1080,format=yuv422p" `
    -c:a pcm_s16le `
    $out
}

Renaming with real information

Sequential camera names carry no meaning. What you actually want is something like 2026-05-24_interview_take03.mov, and the honest source for that is the file's own metadata plus a naming convention you decide.

Camera clips store their creation time. You can read it and build a name from it with ffprobe, FFmpeg's inspection sibling:

ffprobe -v quiet -show_entries format_tags=creation_time \
  -of default=nw=1:nk=1 C0042.MP4

That prints something like 2026-05-24T15:30:12.000000Z. Feed the date portion into your rename so clips sort chronologically regardless of which camera shot them. A compact loop that prefixes every proxy with its shoot date and a running counter:

i=1
for f in *.MP4; do
  ts=$(ffprobe -v quiet -show_entries format_tags=creation_time \
       -of default=nw=1:nk=1 "$f")
  date=${ts:0:10}
  printf -v num "%03d" $i
  name="${date}_shoot_${num}"
  ffmpeg -i "$f" -c:v dnxhd -profile:v dnxhr_lb \
    -vf "scale=1920:1080,format=yuv422p" -c:a pcm_s16le \
    "proxies/${name}.mov"
  i=$((i+1))
done

Now your proxy folder reads like a shot list instead of a lottery. If you shoot with a slate or a naming app that writes real scene and take numbers, prefer those over a blind counter, but a date-plus-index scheme is a solid default that never collides.

The trade-offs worth being honest about

Proxies cost disk. DNxHR LB runs roughly 30 to 50 GB per hour of 1080p footage, more at higher profiles. On a laptop with a small SSD, transcode to an external drive and point your NLE's proxy path there.

Transcoding also costs time up front. A card of 4K H.265 can take longer than real-time to convert on a CPU-only machine. If you have an NVIDIA GPU, adding -hwaccel cuda before the input speeds up decoding, though DNxHR and ProRes encoding still runs on CPU. The trade is real: you pay this time once at ingest so you never pay it again while cutting.

And proxies are for editing, not delivery. Every serious NLE lets you toggle back to camera originals for the final render so your export keeps full quality. If you forget that toggle, you ship a soft, oversized file. Set your proxy resolution consciously, relink at the end, and check one exported frame at 100 percent before you send anything to a client.

Bake these commands into a script named something like ingest.sh, drop it beside your card-offload routine, and the whole "prep the footage" phase collapses into one command you run and walk away from. That is the entire point of a pipeline step: do it once, correctly, then stop thinking about it.

ffmpegtranscodingproxiesingest

A note on shelf life. AI products change fast. This guide deliberately focuses on the parts that stay true — how to judge a tool, what the trade-offs are — rather than ranking products that will have changed by the time you read it. Prices and feature claims should always be checked against the provider before you rely on them.