Guide to HLS Live Streaming with FFmpeg CLI

HTTP Live Streaming (HLS) is a popular protocol developed by Apple for delivering video and audio over the internet. It is particularly well-suited for adaptive streaming, allowing you to serve different video at various bitrates to ensure the best available viewing experience for different network conditions. The main benefit is the protocol itself as HTTP is allowed through various network policies. In this text, I will explore using FFmpeg, a super powerful open-source multimedia framework, to create HLS streams. I will also look at different configurations like bitrates, and provide practical examples and use cases to get you started. To play video stream. I am using a VLC player, not HTTP server like NGINX. 

ffmpeg hls streaming

What is HLS?

HLS is a protocol that breaks video content into small file segments, typically ranging from 2 to 10 seconds each. These segments are delivered sequentially to the viewer's device. HLS allows adaptive bitrate switching based on available bandwidth. The playlist file (usually called an M3U8 file) keeps track of these segments and informs the client player on which segments should be played. 
You can find more information in my previous posts:HLS video stream from Opencv

Using FFmpeg to Create HLS Streams

FFmpeg is command-line tool, but also a set of dev libraries known as libav. This text focuses just on CLI. The programming use of FFmpeg is described in the already mentioned article HLS video stream from Opencv.

Installing FFmpeg

To begin, you need to have FFmpeg installed on your system.
For Windows or MacOS, you can download the appropriate FFmpeg package. https://ffmpeg.org/download.html.

You can install it on most Linux systems with (Ubuntu/Debian apt pkg manager)
sudo apt update
sudo apt install ffmpeg

Generating an HLS video stream

To create an HLS stream with FFmpeg, you need to start by capturing a video source. This can be a video file or a live source, like a webcam. Here's a basic command that creates an HLS stream from a video file:
PS C:\ffmpeg\bin> ./ffmpeg -i c:/www/town0.avi -codec: h264 -start_number 0 -hls_time 10
-hls_list_size 0 -f hls stream.m3u8
  • -i input.mp4: Specifies the input file.
  • -codec: h264: re-encoding input to output as h264
  • -start_number 0: Specifies the starting sequence number.
  • -hls_time 10: Sets the duration of each segment to 10 seconds.
  • -hls_list_size 0: Ensures that all segments are saved in the playlist.
  • -f hls stream.m3u8: Sets the output playlist
PS C:\ffmpeg\bin> ./ffmpeg -i c:/www/town0.avi -codec: h264 -start_number 0 -hls_time 10
-hls_list_size 0 -f hls stream.m3u8
[libx264 @ 000001f3792bbac0] using SAR=1/1
[libx264 @ 000001f3792bbac0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 000001f3792bbac0] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 000001f3792bbac0] 264 - core 160 - H.264/MPEG-4 AVC codec
Output #0, hls, to 'stream.m3u8':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: h264 (libx264), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=-1--1,
25 fps, 90k tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[hls @ 000001f379255b40] Opening 'stream0.ts' for writingate=N/A dup=1 drop=0 speed=2.31x
[hls @ 000001f379255b40] Opening 'stream.m3u8.tmp' for writing
[hls @ 000001f379255b40] Opening 'stream1.ts' for writingate=N/A dup=1 drop=0 speed=2.49x
[hls @ 000001f379255b40] Opening 'stream.m3u8.tmp' for writing
[hls @ 000001f379255b40] Opening 'stream2.ts' for writingate=N/A dup=1 drop=0 speed=2.54x
[hls @ 000001f379255b40] Opening 'stream.m3u8.tmp' for writing
[hls @ 000001f379255b40] Opening 'stream3.ts' for writingate=N/A dup=1 drop=0 speed=2.58x
[hls @ 000001f379255b40] Opening 'stream.m3u8.tmp' for writing
[hls @ 000001f379255b40] Opening 'stream4.ts' for writingate=N/A dup=1 drop=0 speed=2.59x
[hls @ 000001f379255b40] Opening 'stream.m3u8.tmp' for writing
frame= 1143 fps= 66 q=-1.0 Lsize=N/A time=00:00:45.72 bitrate=N/A dup=1 drop=0 speed=2.62x
video:16685kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
On the log above, you can see that streamx.ts are created one after another. The stream.m3u8 is updated through intermediate .tmp files. The result of the playlist is visible in the following text. The format includes video segment names and some properties of the stream. 

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.000000,
stream0.ts
#EXTINF:10.000000,
stream1.ts
#EXTINF:10.000000,
stream2.ts
#EXTINF:10.000000,
stream3.ts
#EXTINF:5.720000,
stream4.ts
#EXT-X-ENDLIST
File system content of the command is:
-a----        10/27/2024   3:39 PM            238 stream.m3u8
-a----        10/27/2024   3:38 PM        3607532 stream0.ts
-a----        10/27/2024   3:38 PM        4154236 stream1.ts
-a----        10/27/2024   3:39 PM        3595876 stream2.ts
-a----        10/27/2024   3:39 PM        4010040 stream3.ts
-a----        10/27/2024   3:39 PM        2234380 stream4.ts
The stream.m3u8 can be played by VLC from the directory where it is stored. 

