FFmpeg’s
-ss,
-t, and
-to flags control time-based selection, while streamcopying preserves the original bitstream without reencoding. Understanding their interaction with keyframes is critical for accurate trimming and efficient processing. This guide clarifies how these options function differently depending on whether you are seeking precisely or copying streams directly.
The Role of Keyframes in Trimming
Video compression relies on keyframes (or I-frames) to store complete image data. Intermediate frames (P and B frames) only store changes relative to previous or future keyframes. When FFmpeg processes a video, it must locate the nearest keyframe before the requested start time to decode the video correctly. If you request a frame that falls between keyframes, the decoder must process all preceding frames from the last keyframe until it reaches your target. This behavior explains why some trim operations appear slower than others or result in slight inaccuracies if not handled properly.
When using streamcopy mode, FFmpeg cannot modify the internal structure of the video. It can only cut at existing keyframe boundaries. Therefore, the actual start point of your output file will be the first keyframe at or after your specified start time. This limitation does not apply when transcoding, where FFmpeg can decode every frame and reconstruct the timeline exactly as requested.
Difference Between -ss Before and After -i
The position of the
-ss flag relative to the input file argument (
-i) determines the method of seeking. Placing
-ss before
-i enables fast, approximate seeking. FFmpeg jumps directly to the nearest keyframe and discards all frames until the desired timestamp. This method is extremely fast because it avoids decoding the bulk of the video file. However, the resulting cut may start slightly before or after the exact second requested, depending on keyframe alignment.
Conversely, placing
-ss after
-i triggers precise seeking. FFmpeg decodes the entire video from the beginning up to the specified timestamp. While this ensures pixel-perfect accuracy, it is significantly slower, especially for large files. This method is necessary when you need to guarantee that the output starts exactly at the specified time, regardless of keyframe positions.
# Fast seeking (before -i)
ffmpeg -ss 00:01:30 -i input.mp4 -c copy output.mp4
# Precise seeking (after -i)
ffmpeg -i input.mp4 -ss 00:01:30 -c copy output.mp4
Understanding -t and -to Flags
The
-t flag specifies the duration of the output segment rather than an absolute end time. For example,
-t 10 tells FFmpeg to record ten seconds of content starting from the defined start point. This is useful when you want to extract a clip of a specific length without calculating the end timestamp manually.
The
-to flag defines an absolute end timestamp. Unlike
-t, which measures duration,
-to sets a hard stop. If you specify both
-ss and
-to, FFmpeg extracts the segment between those two points. Using
-to is often clearer for users who think in terms of clock time rather than duration.
# Extract 5 seconds starting at 1 minute
ffmpeg -ss 00:01:00 -t 00:00:05 -i input.mp4 output.mp4
# Extract from 1 minute to 2 minutes
ffmpeg -ss 00:01:00 -to 00:02:00 -i input.mp4 output.mp4
Streamcopy vs. Transcoding
Streamcopy (
-c copy) instructs FFmpeg to copy the audio and video streams directly into the new container without reencoding. This process is nearly instantaneous and causes zero quality loss because no compression artifacts are generated. However, streamcopy is limited by keyframe availability. As noted earlier, cuts will snap to the nearest keyframe. Additionally, streamcopy may fail if the output format requires different codecs or if the container does not support the original stream structure.
Transcoding involves decoding the video, potentially applying filters or changes, and then reencoding it into the target format. This process allows for precise cuts, resolution changes, and codec conversions. The trade-off is significant CPU usage and potential quality degradation due to generational loss. Use transcoding when you need precision or format changes; use streamcopy for speed and quality preservation when keyframe alignment is acceptable.
For more advanced editing tasks, such as removing specific frames or concatenating videos, understanding these core principles remains essential. You might also find it helpful to review techniques for
Removing Every Nth Frame in Raw Video Using FFmpeg to further manipulate video timelines.
Frequently Asked Questions
Why does my trimmed video start at a different time than expected?
This occurs when using streamcopy with approximate seeking. FFmpeg snaps the start point to the nearest keyframe, which may be several seconds before or after your requested timestamp. To fix this, move the
-ss flag after the
-i argument to enable precise seeking, though this will increase processing time.
Can I use -t and -to together in the same command?
No, these flags serve mutually exclusive purposes for defining the segment's boundary.
-t sets a duration from the start point, while
-to sets an absolute end time. Using both will likely result in an error or unexpected behavior. Choose one based on whether you know the length of the clip or its end time.
Does streamcopy preserve audio sync issues present in the source?
Yes, streamcopy simply moves data chunks without altering them. If the original file has audio drift or synchronization problems, these will persist in the output. Transcoding allows FFmpeg to resynchronize streams during the encoding process, which can sometimes correct minor sync issues inherent in the source material.
Is fast seeking safe for live streaming inputs?
Fast seeking is generally unsafe for live streams or network inputs where seeking capabilities are limited. Many live sources do not support random access to keyframes. In such cases, use precise seeking (placing
-ss after
-i) or avoid seeking altogether, accepting that FFmpeg will process the stream from the beginning.
How do I check keyframe locations in a video file?
You can use ffprobe to inspect the video structure. Run
ffprobe -show_frames -v quiet input.mp4 | grep "key_frame=1" to list all keyframes. This helps you understand why certain trim points behave unexpectedly when using streamcopy, allowing you to plan your edits around existing I-frame positions.