Command Palette

Search for a command to run...

Why a Trimmed Video Starts Before Your Cut

Why a Trimmed Video Starts Before Your Cut

T
Toolz Team
|Oct 20, 2026|16 min read
Prefer Toolz.dev on Google

Part of the Editors collection

Video Trimmer

Cut a video down to the part you want, in your browser. Set a start and end, preview the cut, and export without uploading the file anywhere.

Use the Video Trimmer

I once cut a forty-second answer out of an interview, dropped it into a deck, and watched the speaker begin mid-sentence seven seconds before the bit I wanted. I had set the start carefully. The trimmer had ignored me, or so it looked. It had not: it had done the only thing a fast cut can do, which is start at the nearest keyframe before the point I asked for. Once you know that, the behaviour stops being a bug and becomes a choice with two options, and picking the right one takes a second.

TL;DR: A fast trim copies the existing video stream rather than re-encoding it, and a copy can only begin at a keyframe. Ask to start at 0:07 on a file whose keyframes are ten seconds apart and the cut begins at 0:00, because that is the last point the decoder can start from. The end lands where you asked; only the start drifts, and it drifts backwards. The fix when you need the exact frame is to re-encode, which is slower and costs a little quality. The video trimmer offers both and defaults to the fast one.

Why does the cut start earlier than you asked?

Because almost no frame in a video is a complete picture.

Video compression works by storing one full frame and then describing the changes. A keyframe, properly an IDR frame in H.264, holds a whole image and depends on nothing. The frames after it hold differences: this block moved four pixels left, this region is unchanged, these pixels got slightly darker. A frame halfway through that sequence is meaningless on its own, the way a diff is meaningless without the file it applies to.

So when you ask to start at 0:07 and the tool copies the stream without decoding it, there is nothing at 0:07 to copy. There is a description of how 0:07 differs from something earlier. The only places a player can begin are the keyframes, and the only safe one is the last keyframe at or before your start point.

The alternative is to decode the video up to 0:07, throw away what came before, and compress what remains into a new file that begins with a fresh keyframe. That is exact, and it is the slow path, for the reason that it does real work on every frame rather than copying bytes.

How far apart are keyframes, really?

Further than most people assume, and the gap is what decides how wrong a fast cut looks.

I measured it rather than guessing. Encoding thirty seconds of test footage with x264 at its defaults, then listing the keyframes:

ffmpeg -f lavfi -i "testsrc=duration=30:size=640x360:rate=25" -c:v libx264 clip.mp4

ffprobe -select_streams v -show_entries packet=pts_time,flags -of csv=p=0 clip.mp4 \
  | awk -F, '$2 ~ /K/ {print $1}'
# 0.000000
# 10.000000
# 20.000000

One keyframe every ten seconds. That is x264's default of 250 frames between keyframes, at 25 frames a second. On a file encoded with those defaults, a fast trim can begin up to ten seconds before the point you picked.

Most footage you handle is friendlier, because most of it was made for streaming, where players need frequent entry points to switch quality. Here is the range worth knowing:

Source Typical keyframe gap Worst-case drift on a fast cut
Phone recording 1 to 2 seconds Barely noticeable
Streaming video, HLS or DASH 2 to 6 seconds Noticeable on a short clip
x264 or ffmpeg defaults 10 seconds at 25 fps Ruins a short cut
Screen recorder, low motion 10 seconds or more Ruins a short cut

The pattern: anything encoded for a player has close keyframes, and anything encoded once for storage does not.

What does the drift do to the file?

It moves the start and leaves the end alone, which is worth being precise about because it is easy to assume the whole window slides.

Asking the same clip for 0:07 to 0:15, a window of eight seconds, with a stream copy:

Asked for Keyframes in source Result What happened
7s to 15s 0, 10, 20 0s to 15.08s Start fell back to the keyframe at 0
12s to 20s 0, 10, 20 10s to 20.08s Start fell back to the keyframe at 10
7s to 15s every 2s 6s to 15.08s Start fell back one keyframe

The end is right in all three. I checked that by hashing frames rather than trusting the duration: the last frame of the output is byte-identical to the source frame at 15.04 seconds, which is the frame after the one I asked for and the correct place to stop. What changed is where it begins.

This is why the file is longer than the window you selected. A cut you thought was eight seconds arrives as fifteen, not because anything overran, but because seven seconds of lead-in came along. On a clip where the keyframes are two seconds apart, the same cut arrives as nine seconds and nobody notices.

When should you re-encode instead?

Three cases, and outside them the fast path is the better tool.

You need a specific frame. Cutting on a word, on a gesture, on the moment a ball hits a bat. Keyframe accuracy is not good enough and no amount of care with the slider will help, because the limit is in the file rather than in the interface.

The clip is short. A seven-second lead-in on a thirty-second cut is a nuisance. On a four-second cut it is the whole thing.

You are cutting out of a file with sparse keyframes. Screen recordings and anything exported once for archive, as the measurements above show.

The cost is real but smaller than people fear. A re-encode decodes every frame in the window and compresses it again, so it takes time proportional to the length of the cut rather than the size of the file, and it loses a generation of quality. At a constant-rate factor of 23, which is what the trimmer uses for its accurate mode, that loss is close to invisible on one pass. It is a second pass over footage that has already been compressed once, which is the same generation loss that governs compression generally.

How do you find the keyframes in your own file?

One command, and it tells you in advance whether the fast path will do.

# the first ten keyframe timestamps, in seconds
ffprobe -select_streams v -show_entries packet=pts_time,flags -of csv=p=0 input.mp4 \
  | awk -F, '$2 ~ /K/ {print $1}' | head -10

If the gaps are one or two seconds, trim fast and stop thinking about it. If they are ten, and your cut matters, re-encode.

