Segmenting Video with ffmpeg

To stream video with HLS, you need to divide your video into segments of a fixed duration and add them to a playlist. In the book I use Apple’s HTTP Live Streaming tools to do this. Here’s an example using mediafilesegmenter:

$ mediafilesegmenter -f /Library/WebServer/Documents/vod sample.mov

This command takes the video (sample.mov) and writes out the segments and the playlist to the /Library/WebServer/Documents/vod directory. Unfortunately, Apple’s tools will only work on a Mac.

However, recent versions of ffmpeg can also output HLS compatible files. Given a video as input, it will divide it into segments and create a playlist for us.

Here’s the equivalent of the command above using ffmpeg:

$ ffmpeg -y \
 -i sample.mov \
 -codec copy \
 -bsf h264_mp4toannexb \
 -map 0 \
 -f segment \
 -segment_time 10 \
 -segment_format mpegts \
 -segment_list "/Library/WebServer/Documents/vod/prog_index.m3u8" \
 -segment_list_type m3u8 \
 "/Library/WebServer/Documents/vod/fileSequence%d.ts"

We use ffmpeg‘s segment muxer to segment the video. We can specify the segment duration with the -segment_time option. The last argument passed to ffmpeg is the path to where the segments should be written; it contains a format specifier (%d) similar to those supported by the printf function in C. The %d will be replaced with the current sequence number. In this example, the segments will be named fileSequence0.ts, fileSequence1.ts, and so on.

And that’s how you process a video for streaming with HLS using ffmpeg. There are other examples in the book, including how to use ffmpeg to segment a live video stream, so if you want to learn how, buy your copy today.

In part 2 we’ll look at how to segment video using ffmpeg’s hls muxer.

4 thoughts on “Segmenting Video with ffmpeg

  1. David Schere

    ffmpeg -y -i input.mpg -codec copy -bsf h264_mp4toannexb -map 0 -f segment -segment_time 5 -segment_format mpegts -segment_list play.m3u8 -segment_list_type PreRoll2%03d.ts

    ffmpeg version 3.2.2 Copyright (c) 2000-2016 the FFmpeg developers
    built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
    configuration: –enable-gpl –enable-libass –enable-libfdk-aac –enable-libfreetype –enable-libmp3lame –enable-libopus –enable-libtheora –enable-libvorbis –enable-libvpx –enable-libx264 –enable-nonfree

    At least one output file must be specified

    Reply
  2. Boris

    Hello Simon,
    Thanks for your tutorials.
    In my case, my objective is to create a live stream from video files but I cant get a transition between video files with different fps,resolution,sar-dar parameters..
    1.txt file consists of three mp4 files with different resolution,sar,dar,fps parameters.
    (One of them is 720p,25fps, other one is 576p,24fps but different sar-dar value than that of the 1st file, third one is 480p,24fps)

    ffmpeg -y -f concat \
    -stream_loop -1 \
    -i 1.txt \
    -c:v copy -preset:v fast -c:a copy -strict experimental \
    -f ssegment \
    -segment_list_size 12 \
    -segment_format mpegts \
    -segment_list “/var/www/html/playlist.m3u8” \
    -segment_list_type m3u8 \
    -hls_flags delete_segments \
    “/var/www/html/out%04d.ts” &

    When the last segment of the first file is about to end, it gives “non-monotonous dts in output stream” and stream stops so I can not watch the second video file. I’d appreciate if you would lead me to right direction. What is the right way to stream multiple video files with segmenting in ffmpeg?

    Thanks
    Boris

    Reply
    1. Simon Post author

      The EXT-X-DISCONTINUITY tag can be used to indicate encoding changes between media files. Unfortunately, I don’t think ffmpeg supports it at the moment.

      Reply

Leave a Reply