ffmpegsegment-muxerhlsvideo-splittingcli

FFmpeg Segment Muxer: segment_time, strftime, and reset_timestamps

·Javid Jamae·6 min read
FFmpeg Segment Muxer: segment_time, strftime, and reset_timestamps

The FFmpeg segment muxer splits a video into multiple files based on duration. Three flags cause most of the confusion: segment_time, strftime, and reset_timestamps. The official FFmpeg docs define each in one sentence. This guide shows what they actually do, with verified examples and the gotchas that trip people up.

Quick answer: Split a video into 5-second segments with timestamped filenames and clean playback timestamps:

ffmpeg -i input.mp4 -c copy -f segment -segment_time 5 -reset_timestamps 1 -strftime 1 "segment_%Y%m%d_%H%M%S.mp4"

What segment_time Does (and Why Your Segments Are the Wrong Length)

segment_time sets the target duration for each segment in seconds. With -c copy (stream copy, no re-encoding), FFmpeg can only cut at keyframe boundaries. If your video has keyframes every 8 seconds and you set -segment_time 3, your segments will be roughly 8 seconds each.

Here's what happens with a 13-second video and -segment_time 3 -c copy:

ffmpeg -i input.mp4 -c copy -f segment -segment_time 3 -reset_timestamps 1 "output_%03d.mp4"

Actual segment durations:

SegmentExpectedActual
output_000.mp4~3s8.34s
output_001.mp4~3s5.01s

The muxer waited for the next keyframe after the 3-second mark, which didn't arrive until 8.34 seconds in. This isn't a bug. Stream copying can't split mid-GOP because there's no re-encoding to create a new keyframe at the cut point.

Fix: force keyframes at your split points. This requires re-encoding:

ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast -crf 23 \
  -force_key_frames "expr:gte(t,n_forced*3)" \
  -f segment -segment_time 3 -reset_timestamps 1 "output_%03d.mp4"

Now the segments are exactly 3 seconds:

SegmentDuration
output_000.mp43.00s
output_001.mp43.00s
output_002.mp43.00s
output_003.mp43.00s
output_004.mp41.34s

The tradeoff: re-encoding takes longer and changes quality. For most batch-processing pipelines, ultrafast preset keeps the speed penalty small.

reset_timestamps: Why Your Player Shows the Wrong Time

Without reset_timestamps, each segment inherits its position from the original video. The second segment of a 10-second-split video starts at 00:00:10, not 00:00:00.

ffmpeg -i input.mp4 -c copy -f segment -segment_time 5 "output_%03d.mp4"

Check the second segment's start time with ffprobe:

ffprobe -v quiet -show_entries format=start_time -of default=noprint_wrappers=1 output_001.mp4
# start_time=8.408000

The player jumps to 8.4 seconds on its internal timeline. Some players handle this gracefully. Others show a frozen frame for the first 8 seconds, or skip forward.

Add -reset_timestamps 1 and each segment starts at zero:

ffmpeg -i input.mp4 -c copy -f segment -segment_time 5 -reset_timestamps 1 "output_%03d.mp4"

Same ffprobe check: start_time=0.000000

If you're generating segments for standalone playback (social media clips, download chunks, CMS assets), always use -reset_timestamps 1. If you're generating HLS segments for a streaming player that tracks absolute position, you might intentionally leave it off.

strftime: Timestamped Filenames Instead of Sequential Numbers

The default output pattern uses %03d for sequential numbering: segment_000.mp4, segment_001.mp4. With -strftime 1, you can use date/time tokens in the filename instead:

ffmpeg -i input.mp4 -c copy -f segment -segment_time 5 \
  -reset_timestamps 1 -strftime 1 "segment_%Y%m%d_%H%M%S.mp4"

This produces files like segment_20260530_050835.mp4. The timestamp comes from your system clock at the moment FFmpeg creates each segment file, not from the video's internal timestamps.

Common strftime tokens:

