Create a live CMAF stream (HLS + MPEG-DASH) with FFMPEG

Learn how to create a CMAF compliant Live ABR video stream. You will be able to stream in HLS & MPEG-dash at the same time using the same video segments.

Create a live CMAF stream (HLS + MPEG-DASH) with FFMPEG

Copyrights

Big Buck Bunny
© copyright 2008, Blender Foundation | www.bigbuckbunny.org

Objective

Learn how to create a CMAF compliant Live ABR video stream.
You will be able to stream in HLS & MPEG-dash at the same time.
ABR means Adaptive Bitrate, depending of the connection speed, the player with automatically switch to the most suitable bitrate.

What is CMAF

CMAF means Common media application format
In order to simplify let's say that CMAF has support for both MPEG-DASH and HLS. You just need to create your video segments once. Both of the manifests (MPD & m3u8) will use the same video segments.

Tools

FFMPEG

FFMPEG will encode the video file.
I am using a static build of FFMPEG v4.1.

FFMPEG static builds

FFMPEG command

./ffmpeg -re -stream_loop -1  -i ~/Documents/videos/BigBuckBunny.mp4 \
-map 0 -map 0 -map 0 -c:a aac -c:v libx264 \
-b:v:0 800k -s:v:0 1280x720 -profile:v:0 main \
-b:v:1 500k -s:v:1 640x340  -profile:v:1 main \
-b:v:2 300k -s:v:2 320x170  -profile:v:2 baseline \
-bf 1 \
-keyint_min 120 -g 120 -sc_threshold 0 -b_strategy 0 -ar:a:1 22050 -use_timeline 1 -use_template 1 \
-window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" -hls_playlist 1 -seg_duration 4 -streaming 1 -remove_at_exit 1 -f dash manifest.mpd

Encode faster with a GPU

If you are using a Mac, you can replace -c:v libx264 by -c:v h264_videotoolbox -allow_sw 1 , it will use the GPU when available.

JavaScript Player

In the following examples, I am using Clappr player.

Clappr is an open sources javascript media player.

HLS player

01_cmaf

<head>
  <title>Clappr Player</title>
  <meta charset="UTF-8">
  <!-- Player -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/dist/clappr.min.js"></script>
  <!-- Quality selector -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/gh/clappr/[email protected]/dist/level-selector.min.js"></script>
</head>

<body>
  <div id="player"></div>
  <script>
    Clappr.Log.setLevel(Clappr.Log.LEVEL_DEBUG);
    var player = new Clappr.Player({
      source: "master.m3u8",
      parentId: "#player",
      mute: true,
      autoPlay: true,
      plugins: {
        core: [LevelSelector]
      },
      levelSelectorConfig: {
        title: '動画品質',
      },
    });
  </script>
</body>

DASH player

02_cmaf

<head>
  <title>Clappr Player</title>
  <meta charset="UTF-8">
  <!-- Player -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/dist/clappr.min.js"></script>
  <!-- DASH  -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/dist/dash-shaka-playback.min.js"></script>
</head>

<body>
  <div id="player"></div>
  <script>
    Clappr.Log.setLevel(Clappr.Log.LEVEL_DEBUG);
    var player = new Clappr.Player({
      source: "manifest.mpd",
      parentId: "#player",
      mute: true,
      autoPlay: true,
      plugins: {
       playback:[DashShakaPlayback]
     },
    });
  </script>
</body>

Information sources

https://www.ffmpeg.org/ffmpeg-all.html
http://clappr.io/


Share Tweet Send
0 Comments
Loading...