Tennis Evolution

Guides

Trim iPhone videos losslessly with ffmpeg

Short answer: list the keyframes, move each cut outwards to the nearest keyframe, then cut with ffmpeg -ss START -i IN.MOV -t LENGTH -map 0:v:0 -map 0:a:0 -c copy -movflags +faststart out.mp4. A stream-copy cut can only start on a keyframe; on iPhone HEVC those are about a second apart.

Why -c copy cuts are never frame-exact

Stream copy keeps the original compressed frames, and most frames only make sense relative to an earlier keyframe. A copy can therefore only start on a keyframe. An iPhone at 29.97 fps typically puts one every 32 frames — about 1.07 s — so a lossless cut is accurate to roughly a second. That is fine for sports clips; pad each clip by a second at the start and a second and a half at the end.

1. List the keyframes

ffprobe -v error -select_streams v:0 -skip_frame nokey \
  -show_entries frame=pts_time -of csv=p=0 IMG_1234.MOV > keyframes.txt

2. Snap each cut outwards

For a rally from 27:14 to 28:08 (1634 s to 1688 s), take the last keyframe at or before 1633 s as the start and the first keyframe at or after 1689.5 s as the end. Snapping outwards means nothing of the rally is lost; snapping the end inwards would leave a clip that stops on a frame whose references are missing.

3. Cut

ffmpeg -y -ss 1632.97 -i IMG_1234.MOV -t 57.66 \
  -map 0:v:0 -map 0:a:0 -c copy -movflags +faststart rally-01.mp4

4. Do not join the clips with concat -c copy

Each copied clip starts on a keyframe while its audio starts a few milliseconds off, and the concat demuxer adds those offsets up. On a real recording that gave a permanent 1.01 s audio offset. Build the reel with one encode instead: why, and the command, plus the flags that keep iPhone HDR.

For tennis, it is one command

Tennis Evolution does steps 1–3 for every rally in a list, builds the labelled reel and verifies the results: tennis-evolution all IMG_1234.MOV --highlights rallies.txt --top 5. See the iPhone tennis highlight guide.

FAQ

Can ffmpeg cut video at an exact frame without re-encoding?

No. A stream copy has to start on a keyframe. For frame-exact cuts you must re-encode at least the start of the clip.

How far apart are keyframes in iPhone videos?

Typically 32 frames, about 1.07 s at 29.97 fps. List them with ffprobe -skip_frame nokey.

Does a -c copy cut keep HDR and rotation?

Yes. Nothing is re-encoded, so HDR, Dolby Vision metadata and the rotation flag stay as recorded.

Try the rally lab Free vs Pro