There is a second use for this. If you are producing footage other people will cut, encoding with a shorter keyframe interval makes their life much easier, at a small cost in file size. A keyframe is a full picture, so more of them means more bytes, which is exactly why encoders space them out when nobody asked for anything else.

Does trimming lose quality?

The fast path does not, in the strict sense. Nothing is decoded, so nothing is re-compressed: the frames in the output are the same compressed frames that were in the input, byte for byte, in a new container. Trim a file ten times this way and the tenth is identical in quality to the first.

The accurate path does, once. The window is decoded and compressed again, so it picks up one generation of loss. On well-encoded source at a sensible quality target this is hard to see, and the sensible rule is to make the cut you need in one pass from the original rather than trimming a trim of a trim.

Neither path upscales, sharpens or improves anything. A trimmer removes time, which is the whole job.

Why does my trimmed clip not start playing immediately?

Because of where the index lands, and it is the same flag that matters when compressing.

An MP4 holds a table describing where every frame begins. Written in the obvious order, that table ends up at the end of the file, because the encoder only knows its contents when it has finished. Played from a disk, fine. Served over HTTP, a player cannot start until the whole file has arrived.

The trimmer passes -movflags +faststart, which does a quick second pass and moves that table to the front. The cut then begins playing while it downloads, which is what you want when the file is going into a chat app, a CMS, or a slide that pulls it from a URL.

What happens to the audio?

Audio is cut on its own frame boundaries, and those are much shorter than video keyframe intervals, so the audio can start closer to your mark than the picture does.

That mismatch is the source of the other classic trimming fault: a clip whose sound is slightly ahead of the picture, or that begins with a fragment of a word. The fix is in the arguments rather than in the editing, and the trimmer passes it: -avoid_negative_ts make_zero rebases the timestamps of both streams so that the output starts at zero with the streams still aligned relative to each other. Without it, a stream copy can emit negative timestamps for the frames between the keyframe and your cut point, and players disagree about what to do with those. Some skip, some stall, some play the audio early.

If you only want the sound, cutting the video first and then extracting the audio is the wrong order. Extract first and cut the audio, because audio cuts are frame-accurate and cheap.

Is it better to trim in the phone's photo app?

For a quick personal clip, it is fine and it is right there. For anything you will publish, no, and the reason is not obvious.

Phone editors generally re-encode on export, and they do it with settings chosen for speed and for a predictable file size rather than for fidelity. You pay a generation of loss on every trim. Worse, some of them trim non-destructively, storing your in and out points as metadata next to the original, which looks like a trim on the phone and is not a trim at all once the file leaves it: the recipient gets the full clip, or an edit list their player ignores.

A copy-mode trim avoids both problems. The file you get is the file everyone gets, and the frames in it were never decoded.

Does the video leave my machine?

No. The cut runs through ffmpeg compiled to WebAssembly inside the browser tab: the file is read from disk into page memory, trimmed there, and handed back as a download. The network panel in devtools stays empty of the video while this happens.

For footage, that matters more than for most file types. A clip is usually the largest and most personal thing anyone edits, and the normal arrangement for a free online trimmer is that you upload your footage to a stranger and trust the retention policy on a page you did not read. Here no copy exists to retain.

The limits are the tab's rather than a plan's: a single cut is capped at thirty minutes, and the whole source has to fit in browser memory. Past that, a desktop tool is both faster and more reliable, and saying so is better than handing you a tab that runs out of memory at minute nine.

When is a desktop editor the right tool?

When you are doing more than removing time. Joining several clips, adding titles, colour, music, or cutting on a waveform you need to see at sample level. That is an editing timeline, not a trimmer, and the right answer is a real editor.

Within the browser, the dividing line is nearly as clean. Removing one stretch from one clip is a trim. Joining pieces together is the video editor. Making the result smaller is the compressor, and changing the container or codec is the converter, which is a different operation from compression even though the two get confused constantly.

Why do the preview and the exported file disagree?

Because a trim interface collects the same number from three places that do not agree on what a number is, and getting them onto one value is most of the work in a trimmer.

A text field gives you whatever someone typed, which might be 7, 0:07, 00:00:07 or 7.25. A slider gives a float with more precision than anyone wants. A video element's currentTime gives another float, which is not necessarily the timestamp of a frame at all: browsers are allowed to report a position between frames, and they do.

If those three land on slightly different seconds, the preview shows one thing and the export produces another, which is the specific bug that makes a trimmer feel broken even when the cut is correct. The parser here accepts all three timecode shapes, resolves them right-aligned so the last part is always seconds whatever the length, and hands a single value to both the preview and the export. A half-typed field returns nothing rather than throwing, so the input does not explode on every keystroke while you type 0:0.

The practical advice: type the timecode rather than dragging, when the exact second matters. A slider is for finding the moment, a field is for naming it.

How do I cut a section out of the middle?

Two cuts and a join, and no trimmer does it in one step, which surprises people reasonably often.

Removing the middle of a clip means keeping the part before your selection and the part after it, which is two separate windows, and then putting them back together. The trimmer here produces one window per run, so the sequence is: trim from the start to the beginning of the bad section, trim from the end of the bad section to the end, then join the two in the video editor.

Two things to watch when you do that. The join works cleanly when both pieces share a codec, a resolution and a frame rate, which they will if both came from the same source file through copy-mode trims. And the seam lands on a keyframe boundary on both sides, so the second piece begins slightly earlier than you marked, exactly as described above. If the cut point matters, use the accurate mode for the second piece.

The other option is to stop before you start: if what you want is a highlight rather than a redaction, two separate clips are often more useful than one clip with a gap stitched out of it.

Common questions

Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!