Why Re-encoding Should Be Avoided
Every time video is re-encoded, quality drops slightly and time is spent computing the new encoded stream. For trimming operations (cutting the start, end, or middle of a video), re-encoding is often unnecessary.
FFmpeg's -c copy flag enables "stream copy" mode: the encoded video and audio data are copied bit-perfect from input to output. The result is a trimmed file in seconds, not minutes, with zero quality loss.
The catch: stream copy only works at keyframe boundaries. Most modern video has keyframes every 2-10 seconds. Trimming between keyframes either:
- Loses frames at the start (until the next keyframe)
- Includes extra frames at the start (back to the previous keyframe)
This post covers the practical FFmpeg trim workflow with both stream copy and frame-accurate trimming. For broader FFmpeg context, see HEVC to H.264 for Premiere.
Stream Copy Trim
The basic command:
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.mp4 -c copy output.mp4
Parameters:
-ss 00:00:30: start at 30 seconds-to 00:05:00: end at 5 minutes-c copy: stream copy (no re-encoding)-i input.mp4: input file
The output is a 4:30 clip from the source. Processing time: 1-2 seconds for a 1-hour source. Quality: identical to source.
Keyframe Boundary Effect
When the trim points fall on keyframes, output is exactly as specified. When they don't:
| Input | Source keyframe pattern | Result |
|---|---|---|
| 30s start, KF at 28s and 32s | -ss 30 produces output starting at 28s | |
| 30s start, KF at 30s | Exact start at 30s | |
| 30s start, source has 1s GOP | Likely exact start at 30s (small GOP) |
For most modern video (2-second GOP), the start time is within ±2 seconds of requested. For exact start: re-encode or use a different approach.
Frame-Accurate Trim with Re-encoding
For frame-accurate trim:
ffmpeg -ss 00:00:30.5 -to 00:05:00 -i input.mp4 \
-c:v libx264 -preset ultrafast -crf 18 \
-c:a aac -b:a 192k \
-movflags +faststart \
output.mp4
CRF 18 is visually lossless. The -preset ultrafast minimizes re-encoding time at slight file size cost. Output is exactly 30.5 seconds to 5:00 from source.
For maximum quality at the cost of more time: -preset slow -crf 18.
Hybrid Approach
For best of both worlds: re-encode the start and end, stream-copy the middle:
# Stream copy from nearest keyframe at 30s to 5:00
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.mp4 -c copy temp_middle.mp4
# Re-encode just the part before 30s
ffmpeg -ss 00:00:28 -to 00:00:30 -i input.mp4 \
-c:v libx264 -preset ultrafast -crf 18 \
-c:a aac \
temp_start.mp4
# Concat
ffmpeg -f concat -safe 0 -i <(printf "file '%s'\nfile '%s'\n" "$(pwd)/temp_start.mp4" "$(pwd)/temp_middle.mp4") \
-c copy output.mp4
This produces frame-accurate trim at minimal re-encoding cost. Most of the file is stream copy; only the few seconds at the boundaries are re-encoded.
Multiple Trim Operations
For trimming out a segment in the middle (split + concat):
# Get part before bad section
ffmpeg -i input.mp4 -ss 00:00:00 -to 00:02:00 -c copy part1.mp4
# Get part after bad section
ffmpeg -i input.mp4 -ss 00:03:00 -to 00:60:00 -c copy part2.mp4
# Concat
ffmpeg -f concat -safe 0 -i <(printf "file '%s'\nfile '%s'\n" "$(pwd)/part1.mp4" "$(pwd)/part2.mp4") \
-c copy output.mp4
The concat preserves quality (no re-encode). Can be combined with the hybrid approach for frame-accurate cuts.
For batch trim patterns, see Batch Processing Files Guide.
Identifying Keyframes
To check where keyframes are in your video:
ffprobe -v error -select_streams v:0 \
-show_entries packet=pts_time,flags \
-of csv input.mp4 | grep K
Output is a list of timestamps where keyframes occur. Use these for choosing trim points that work with stream copy.
For a video with 2-second GOP at 30 fps: keyframes at every 60 frames (2 seconds).
When Re-encoding Is Necessary
You can't avoid re-encoding when:
- Trimming requires frame-accurate boundaries
- Source has very long GOP (10+ seconds)
- Combining multiple sources with different codecs
- Adding effects, filters, or overlays
- Format conversion (MP4 to WebM, etc.)
- Resolution change
For these: use re-encode workflow. CRF 18 visually lossless preserves quality.
Audio Trim
For audio file trimming:
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.mp3 -c copy output.mp3
MP3 has very small frames (typically 26ms each), so trim is essentially frame-accurate without re-encoding. Same applies to AAC.
For lossless audio (FLAC, WAV):
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.flac -c copy output.flac
Stream copy with audio is much more accurate than with video.
Common Issues
Output starts before requested time: keyframe boundary issue. Either accept the offset, or re-encode for frame accuracy.
Output has black frames at start: source has GOP and the player decodes from the keyframe. Some players handle this gracefully; others show black until next keyframe.
Audio out of sync after trim: audio offset from video keyframes. Re-mux with -vsync cfr.
File size larger than expected: stream copy preserves source bitrate; can't reduce file size with -c copy. Re-encode at higher CRF for smaller files.
FFmpeg trim ignores negative offset: -ss doesn't accept negative values. Use -itsoffset for input offset adjustments.
For broader video processing context, see HEVC to H.264 for Premiere.
Trim with Subtitle Tracks
If your input has subtitles:
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.mkv \
-map 0:v -map 0:a -map 0:s \
-c copy \
output.mkv
The -map flags include video, audio, and subtitle streams. Stream copy preserves them.
For subtitle conversion details, see SRT vs VTT vs ASS.
Trim with Multiple Audio Tracks
For multi-language video:
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.mkv \
-map 0:v -map 0:a:0 -map 0:a:1 -map 0:a:2 \
-c copy \
output.mkv
Maps the video and the first three audio tracks. Useful for Blu-ray rips with multiple language tracks.
For MKV vs MP4 context, see MKV vs MP4 Container.
Frequently Asked Questions
Should I always use stream copy?
For trim-only operations: yes, when accuracy permits. For complex edits: re-encode.
What's the speed difference?
Stream copy: 30x realtime typical. Re-encode: 0.5-1x realtime depending on settings.
Does stream copy work for all formats?
Most modern formats (MP4, MKV, WebM, MOV, FLV). Some legacy formats (AVI, MPEG-1) may have issues. Try stream copy first; if it fails, re-encode.
Can I trim with audio fade in/out?
Stream copy doesn't support audio effects. For fade in/out: re-encode the trim with audio filter:
ffmpeg -ss 00:00:30 -to 00:05:00 -i input.mp4 \
-c:v libx264 -crf 18 \
-c:a aac -af "afade=in:st=0:d=2,afade=out:st=268:d=2" \
output.mp4
What about precise frame-by-frame edits?
For frame-accurate cuts every frame: re-encode. Stream copy is keyframe-aligned only.
How do I trim multiple segments?
Use the concat approach above. Multiple stream-copy trims, concat with -f concat filter.
Related Reading
Bottom Line
For FFmpeg trimming without re-encoding: use -c copy flag, accept keyframe-boundary alignment. For frame-accurate trim: re-encode at CRF 18 with ultrafast preset. Hybrid approach for production work where most of the video is stream-copy and only edge frames re-encode. Our video compressor handles re-encoding at known-good settings.