Adaptive Bitrate Streaming

One of the most powerful features of HLS is its ability to adapt the bitrate based on network conditions. To achieve this, you need to generate multiple versions of your stream at different bitrates and create a master playlist (M3U8) that contains all variants.

Here's how you can use FFmpeg to create multiple variants of an HLS stream:

./ffmpeg -i c:/www/town0.avi -filter_complex "[0:v]split=3[v720][v480][v360];
[v720]scale=-2:720[v720out];
[v480]scale=-2:480[v480out];
[v360]scale=-2:360[v360out]"
-map "[v720out]" -c:v:0 libx264 -b:v:0 1500k -c:a:0 aac -ar 48000 -b:a:0 128k
-hls_time 10 -hls_segment_filename '720p_%03d.ts' 720p.m3u8
-map "[v480out]" -c:v:1 libx264 -b:v:1 800k -c:a:1 aac -ar 44100 -b:a:1 96k
-hls_time 10 -hls_segment_filename '480p_%03d.ts' 480p.m3u8
-map "[v360out]" -c:v:2 libx264 -b:v:2 400k -c:a:2 aac -ar 44100 -b:a:2 64k
-hls_time 10 -hls_segment_filename '360p_%03d.ts' 360p.m3u8

  • The command creates segments of 720p_%03d.ts, 480p_%03d.ts, 360p_%03d.ts for three different sizes of video with matching playlists. The input video is split into 3 outputs. Each output is scaled to the appropriate size v720out. The scaled output is then mapped by -map command to its output. All outputs are encoded as h264 codec.
PS C:\ffmpeg\bin> ./ffmpeg -i c:/www/town0.avi -filter_complex "[0:v]split=3[v720]
[v480][v360];
[v720]scale=-2:720[v720out];
[v480]scale=-2:480[v480out];
[v360]scale=-2:360[v360out]"
-map "[v720out]" -c:v:0 libx264 -b:v:0 1500k -c:a:0 aac -ar 48000 -b:a:0 128k
-hls_time 10 -hls_segment_filename '720p_%03d.ts' 720p.m3u8
-map "[v480out]" -c:v:1 libx264 -b:v:1 800k -c:a:1 aac -ar 44100 -b:a:1 96k
-hls_time 10 -hls_segment_filename '480p_%03d.ts' 480p.m3u8
-map "[v360out]" -c:v:2 libx264 -b:v:2 400k -c:a:2 aac -ar 44100 -b:a:2 64k
-hls_time 10 -hls_segment_filename '360p_%03d.ts' 360p.m3u8

ffmpeg version 4.3 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.3.1 (GCC) 20200621
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, avi, from 'c:/www/town0.avi':
  Duration: 00:05:00.00, start: 0.000000, bitrate: 3932 kb/s
    Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p,
1920x1080 [SAR 1:1 DAR 16:9], 3928 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
Codec AVOption b (set bitrate (in bits/s)) specified for output file #1 (480p.m3u8)
has not been used for any stream. The most likely reason is either wrong type (e.g.
a video option with no video streams) or that it is a private option of some encoder
which was not actually used for any stream.
Codec AVOption b (set bitrate (in bits/s)) specified for output file #2 (360p.m3u8)
has not been used for any stream. The most likely reason is either wrong type
(e.g. a video option with no video streams) or that it is a private option of
some encoder which was not actually used for any stream.
Stream mapping:
  Stream #0:0 (mpeg4) -> split
  scale -> Stream #0:0 (libx264)
  scale -> Stream #1:0 (libx264)
  scale -> Stream #2:0 (libx264)
