How to split a video into chunks based on duration using FFmpeg?

I am building a simple streaming service and I have read that to stream a large video in duration I need to use HLS format which allows me to split the video into chunks each of four seconds in duration, I am using FFmpeg for video-related tasks, is there any way I can split a video into smaller chunks using FFmpeg?

To split a video into chunks based on duration using FFmpeg is very easy, you just have to use the segment format provided by FFmpeg. With segment format, you can use the -segment_time option provided by FFmpeg to set chunk duration. Consider the following command as an example for your use case.

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:10:00 -f segment output%03d.mp4

  • -i input.mp4: Indicates the input file (input.mp4) to be segmented.
  • -c copy: This option is used to make a duplicate copy without re-encoding.
  • -map 0: This will tell the FFmpeg to get all streams from the input file.
  • -segment_time 00:10:00: Indicates the duration for each segment. In this case, it’s set to 10 minutes.
  • -f segment: Sets the output format as segmented files.
  • output%03d.mp4: Indicates the output file name pattern whereas, the %03d represents a sequence number which is assigned to each segment, starting from 001. The segments will be saved as output001.mp4, output002.mp4, and so on.

After splitting you can also merge videos/audios in FFmpeg.

For more visit: Splitting large videos into smaller chunks with FFmpeg

Why only the first chunk of the chunks created by FFmpeg’s segment format is playable?

Usually, segment format takes care of errors generated in timestamps by splitting the video into chunks but sometimes it generates negative timestamps for some chunks which can create issues with video playback.

To avoid this kind of issue you can include -the reset_timestamps 1 option which resets timestamps at the beginning of each segment so that each segment will start with near-zero timestamps.

Does the above command divide a video into equal-length pieces?

You can use the below command to divide into equal-length pieces:

ffmpeg -i 'input.mp4' -map 0 -codec copy -f segment -segment_time 15:00 'output%03d.mp4'
The options are as follows:
-i video-name.mp4:the input file
-map 0: use the first input file for all outputs
-codec copy: does not recompress the video
-f segment: the output file will be divided into multiple segments
-segment_time 10:00: it will create the segments of this duration (15 minutes in the example)
output%03d.mp4: the output files like output001.mp4 etc. (3 is the number of digits in the counter)

Because FFmpeg creates separate media files with no index that ties them together, only the initial piece of the chunks produced by the segment format of FFmpeg can be played. Media players can only play the first segment without a valid index since they are unable to traverse from one piece to the next.

An index file (such as M3U8 for HLS or DASH manifest) must be prepared along with the segmented media files in order for all the segments to play together seamlessly. Media players can play all the segments in order thanks to the information in this index file.