producing HLS Packaging using FFmpeg & Bento4
Tags: hls, ffmpeg, bento4, tutorial
Published: 2023-01-21 05:43:33

#### HlS it's a standard created by apple in order to deliver audio/video streaming using ordinary web servers.

If we want to prepare a video into a standard HLS stream, we will need both FFMPEG and Bento4.

Install `Bento4` by `docker`

`docker file` and `compose.yml` file location: [https://github.com/alfg/docker-bento4](https://github.com/alfg/docker-bento4)
```bash
docker pull alfg/bento4
```
run your command by 
```bash
docker run -it --rm alfg/bento4 mp4info 
```
Convert your master into multi-bit rate with FFMPEG
To begin, we will have 1 master file that will need to be converted in different bit rates 

Let's say our master file is in 1080p(1920x1080). For our streaming needs, we need convert that file into multi bit rate for smoothing user experience

```bash
ffmpeg -i input.mp4 -c:v h264 -crf 22 -tune film -profile:v main -level:v 4.0 -maxrate 5000k -bufsize 10000k -r 25 -keyint_min 25 -g 50 -sc_threshold 0 -c:a aac -ar 44100 -b:a 128k -ac 2 -pix_fmt yuv420p -movflags +faststart 1080.mp4 -s 1280x720 -c:v h264 -crf 24 -tune film -profile:v main -level:v 4.0 -maxrate 2500k -bufsize 5000k -r 25 -keyint_min 25 -g 50 -sc_threshold 0 -c:a aac -ar 44100 -b:a 128k -ac 2 -pix_fmt yuv420p -movflags +faststart 720.mp4 -s 854x480 -c:v h264 -crf 30 -tune film -profile:v main -level:v 4.0 -maxrate 1250k -bufsize 2500k -r 25 -keyint_min 25 -g 50 -sc_threshold 0 -c:a aac -ar 44100 -b:a 96k -ac 2 -pix_fmt yuv420p -movflags +faststart 480.mp4 -s 640x360 -c:v h264 -crf 33 -tune film -profile:v main -level:v 4.0 -maxrate 900k -bufsize 1800k -r 25 -keyint_min 25 -g 50 -sc_threshold 0 -c:a aac -ar 44100 -b:a 96k -ac 2 -pix_fmt yuv420p -movflags +faststart 360.mp4 -s 320x24 -c:v h264 -crf 36 -tune film -profile:v main -level:v 4.0 -maxrate 625k -bufsize 1250k -r 25 -keyint_min 25 -g 50 -sc_threshold 0 -c:a aac -ar 22050 -b:a 64k -ac 1 -pix_fmt yuv420p -movflags +faststart 240.mp4
```

* `-i input.mp4`: Master file
* `-c:v h264`: Convert master file into h164 codec
* `-crf 22`: Constant Rate Factor(CRF). Value can be anything from 0(lossless) up to 50(lowest)
* `-tune flim`: especially suitable for ﬁlm content
* `-profile:v main -level 4.0`: Compress frames for compatibility reasons 
* `-maxrate 5000k -bufsize 10000k`: Along with the -crf option enabled this will instruct FFMPEG to encode our video with a speciﬁc constrained mode
* `-r 25 -keyint_min 25 -g 50`: Instruction for produce a 25 FPS file with the recommended distance between key frames every 2 seconds
* `-sc_threshold 0`: Instruction no to insert key frame at scene changes
* `-c:a aac -ar 44100 -b:a 128k -ac 2`: This will produce a standard AAC audio file at 44.100 KHz, at 128 Kbps, in stereo
* `-pix_fmt yuv420p`: option for produce a video compatible with major video players, including Apple's QuickTime
* `-movflags +faststart`: The -movflags
+faststart instruction is advised whenever there is a streaming case-scenario. This particular instruction tells FFMPEG to move a speciﬁc part of an Mp4 File, called "atom"
* `1080.mp4`: outfile name 
* `\`: Backslash symbol means `Escape`. It is used also as a new line delimiter
* `-s 1280x720`: Instruction for resize the input file into desire resolution

> 1080.mp4 - For the 1920x1080 resolution
720.mp4 - For the 1280x720 resolution
480.mp4 - For the 854x480 resolution
360.mp4 - For the 640x360 resolution
240.mp4 - For the 426x240 resolution

> 1080.mp4 - AAC Audio at 128 Kbps, 44.100 kHz, Stereo
720.mp4 - same as 1080.mp4
480.mp4 - AAC Audio at 96 Kbps, 44.100 kHz, Stereo
360.mp4 - same as 480.mp4
240.mp4 - AAC Audio at 64 Kbpx, 22.050 kHz, Mono

#### Create multi-bitrate HLS playlist with Bento4
```bash
mp4hls 240.mp4 360.mp4 480.mp4 720.mp4 1080.mp4 --verbose --segment-duration 6 --output-single-file
```
* `mp4hls`: this will launch Bento4's Mp4HLS tool
* `240.mp4 360.mp4 480.mp4 720.mp4 1080.mp4`: Five input file 
* `--verbose`: Enable verbose mode. This will print progress in terminal. If any error happens in processing, it will show that error
* `--segment-duration 6`: This will produce standard 6 second segment, as per Apple's technical requirements 
* `--output-single-file`: This will store segment data in a single output file per input file. In working directory, it will create a output directory containing all the `HLS` playlist and media files.

This whole directory can be then uploaded onto our web server, so to stream and deliver our desired HLS playlists.