Press [q] to stop, [?] for help
[libx264 @ 000001dfe959cb40] using SAR=1/1
[libx264 @ 000001dfe959cb40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
FMA3 BMI2 AVX2
[libx264 @ 000001dfe959cb40] profile High, level 3.1, 4:2:0, 8-bit
[libx264 @ 000001dfe959cb40] 264 - core 160 - H.264/MPEG-4 AVC codec - Copyleft
2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0
analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16
chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2
threads=18 lookahead_threads=3 sliced_threads=0 nr=0 decimate=1 interlaced=0
bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1
weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0
rc_lookahead=40 rc=abr mbtree=1 bitrate=1500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69
qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, hls, to '720p.m3u8':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: h264 (libx264), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1,
1500 kb/s, 25 fps, 90k tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/1500000 buffer size: 0 vbv_delay: N/A
[libx264 @ 000001dfe95a0e40] using SAR=1280/1281
[libx264 @ 000001dfe95a0e40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
FMA3 BMI2 AVX2
[libx264 @ 000001dfe95a0e40] profile High, level 3.0, 4:2:0, 8-bit
[libx264 @ 000001dfe95a0e40] 264 - core 160 - H.264/MPEG-4 AVC codec
- Copyleft 2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=3
deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1
me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1
chroma_qp_offset=-2 threads=15 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1
interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1
b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40
intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69
qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #1, hls, to '480p.m3u8':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #1:0: Video: h264 (libx264), yuv420p, 854x480 [SAR 1280:1281 DAR 16:9],
q=-1--1, 25 fps, 90k tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[libx264 @ 000001dfe95a5740] using SAR=1/1
[libx264 @ 000001dfe95a5740] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
FMA3 BMI2 AVX2
[libx264 @ 000001dfe95a5740] profile High, level 3.0, 4:2:0, 8-bit
[libx264 @ 000001dfe95a5740] 264 - core 160 - H.264/MPEG-4 AVC codec - Copyleft
2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0
analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16
chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2
threads=11 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0
bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0
direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40
intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69
qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #2, hls, to '360p.m3u8':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #2:0: Video: h264 (libx264), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1,
25 fps, 90k tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[hls @ 000001dfe95a1e00] Opening '360p_000.ts' for writing00:09.84 bitrate=N/A dup=3
drop=0 speed=1.61x
[hls @ 000001dfe95a1e00] Opening '360p.m3u8.tmp' for writing
[hls @ 000001dfe959d600] Opening '480p_000.ts' for writing
[hls @ 000001dfe959d600] Opening '480p.m3u8.tmp' for writing
[hls @ 000001dfe95cac00] Opening '720p_000.ts' for writing
[hls @ 000001dfe95cac00] Opening '720p.m3u8.tmp' for writing
[hls @ 000001dfe95a1e00] Opening '360p_001.ts' for writing00:19.60 bitrate=N/A dup=3
drop=0 speed=1.64x
[hls @ 000001dfe95a1e00] Opening '360p.m3u8.tmp' for writing
[hls @ 000001dfe959d600] Opening '480p_001.ts' for writing
[hls @ 000001dfe959d600] Opening '480p.m3u8.tmp' for writing
[hls @ 000001dfe95cac00] Opening '720p_001.ts' for writing
[hls @ 000001dfe95cac00] Opening '720p.m3u8.tmp' for writing
[hls @ 000001dfe95a1e00] Opening '360p_002.ts' for writing00:29.72 bitrate=N/A dup=3
drop=0 speed=1.69x
[hls @ 000001dfe95a1e00] Opening '360p.m3u8.tmp' for writing
[hls @ 000001dfe959d600] Opening '480p_002.ts' for writing
[hls @ 000001dfe959d600] Opening '480p.m3u8.tmp' for writing
[hls @ 000001dfe95cac00] Opening '720p_002.ts' for writing
[hls @ 000001dfe95cac00] Opening '720p.m3u8.tmp' for writing
frame= 1032 fps= 45 q=27.0 q=28.0 q=28.0 size=N/A time=00:00:39.08 bitrate=N/A dup=3
drop=0 speed=1.72x
The results are three playlists with their own sets of segments.
360p.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:25
#EXTINF:10.000000,
360p_025.ts
#EXTINF:10.000000,
360p_026.ts
#EXTINF:10.000000,
360p_027.ts
#EXTINF:10.000000,
360p_028.ts
#EXTINF:5.440000,
360p_029.ts
#EXT-X-ENDLIST
480p.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:25
#EXTINF:10.000000,
480p_025.ts
#EXTINF:10.000000,
480p_026.ts
#EXTINF:10.000000,
480p_027.ts
#EXTINF:10.000000,
480p_028.ts
#EXTINF:5.440000,
480p_029.ts
#EXT-X-ENDLIST
Differenc in quality and as you can see on the following file listing can be recognized by file size. 
-a----        10/28/2024   2:59 PM            244 360p.m3u8
-a----        10/28/2024   2:56 PM         430332 360p_000.ts
-a----        10/28/2024   2:56 PM         537868 360p_001.ts

-a----        10/28/2024   2:59 PM            244 480p.m3u8
-a----        10/28/2024   2:56 PM         674356 480p_000.ts
-a----        10/28/2024   2:56 PM         826824 480p_001.ts

-a----        10/28/2024   2:59 PM            244 720p.m3u8
-a----        10/28/2024   2:56 PM        1712492 720p_000.ts
-a----        10/28/2024   2:56 PM        2145456 720p_001.ts

Live Streaming with HLS

If you want to create a live stream from a webcam or another input, you can use a command like this:
PS C:\ffmpeg\bin> ./ffmpeg -i c:/www/town0.avi -codec: h264 -start_number 0 -preset
veryfast -maxrate 2000k -bufsize 4000k -g 50 -hls_time 2 -hls_list_size 5 -f
hls live.m3u8
The main difference is
  • -preset veryfast: Uses a faster preset for x264 encoding (less compression)
  • -g 50: Specifies the GOP (Group of Pictures) size, which affects latency
  • -hls_time 2 smaller time
PS C:\ffmpeg\bin> ./ffmpeg -i c:/www/town0.avi -codec: h264 -start_number 0 -preset
veryfast -maxrate 2000k -bufsize 4000k -g 50 -hls_time 2 -hls_list_siz
e 5 -f hls live.m3u8
ffmpeg version 4.3 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.3.1 (GCC) 20200621
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig
--enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray
--enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb
--enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine
--enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora
--enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp
--enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma
--enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis
--enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid
--enable-libaom --enable-libgsm --disable-w32threads --enable-libmfx
--enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va
--enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
--enable-amf
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, avi, from 'c:/www/town0.avi':
  Duration: 00:05:00.00, start: 0.000000, bitrate: 3932 kb/s
    Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658),
yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 3928 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg4 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 00000179957bb580] using SAR=1/1
[libx264 @ 00000179957bb580] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
AVX FMA3 BMI2 AVX2
[libx264 @ 00000179957bb580] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 00000179957bb580] 264 - core 160 - H.264/MPEG-4 AVC codec -
Copyleft 2003-2020 - http://www.videolan.org/x264.html - options: cabac=1
ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00
mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11
fast_pskip=1 chroma_qp_offset=0 threads=18 lookahead_threads=6 sliced_threads=0
nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3
b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=50
keyint_min=5 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=crf mbtree=1 crf=23.0
qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 vbv_maxrate=2000 vbv_bufsize=4000 crf_max=0.0
nal_hrd=none filler=0 ip_ratio=1.40 aq=1:1.00
Output #0, hls, to 'live.m3u8':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: h264 (libx264), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9],
q=-1--1, 25 fps, 90k tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.91.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 2000000/0/0 buffer size: 4000000 vbv_delay: N/A
[hls @ 0000017995755600] Opening 'live0.ts' for writingtrate=N/A dup=1 drop=0 speed=1.44x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live1.ts' for writingtrate=N/A dup=1 drop=0 speed=3.34x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live2.ts' for writingtrate=N/A dup=1 drop=0 speed=3.85x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live3.ts' for writingtrate=N/A dup=1 drop=0 speed=3.51x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live4.ts' for writingtrate=N/A dup=1 drop=0 speed=3.48x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live5.ts' for writingtrate=N/A dup=1 drop=0 speed=3.37x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live6.ts' for writingtrate=N/A dup=1 drop=0 speed=3.54x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live7.ts' for writingtrate=N/A dup=1 drop=0 speed=3.58x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live8.ts' for writingtrate=N/A dup=1 drop=0 speed= 3.7x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live9.ts' for writing
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live10.ts' for writingrate=N/A dup=1 drop=0 speed=3.95x
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live11.ts' for writing
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
[hls @ 0000017995755600] Opening 'live12.ts' for writing
[hls @ 0000017995755600] Opening 'live.m3u8.tmp' for writing
frame=  601 fps=107 q=-1.0 Lsize=N/A time=00:00:24.04 bitrate=N/A dup=1 drop=0 speed=4.28x
video:5950kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead:
unknown
[libx264 @ 00000179957bb580] frame I:13    Avg QP:22.49  size:116382
[libx264 @ 00000179957bb580] frame P:235   Avg QP:23.67  size: 16397
[libx264 @ 00000179957bb580] frame B:353   Avg QP:29.90  size:  2057
[libx264 @ 00000179957bb580] consecutive B-frames:  3.2% 38.9% 49.9%  8.0%
[libx264 @ 00000179957bb580] mb I  I16..4:  6.8% 63.0% 30.2%
[libx264 @ 00000179957bb580] mb P  I16..4:  0.5%  3.8%  0.4%  P16..4: 26.8%  7.4%  4.2%
 0.0%  0.0%    skip:56.8%
