Originally published at ffmpeg-micro.com
Trimming video with FFmpeg looks simple until your 5-second clip comes out as 7 seconds. Or your output starts a few frames late. The culprit is almost always flag order: where you put -ss relative to -i completely changes how FFmpeg processes the seek.
This post covers what -ss, -t, and -to do, why their placement matters, and when to use each combination.
What -ss, -t, and -to Actually Do
Three flags control timing in FFmpeg:
-
-sssets the start position (the seek point) -
-tsets the duration of the output -
-tosets the end timestamp
-t and -to are mutually exclusive. If you use both, -t wins and -to gets ignored silently.
The critical distinction is where you place -ss: before -i (input seeking) or after -i (output seeking). The two produce different results with different tradeoffs.
Input Seeking: Fast but Imprecise
Place -ss before -i and FFmpeg jumps directly to the nearest keyframe at or before your timestamp. It doesn't decode anything before that point.
ffmpeg -ss 2 -i input.mp4 -t 5 -c copy output.mp4
This is fast. On a 2-hour file, FFmpeg skips straight to the 2-second mark instead of decoding from the beginning.
The catch: with -c copy (stream copy), FFmpeg can only cut at keyframes. If the nearest keyframe is at 0.5s instead of 2s, your output starts earlier than you asked for. In testing on a 13-second 640x360 MP4, this command produced a 7.07-second file instead of the expected 5 seconds.
Output Seeking: Slow but Frame-Accurate
Place -ss after -i and FFmpeg decodes the entire file from the beginning, throwing away frames until it hits your timestamp.
ffmpeg -i input.mp4 -ss 2 -t 5 output.mp4
This re-encodes by default, which means frame-accurate cuts. The same test file produced exactly 5.005 seconds. The timestamp landed right where expected.
The cost: on long files, FFmpeg decodes everything before the seek point just to discard it.
The Sweet Spot: Input Seek + Re-encode
ffmpeg -ss 2 -i input.mp4 -t 5 -c:v libx264 -preset fast output.mp4
Input seeking jumps to the approximate position (fast), then re-encoding trims at exact frame boundaries (precise). Best of both.
-t vs -to: Duration vs End Position
-t specifies how long the output should be. -to specifies an absolute end timestamp.
# Extract from 5s, for 3 seconds
ffmpeg -i input.mp4 -ss 5 -t 3 output.mp4
# Same result: from 5s, stop at the 8-second mark
ffmpeg -i input.mp4 -ss 5 -to 8 output.mp4
Both produce a 3-second file. When -ss is before -i, the timeline resets to zero, so -to and -t become equivalent.
Common Pitfalls
Using -c copy and expecting exact timestamps. Stream copy can't cut between keyframes. Drop -c copy and re-encode for precision.
Mixing up -t and -to with input seeking. When -ss is before -i, both flags are relative to the seeked position, not the original file.
Using output seeking on huge files. Output seeking at -ss 3:59:00 on a 4-hour file decodes nearly the entire thing. Use input seeking.
Using -to before -i on old FFmpeg versions. Requires FFmpeg 4.0+. Older versions silently ignore it.
Combining -t and -to. FFmpeg doesn't warn you. It uses -t and throws away -to.
FAQ
Why is my trimmed video longer than expected?
You're probably using -c copy. FFmpeg can only cut at keyframe boundaries with stream copy. Re-encode for frame-accurate timestamps.
What's the fastest way to trim a video?
Input seeking with stream copy: ffmpeg -ss 30 -i input.mp4 -t 10 -c copy output.mp4. Finishes in milliseconds but won't be frame-accurate.
Last verified: 2026-05-11 against FFmpeg 7.x
Top comments (0)