FFmpeg, is a free open-source media editing tool, it is generally called a swiss army knife of media editing tool.
FFmpeg is quite popular in the industry among companies handling media. Although, FFmpeg project is well documented, there isn’t enough material at one place for transcoding videos to Apple HLS format. In this article we will learn how to transcode videos to HLS format using FFmpeg.
Apple HTTP Live Streaming(HLS) is a video streaming format, in which the original video is divided into multiple chunks and delivered over HTTP. Video, which is typically in
.mp4 format gets transcoded and various
.ts files along with a playlist file,
.m3u8 is created. The playlist, as the name suggests will have the details of the chunks to be played. This playlist can also store information to adapt the playback to changing network conditions. You can find more details about this on the link provided above.
Need for transcoding
Why do we have to transcode videos for various formats? Transcoding helps in adapting the playback of video to different video playing conditions. Below are some.
- different media devices like mobile, desktop which might require different resolutions
- changing network bandwidth
- video playback on wide range of players
FFmpeg can be installed on mac via the below command. This is a pre-built executable with specific set of features. If you need full set of features, you can download the build from ffmpeg site.
brew install ffmpeg
You can check if ffmpeg is installed properly via below command.
The above command will print to console something like below. Notice the different features enabled and disabled in the configuration. This is where you have to look at if a feature is missing in the build currently installed.
Transcoding video to HLS format
Now that ffmpeg is installed and ready to be used, we can now start encoding a sample video
input.mp4 to HLS format using below command.
If you are not aware in what extensions the HLS formatted video output files are generated. Below is the list.
- .m3u8 file, this is an index file consisting of pointers to different segment files
- .ts files, different segements of the video
The mime-types for output files if you are uploading them to a cloud store like S3 are
- m3u8 file, mime-type will be
- ts file, mime-type will be
ffmpeg -y -i input.mp4 -c:a aac -strict experimental -ac 2 -b:a 64k -ar 44100 -c:v libx265 -pix_fmt yuv420p -level 1.3 -maxrate 192K -bufsize 1M -crf 18 -r 10 -g 30 -f hls -hls_time 9 -hls_list_size 0 -s 320x180 output.m3u8
Now let’s understand the flags one-by-one and how they are relevant in the context of HLS. Also, once you understand these flags, you can modify them to create different presets for different resolutions for example.
y- override the output files if they exists while the command is run
i- input to the command, video to be transcoded
-c:a- audio codec to be used for transcoding, in the above case it is
-ac- number of audio channels, 2 in this case
-b:a- audio bit rate, 64kb
-strict- how strictly to follow standards, allow experimental or WIP encoders/decoders
-ar- set audio sampling rate, in Hz
-c:v- video codec to be used, H265 in this case
-pix_fmt- pixel format
-level- set the level in VPS ans SPS
-maxrate- max bit rate
-bufsize- set ratecontrol buffer size
-crf- quality size tradeoff, ranges between 0 and 63, high numbers indicate low quality and smaller output size
-g- sets keyframe placement or GOP size
-f- force input and output file format
-hls_time- segment time
-hls_list_size- maximum number segments in the playlist, if set to 0, will contain all segments
Testing the transcoded video with ffplay
You can test the generated playlist with below command. This uses an utility called
ffplay, which was already downloaded with your
Downloading HLS format videos, .m3u8 and .ts files
ffmpeg can also read input from remote locations, which we can use to download HLS format videos. Below is the command for going about the same.
ffmpeg -i "https://testlocation/video.mp4" -c copy "output.mp4"