[libx264 @ 00000179957bb580] mb B  I16..4:  0.0%  0.1%  0.0%  B16..8:  4.7%  1.6%  0.1%  
direct: 0.7%  skip:92.8%  L0:34.7% L1:43.6% BI:21.7%
[libx264 @ 00000179957bb580] 8x8 transform intra:71.0% inter:63.0%
[libx264 @ 00000179957bb580] coded y,uvDC,uvAC intra: 78.5% 50.7% 5.3% inter: 4.3% 1.8% 0.0%
[libx264 @ 00000179957bb580] i16 v,h,dc,p: 26% 23% 40% 11%
[libx264 @ 00000179957bb580] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 22% 30%  5%  3%  3%  4%  4%  8%
[libx264 @ 00000179957bb580] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 24% 20% 12%  8%  7%  6%  7%  6% 10%
[libx264 @ 00000179957bb580] i8c dc,h,v,p: 48% 26% 22%  4%
[libx264 @ 00000179957bb580] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 00000179957bb580] kb/s:2027.47

-a----        10/31/2024   1:55 PM            226 live.m3u8
-a----        10/31/2024   1:55 PM         503840 live0.ts
-a----        10/31/2024   1:55 PM         576032 live1.ts
-a----        10/31/2024   1:55 PM         499704 live10.ts
-a----        10/31/2024   1:55 PM         477708 live11.ts
-a----        10/31/2024   1:55 PM          96820 live12.ts
-a----        10/31/2024   1:55 PM         550276 live2.ts
-a----        10/31/2024   1:55 PM         472256 live3.ts
-a----        10/31/2024   1:55 PM         505720 live4.ts
-a----        10/31/2024   1:55 PM         600660 live5.ts
-a----        10/31/2024   1:55 PM         510796 live6.ts
-a----        10/31/2024   1:55 PM         518316 live7.ts
-a----        10/31/2024   1:55 PM         488048 live8.ts
-a----        10/31/2024   1:55 PM         510044 live9.ts

Use cases of HLS streaming

HLS is widely used by video-on-demand platforms like Netflix and Disney+ to deliver high-quality adaptive streams.

HLS is used for streaming live events such as sports, conferences, and concerts, where adaptive streaming ensures a smooth experience for viewers on different network conditions.

Online educational platforms can use HLS to provide lectures and tutorials that are accessible to users across various devices, with different network speeds.

HLS is also popular for user-generated live content. Platforms like YouTube Live and Facebook Live use it for low-latency, scalable delivery.

Conclusion

HLS is an extremely versatile streaming protocol that offers a powerful solution for creating adaptive video streams. FFmpeg CLI makes the task simpler by providing all the tools you need to create various versions of stream and manage bitrates. FFmpeg is an open-source rockstar, with licensed parts as well. It will help you with so many video tasks as a command line tool or as a libav library if you are a developer. I personally enjoy FFmpeg from both sides. 
Previous Post
No Comment
Add Comment
comment url