{"slug": "how-to-split-video-into-segments-with-ffmpeg-cli-api", "title": "How to Split Video into Segments with FFmpeg (CLI + API)", "summary": "This article explains how to split a video into equal-length segments using FFmpeg's segment muxer, detailing key flags like `-segment_time`, `-reset_timestamps`, and `-c copy` for fast, keyframe-aligned cuts. It also covers advanced options such as generating CSV segment lists, timestamp-based filenames, and forcing exact timing through re-encoding. Finally, the guide introduces the FFmpeg Micro API as an alternative to managing server infrastructure for automated video processing pipelines.", "body_md": "Originally published at [ffmpeg-micro.com](https://www.ffmpeg-micro.com/blog/ffmpeg-split-video-into-segments).\n\nYou need to chop a long video into equal-length clips. Maybe you're building a social media repurposing pipeline, batch-processing uploads for a CMS, or splitting recordings into chapters. FFmpeg's segment muxer handles this, but getting it right means fighting with keyframe alignment, timestamp resets, and infrastructure you don't want to manage.\n\nThis guide covers the exact FFmpeg commands for splitting video, the flags that matter, and how to skip the server setup entirely with an API.\n\n## Quick answer\n\nSplit a video into 10-second segments with no re-encoding:\n\n```\nffmpeg -i input.mp4 -c copy -f segment -segment_time 10 -reset_timestamps 1 segment_%03d.mp4\n```\n\nThis uses the segment muxer to cut at the nearest keyframe boundary. Each output file gets its own timestamps starting at zero.\n\n## How the FFmpeg segment muxer works\n\nThe segment muxer (`-f segment`\n\n) tells FFmpeg to write output to multiple files instead of one. It splits based on a time interval you set with `-segment_time`\n\n.\n\n```\nffmpeg -i input.mp4 \\\n  -c copy \\\n  -f segment \\\n  -segment_time 30 \\\n  -reset_timestamps 1 \\\n  output_%03d.mp4\n```\n\nKey flags:\n\n-\n`-f segment`\n\nactivates the segment muxer -\n`-segment_time 30`\n\nsets the target duration for each segment in seconds -\n`-reset_timestamps 1`\n\nresets timestamps to zero for each segment (without this, players show wrong seek positions) -\n`-c copy`\n\ncopies streams without re-encoding (fast, but cuts only at keyframes) -\n`output_%03d.mp4`\n\nis the numbered output pattern (`000`\n\n,`001`\n\n,`002`\n\n, ...)\n\nThe `%03d`\n\npattern in the output filename is required. FFmpeg increments the number for each new segment.\n\n## Getting a segment manifest\n\nIf your pipeline needs to know what segments were created and their exact timestamps, add `-segment_list`\n\n:\n\n```\nffmpeg -i input.mp4 \\\n  -c copy \\\n  -f segment \\\n  -segment_time 30 \\\n  -reset_timestamps 1 \\\n  -segment_list segments.csv \\\n  -segment_list_type csv \\\n  segment_%03d.mp4\n```\n\nThe CSV output looks like this:\n\n```\nsegment_000.mp4,0.000000,30.030000\nsegment_001.mp4,30.030000,60.060000\nsegment_002.mp4,60.060000,85.418750\n```\n\nEach row has the filename, start time in seconds, and end time in seconds. You can also use `-segment_list_type flat`\n\nfor just filenames or `-segment_list_type ffconcat`\n\nfor FFmpeg concat demuxer format.\n\n## Timestamp-based filenames with strftime\n\nFor automation pipelines where you're processing videos on a schedule, timestamp-based filenames prevent collisions:\n\n```\nffmpeg -i input.mp4 \\\n  -c copy \\\n  -f segment \\\n  -segment_time 30 \\\n  -reset_timestamps 1 \\\n  -strftime 1 \\\n  \"clip_%Y%m%d_%H%M%S.mp4\"\n```\n\nThis produces files like `clip_20260523_143000.mp4`\n\n. Useful when you're processing multiple source videos into the same output directory.\n\n## The keyframe problem\n\nWhen you use `-c copy`\n\n(stream copy, no re-encoding), FFmpeg can only cut at keyframe boundaries. If your video has keyframes every 2 seconds and you request 5-second segments, your actual segments might be 4 or 6 seconds long.\n\nTwo ways to handle this:\n\n**Accept keyframe-aligned cuts** (fast, slightly imprecise):\n\n```\nffmpeg -i input.mp4 -c copy -f segment -segment_time 5 -reset_timestamps 1 output_%03d.mp4\n```\n\n**Force exact timing** (requires re-encoding, 10-50x slower):\n\n```\nffmpeg -i input.mp4 \\\n  -c:v libx264 -crf 23 \\\n  -force_key_frames \"expr:gte(t,n_forced*5)\" \\\n  -f segment \\\n  -segment_time 5 \\\n  -reset_timestamps 1 \\\n  output_%03d.mp4\n```\n\nThe second approach re-encodes the video and inserts keyframes at exact 5-second intervals. Accurate, but dramatically slower depending on your hardware and encoding settings.\n\nFor most batch processing and content repurposing workflows, keyframe-aligned cuts are good enough.\n\n## Splitting video with the FFmpeg Micro API\n\nRunning FFmpeg on your own server means managing binaries, scaling for concurrent jobs, and handling timeouts on long videos. The FFmpeg Micro API handles the infrastructure so you can focus on your pipeline logic.\n\nThe API uses `-ss`\n\n(seek) and `-t`\n\n(duration) per transcode job, which gives you precise control over exactly what you extract from each video.\n\n**Extract a 30-second segment starting at 1 minute:**\n\n```\ncurl -X POST https://api.ffmpeg-micro.com/v1/transcodes \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"inputs\": [{\"url\": \"https://storage.example.com/video.mp4\"}],\n    \"outputFormat\": \"mp4\",\n    \"options\": [\n      {\"option\": \"-ss\", \"argument\": \"60\"},\n      {\"option\": \"-t\", \"argument\": \"30\"},\n      {\"option\": \"-c\", \"argument\": \"copy\"}\n    ]\n  }'\n```\n\nThe response includes a job ID you can poll:\n\n```\n{\n  \"id\": \"b5f5a9c0-9e33-4e77-8a5b-6a0c2cd9c0b3\",\n  \"status\": \"queued\",\n  \"output_format\": \"mp4\"\n}\n```\n\n**Check status and download the result:**\n\n```\ncurl https://api.ffmpeg-micro.com/v1/transcodes/JOB_ID \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n\ncurl https://api.ffmpeg-micro.com/v1/transcodes/JOB_ID/download \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n**Split a 5-minute video into 30-second segments programmatically:**\n\n``` python\nimport requests\n\nAPI_KEY = \"YOUR_API_KEY\"\nBASE = \"https://api.ffmpeg-micro.com/v1\"\nVIDEO_URL = \"https://storage.example.com/video.mp4\"\nSEGMENT_SECONDS = 30\nTOTAL_SECONDS = 300\n\nheaders = {\n    \"Authorization\": f\"Bearer {API_KEY}\",\n    \"Content-Type\": \"application/json\"\n}\n\njobs = []\nfor start in range(0, TOTAL_SECONDS, SEGMENT_SECONDS):\n    resp = requests.post(f\"{BASE}/transcodes\", headers=headers, json={\n        \"inputs\": [{\"url\": VIDEO_URL}],\n        \"outputFormat\": \"mp4\",\n        \"options\": [\n            {\"option\": \"-ss\", \"argument\": str(start)},\n            {\"option\": \"-t\", \"argument\": str(SEGMENT_SECONDS)},\n            {\"option\": \"-c\", \"argument\": \"copy\"}\n        ]\n    })\n    job = resp.json()\n    jobs.append(job)\n    print(f\"Segment {start}s-{start + SEGMENT_SECONDS}s: {job['id']}\")\n```\n\nAll 10 jobs run in parallel on cloud infrastructure. No server, no queue management, no timeout handling on your end.\n\n[Get a free API key](https://www.ffmpeg-micro.com) and try splitting your first video.\n\n## Common pitfalls when splitting video\n\n**Forgetting -reset_timestamps 1.** Without this flag, each segment keeps the timestamps from the original video. Players show the wrong position on the seek bar, and some players won't play the segments at all.\n\n**Audio sync drift with -c copy.** Stream copy can sometimes drift audio out of sync at cut points. If you hear pops or sync issues, switch to\n\n`-c:a aac`\n\nto re-encode just the audio track while keeping video as copy.**Output pattern without %d.** If you forget the number pattern in the output filename, FFmpeg overwrites the same file for every segment. Always include\n\n`%03d`\n\nor similar.**Segment time vs. actual duration.** With `-c copy`\n\n, segments won't be exactly the duration you requested. They'll be close, but keyframe alignment means they might vary by 1-2 seconds. If you need frame-accurate cuts, you have to re-encode.\n\n**Large video timeouts.** Running the segment muxer locally on a 2-hour video is fine. Running it on a server with a 30-second HTTP timeout kills the job mid-split. If you're processing long videos in a web pipeline, use an async API or background worker.\n\n## FAQ\n\n### How do I split a video into equal parts with FFmpeg?\n\nUse the segment muxer: `ffmpeg -i input.mp4 -c copy -f segment -segment_time 60 -reset_timestamps 1 part_%03d.mp4`\n\n. Replace `60`\n\nwith your desired segment length in seconds. Segments will be approximately equal, with variation depending on keyframe positions.\n\n### Can I split video without re-encoding?\n\nYes. Use `-c copy`\n\nwith the segment muxer for near-instant splitting. The tradeoff is that cuts happen at keyframe boundaries, so segment durations won't be frame-accurate. For most batch processing and content repurposing workflows, keyframe-aligned cuts are close enough.\n\n### What's the difference between the segment muxer and using -ss with -t?\n\nThe segment muxer (`-f segment`\n\n) automatically splits into multiple files in a single FFmpeg pass. The `-ss`\n\n/`-t`\n\napproach extracts one specific clip per command. The segment muxer is faster for creating many segments from one video locally. The `-ss`\n\n/`-t`\n\napproach works better with APIs and cloud pipelines where each segment runs as an independent job.\n\n### Does the FFmpeg segment muxer work with audio files?\n\nYes. Same syntax with audio containers: `ffmpeg -i podcast.mp3 -c copy -f segment -segment_time 600 chunk_%03d.mp3`\n\n. This splits a podcast into 10-minute chunks without re-encoding.\n\n### How do I split video into segments with an API?\n\nFFmpeg Micro lets you submit transcode jobs via HTTP with `-ss`\n\nand `-t`\n\noptions to extract specific segments. Each job runs on cloud infrastructure with automatic scaling. [Sign up for a free API key](https://www.ffmpeg-micro.com) and POST to `/v1/transcodes`\n\nwith your input URL, output format, and seek/duration options.\n\n*Last verified: May 2026 with FFmpeg 7.x and FFmpeg Micro API v1*", "url": "https://wpnews.pro/news/how-to-split-video-into-segments-with-ffmpeg-cli-api", "canonical_source": "https://dev.to/javidjamae/how-to-split-video-into-segments-with-ffmpeg-cli-api-2n8p", "published_at": "2026-05-23 10:15:08+00:00", "updated_at": "2026-05-23 11:04:45.003374+00:00", "lang": "en", "topics": ["developer-tools", "open-source"], "entities": ["FFmpeg"], "alternates": {"html": "https://wpnews.pro/news/how-to-split-video-into-segments-with-ffmpeg-cli-api", "markdown": "https://wpnews.pro/news/how-to-split-video-into-segments-with-ffmpeg-cli-api.md", "text": "https://wpnews.pro/news/how-to-split-video-into-segments-with-ffmpeg-cli-api.txt", "jsonld": "https://wpnews.pro/news/how-to-split-video-into-segments-with-ffmpeg-cli-api.jsonld"}}