TokenMeaningExample
%Y4-digit year2026
%mMonth (01-12)05
%dDay (01-31)30
%HHour (00-23)14
%MMinute (00-59)30
%SSecond (00-59)45

This is useful for live recording pipelines, security camera footage, or any workflow where you need to correlate segment files with wall-clock time.

**You can't mix %03d and strftime in the same pattern.** It's one or the other. If -strftime 1 is set, sequential counters like %03d won't work.

Generating an HLS Playlist with segment_list

The segment muxer can generate a playlist file alongside the segments:

ffmpeg -i input.mp4 -c copy -f segment -segment_time 3 \
  -segment_list playlist.m3u8 -segment_list_type m3u8 \
  -reset_timestamps 1 "segment_%03d.ts"

The generated playlist.m3u8:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:9
#EXTINF:8.408400,
segment_000.ts
#EXTINF:5.005000,
segment_001.ts
#EXT-X-ENDLIST

For a CSV manifest (useful for programmatic processing):

ffmpeg -i input.mp4 -c copy -f segment -segment_time 5 \
  -segment_list segments.csv -segment_list_type csv \
  -reset_timestamps 1 "segment_%03d.mp4"

Output: segment_000.mp4,0.000000,8.408400. Filename, start time, end time. Easy to parse in any language.

Common Pitfalls

Segments are way longer than segment_time. You're using -c copy and the GOP interval is larger than your segment time. Either re-encode with -force_key_frames or accept keyframe-aligned cuts.

strftime filenames all have the same timestamp. Short videos segment faster than one-second clock resolution. For sub-second segmentation of small files, use %03d sequential naming instead.

Player shows black frames at segment start. Missing -reset_timestamps 1. Add it.

"Could not write header" error. The output format doesn't support the segment muxer. Use -segment_format mp4 (or mpegts, matroska) to set the container format explicitly when the extension alone isn't enough.

HLS playlist has wrong TARGETDURATION. TARGETDURATION reflects the actual longest segment, not your -segment_time value. If keyframe alignment stretches a segment, the playlist reflects that.

Skipping the Server: Video Segmentation via API

If you're building an automation pipeline and don't want to install or manage FFmpeg, an API handles the infrastructure for you. FFmpeg Micro processes video with a single HTTP call:

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": "-c:v", "argument": "libx264"}, {"option": "-preset", "argument": "ultrafast"}]}'

No FFmpeg installation, no server to maintain. For the full segment-splitting workflow via API, see How to Split Video into Segments with FFmpeg API.

FAQ

Does segment_time guarantee exact segment durations?

Only when re-encoding. With -c copy, FFmpeg cuts at the nearest keyframe after the target time. Use -force_key_frames with re-encoding for precise cuts.

Can I use strftime with HLS output?

Yes, but HLS players expect sequential or predictable segment names in the playlist. Using strftime with -segment_list works, but test your player. Sequential naming (%03d) is safer for HLS delivery.

What's the difference between the segment muxer and HLS muxer?

The HLS muxer (-f hls) is purpose-built for Apple HLS streaming with native playlist generation, encryption, and variant streams. The segment muxer (-f segment) is a general-purpose splitter that can output any container format with optional playlist generation. Use the HLS muxer for streaming delivery, segment muxer for batch splitting.

Does reset_timestamps affect audio sync?

It resets both video and audio timestamps together, so sync is preserved. Problems arise with some codec/muxer combinations where the audio stream's timestamp base doesn't align cleanly. If you hear audio drift, try adding -avoid_negative_ts make_zero.

What containers work with the segment muxer?

MP4, MPEG-TS, Matroska (MKV), WebM, and most other FFmpeg-supported container formats. Set the format explicitly with -segment_format if the file extension is ambiguous.

*Last verified: 2026-05-30 against FFmpeg 4.3*

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.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Ready to process videos at scale?

Start using FFmpeg Micro's simple API today. No infrastructure required.

Get Started Free