FFmpeg -ss, -t, and -to Flags: Input vs Output Seeking

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:
-ss** sets the start position (the seek point)-t** sets the duration of the output-to** sets the end timestamp
-t and -to are mutually exclusive. If you use both, -t wins and -to gets ignored silently.
The critical distinction isn't between -t and -to. It's 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 (311KB) instead of the expected 5 seconds. The cut boundaries snapped to the nearest keyframes.
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. Then it starts writing output.
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 (200KB). The timestamp landed right where expected.
The cost: on long files, FFmpeg decodes everything before the seek point just to discard it. A seek to 1:30:00 in a 2-hour file means decoding 90 minutes of video you don't want.
The Sweet Spot: Input Seek + Re-encode
You can get both speed and precision by combining input seeking with re-encoding:
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). This is the right default for most trimming jobs.
| Scenario | Approach | Tradeoff |
|---|---|---|
| Quick rough cut | `-ss` before `-i` + `-c copy` | Instant, but keyframe-aligned |
| Frame-accurate trim | `-ss` after `-i` + re-encode | Exact, but decodes everything |
| Fast AND precise | `-ss` before `-i` + re-encode | Best of both |
-t vs -to: Duration vs End Position
-t specifies how long the output should be. -to specifies an absolute end timestamp.
With output seeking (both flags after -i):
# 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.003-second file. -t 3 means "3 seconds of output." -to 8 means "stop when the input timeline hits 8 seconds."
With input seeking (-ss before -i), the timeline resets to zero at the seek point. This makes -to and -t behave the same way:
# These two produce identical output
ffmpeg -ss 5 -i input.mp4 -t 3 -c copy output.mp4
ffmpeg -ss 5 -i input.mp4 -to 3 -c copy output.mp4
This trips people up. When -ss is before -i, -to 10 doesn't mean "stop at 10s in the original file." It means "stop 10 seconds from wherever the seek landed."
Common Pitfalls
**Using -c copy and expecting exact timestamps.** Stream copy can't cut between keyframes. You'll get extra frames at the start or end. If you need precision, drop -c copy and re-encode.
**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. -to 10 means 10 seconds from the new start, not 10 seconds into the source.
Using output seeking on huge files. Output seeking at -ss 3:59:00 on a 4-hour file decodes nearly the entire thing before producing output. Use input seeking if processing speed matters.
**Using -to before -i on old FFmpeg versions.** The -to flag as an input option requires FFmpeg 4.0+. Older versions silently ignore it, and your output contains the full file.
**Combining -t and -to.** FFmpeg doesn't warn you. It uses -t and throws away -to. If your output duration looks wrong, check for both in your command.
Trimming Video via API
If you're building an app that trims video programmatically, managing -ss placement and keyframe alignment in subprocess calls gets old fast. Especially at scale.
FFmpeg Micro handles this with one API call. You pass the FFmpeg flags directly:
curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": [{"url": "https://example.com/video.mp4"}],
"outputFormat": "mp4",
"options": [
{"option": "-ss", "argument": "2"},
{"option": "-t", "argument": "5"},
{"option": "-c:v", "argument": "libx264"}
]
}'
The API runs FFmpeg on cloud infrastructure with auto-scaling. No subprocess management, no keyframe debugging, no server to maintain. Sign up for a free API key to try it.
FAQ
Does flag order matter for -t and -to?
As output options (after -i), -t sets duration and -to sets an absolute end position in the input timeline. With -ss before -i, the input timeline resets to zero, so -t and -to become equivalent for the seeked segment.
Can I use -ss, -t, and -to all in the same command?
You can use -ss with either -t or -to, but not -t and -to together. If both are present, FFmpeg silently uses -t and ignores -to.
Why is my trimmed video longer than expected?
You're probably using -c copy (stream copy). FFmpeg can only cut at keyframe boundaries with stream copy, so the output snaps to the nearest keyframes. Drop -c copy and re-encode for frame-accurate timestamps.
What's the fastest way to trim a video with FFmpeg?
Input seeking with stream copy: ffmpeg -ss 30 -i input.mp4 -t 10 -c copy output.mp4. This jumps to the nearest keyframe and copies bytes without decoding. It finishes in milliseconds but won't be frame-accurate.
*Last verified: 2026-05-11 against FFmpeg 7.x*
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

How to Trim and Cut Video with FFmpeg (CLI + API Guide)
Learn how to trim and cut video with FFmpeg using -ss, -t, and -to flags. Covers keyframe-accurate cutting, stream copy vs re-encode, and the FFmpeg Micro API.

FFmpeg CRF Explained: Quality vs File Size Guide
Learn how FFmpeg CRF (Constant Rate Factor) controls video quality vs file size. CRF scales for H.264, H.265, VP9, AV1 with recommended settings per use case.

How to Crop and Resize Video with FFmpeg
Learn how to crop and resize video with FFmpeg using scale, crop, and pad filters. Includes CLI commands, API examples, and TikTok/Reels presets.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free