How-To & Life · Guide · Audio, Video & Voice
How to trim videos
Lossless vs re-encoded trim, keyframe constraints, handling audio track drift, trim markers, and client-side tools that don't upload your files.
Ninety percent of video editing is just trimming — clipping out the silence at the start, the fumble at the end, the awkward pause in the middle. The thing most people don’t realize is that trimming can be lossless or lossy, and the difference shows up as both file size and image quality. Cut at a keyframe and you keep the original encode intact. Cut between keyframes and you force a re-encode, which degrades quality. This guide covers the keyframe mechanics that determine lossless versus lossy cuts, FFmpeg’s -ss and -to flags, the precise-vs-fast mode tradeoff, how container formats affect what’s possible, and when re-encoding is the right call.
Advertisement
Keyframes: the anchor of modern video
Modern video codecs (H.264, H.265, VP9, AV1) compress by storing only the differences between consecutive frames. A keyframe (also called an I-frame) is a full, self-contained image. Every other frame (P-frames and B-frames) depends on surrounding frames to reconstruct. A video might have a keyframe every 2–10 seconds; the rest are deltas.
This matters for trimming because you can only cut cleanly at a keyframe. Cut between keyframes and the resulting file starts on a delta that has no anchor, which means either the decoder fails, or the player recomputes by decoding from the previous keyframe and skipping — which means re-encoding.
Lossless trim (stream copy)
When you trim at keyframe boundaries, you can tell the encoder “don’t re-encode, just copy the compressed stream” — FFmpeg’s -c copy flag. The operation takes seconds even for a multi-gigabyte file, and the output is pixel-identical to the source.
# Lossless trim at keyframes ffmpeg -ss 00:00:10 -to 00:00:40 -i input.mp4 -c copy output.mp4 # Note: -ss before -i = seeks fast to the nearest prior keyframe # This may result in slight timing offset from requested position
The catch: your cut point snaps to the nearest prior keyframe. If you asked for 10.0 seconds but the nearest keyframe is at 8.5 seconds, your output starts at 8.5s. For most casual cuts this is fine. For precise frame-accurate edits, it’s not.
Precise (re-encoding) trim
To hit an exact frame, you have to re-encode — decode from the prior keyframe to your target, then re-encode the output starting at that frame as a new keyframe.
# Precise trim, re-encodes ffmpeg -i input.mp4 -ss 00:00:10.500 -to 00:00:40.000 \ -c:v libx264 -preset slow -crf 18 -c:a aac -b:a 192k output.mp4 # -ss AFTER -i = accurate but slower (decodes from start) # crf 18 = visually lossless H.264 # preset slow = better compression at cost of encode time
Re-encoding always costs some quality (generation loss) and takes time proportional to clip length. For a 2-minute output, expect 30 seconds to 5 minutes depending on your machine and preset.
The -ss position trick
FFmpeg’s behavior depends on where -ss sits:
# -ss BEFORE -i: fast seek to nearest keyframe # (input-side seek, snaps to keyframe) ffmpeg -ss 00:00:10 -i input.mp4 -t 30 -c copy out.mp4 # -ss AFTER -i: accurate seek (output-side seek) # (decodes everything before the mark, slow) ffmpeg -i input.mp4 -ss 00:00:10 -t 30 -c libx264 out.mp4 # Combined: fast seek to keyframe, then precise adjust ffmpeg -ss 00:00:09 -i input.mp4 -ss 00:00:01 -t 29 -c libx264 out.mp4
The combined form is the common compromise — fast seek to roughly the right region, then precise adjust within that region. It’s much faster than pure output-side seek on a long file.
Start and duration vs start and end
-to sets an absolute end time in the source. -t sets a duration from -ss. They produce different results when combined with -ss:
ffmpeg -ss 00:00:10 -to 00:00:40 -i input.mp4 ... # Output: 30 seconds (from 10 to 40 in source) ffmpeg -ss 00:00:10 -t 30 -i input.mp4 ... # Output: 30 seconds starting at 10
Use -to when you know the exact end frame in the source. Use -t when you know the desired output length.
Container formats and their quirks
MP4 (H.264/H.265 in MPEG-4) — the default for most web video. Trims cleanly at keyframes with stream copy. Supports faststart (-movflags +faststart) so the moov atom is at the file head, making the video playable before full download.
MOV (QuickTime) — Apple’s container. Similar to MP4 for trimming purposes. QuickTime Player trims losslessly by default using the same mechanism.
WebM (VP9/VP8/AV1) — open-source web video. Trim works the same way; stream copy is fine at keyframes.
MKV (Matroska) — supports almost any codec. Good for lossless trimming of long captures.
Raw MPEG-TS (often from broadcasts or older captures) — can trim at any frame because every frame is closer to self-contained, but the format is less efficient.
When to re-encode intentionally
Even if you don’t need frame-precise cuts, re-encode when:
The source is higher bitrate than needed. A 50Mbps camera recording compressed to 8Mbps is 6x smaller with no meaningful quality loss for web use.
The codec doesn’t play on target. HEVC (H.265) source re-encoded to H.264 for older browsers.
You’re joining clips. Concatenation requires matching codec parameters; re-encoding normalizes them.
You need a specific output spec. Social platform requirements (Twitter’s 140-sec H.264, Instagram’s 1080p 30fps cap) force re-encoding.
Keyframe interval and fragment size
If you control the encode pipeline upstream, set a shorter keyframe interval for content you expect to trim. A 1-second keyframe interval means you can trim losslessly within 1 second of any target, at the cost of ~10% larger files. For streaming (HLS/DASH) this is already the norm.
# Encode with 1-second keyframes for easier lossless trimming ffmpeg -i source.mov -c:v libx264 -g 30 -keyint_min 30 \ -sc_threshold 0 -c:a aac output.mp4
Audio considerations
Audio tracks also have their own frame boundaries (AAC frames are ~23ms). Lossless trim doesn’t guarantee frame-accurate audio, but the drift is imperceptible (<25ms). If you’re trimming right at speech boundaries, you may prefer to re-encode audio with a precise cut.
Preserving metadata
Trim operations with -c copy preserve almost all metadata — timestamps, GPS, camera info, chapters. Re-encoding may strip extended metadata. Use -map_metadata 0 to explicitly preserve it, and -movflags use_metadata_tags for MP4.
Common mistakes
Re-encoding when stream copy would work. Wastes time and loses quality unnecessarily. Try -c copy first.
Expecting frame-accurate cuts from stream copy. Stream copy snaps to keyframes. If precision matters, you must re-encode.
Using -ss after -i on long files. Decodes from the start and takes forever. Use -ss before -i for fast seek.
Omitting -c:a when re-encoding video. Audio re-encodes too if you don’t specify; may lose quality. Use -c:a copy to keep audio untouched when re-encoding video.
Trimming without faststart. The moov atom ends up at the tail of the file, so the video isn’t streamable. Add -movflags +faststart for web.
Joining trimmed segments that don’t share codec parameters. Concatenation fails. Re-encode to a common spec before joining.
Forgetting that timestamps can be non-zero. After trim, some players may show the source’s start timestamp. Add -reset_timestamps 1 to zero it.
Run the numbers
Trim videos without installing FFmpeg using the video trimmer. Pair with the video-to-GIF converter for turning a trimmed segment into a looping demo, and the video mute tool when you need to strip the audio track before publishing.
Advertisement