How to Package MPEG-DASH using Bento4’s mp4dash

In this article from the MPEG-DASH series, we take a look at how to create MPEG-DASH compliant streams (package) using the popular Bento4 (mp4dash) tool. Follow this step-by-step tutorial to take a set of video renditions and create DASH-compliant streams.

MPEG-DASH is one of the most popular video-streaming protocols and is widely used to deliver media via Video on Demand (VOD) or Live Streaming to various end-user devices, including smartphones, tablets, SmartTVs, gaming consoles, and more.

Fundamental to the MPEG-DASH protocol is the manifest or MPD (Media Presentation Description) created when the media is packaged and prepared for transmission via DASH.

DASH packaging using Bento4 and mp4dash

In this edition of the Hitchhiker’s Guide to MPEG-DASH, we dig into the Bento4 MPEG DASH tools.

Bento4 is a versatile toolkit that can package and encrypt videos for transmission using the MPEG-DASH protocol. Bento4 is available as both free, GPLv2 open-source and under a paid commercial license, and very easy to use – as we’ll see in this tutorial. 

So, let’s get packaging!

Bento4 Toolkit Licensing

The Bento4 toolkit developer licenses it under the GPLv2 license. A non-GPL commercial license is available from Axiomatic Systems LLC. Contact Gilles Boccon-Gibod ([email protected]) or [email protected] for more information.

Supported Platforms

Bento4 is available with pre-compiled binaries for Windows 10, macOSX, and Linux x86_64.

Getting the Bento4 toolkit

There are two ways to get hold of the Bento4 toolkit –

  1. Go to Bento4’s GitHub page and download the latest release.
  2. Or, go to the Bento4 website’s downloads page to download binaries for Windows 10, macOSX, and Linux.

After you download and install it on your system, you are ready to package your videos into the MPEG-DASH protocol. Let’s learn how in the following sections.

You’ll notice that the download has a lot of binaries – each performing a useful function in the video inspection and packaging process.

bent4 mp4dash

There are several of these that we will be using specifically for DASH packaging

Preparing a DASH Video

Step 0: Content Preparation

The packager doesn’t change the actual content encoding, just the file packaging format. You need to encode the content for streaming before you get to the actual packaging. Encoding a video for streaming is a whole subject on its own, but here are the key things to remember.

  • Codecs: HEVC is the most efficient video codec currently in use, but it is not as widely supported as H264. MPEG DASH allows you to encode the video using both codecs, each in its own Adaptation Set.
  • Bitrates/Resolutions: Adaptive Bitrate (ABR) streaming lets you encode the video in a range of bitrates and resolutions, allowing for uninterrupted viewing under a wide range of network bandwidths.
  • GOP Length: MPEG DASH requires all of the Representations in an Adaptation Set to have the same GOP length. Consistent GOP lengths allow the media player to switch representations from one segment to the next. Each segment will contain one or more GOPs. For example, if the GOP length is 2 seconds, you can package the content with segments that are 2 seconds, 4 seconds, 6 seconds, etc. Note: If you don’t know what Adaptation Sets / Segments are, then read this article that explains the basics of a MPEG-DASH MPD file.

For the following example, we will be using a video encoded in four different resolutions:

  • myvideo_1920x1080.mp4
  • myvideo_1280x720.mp4
  • myvideo_640x360.mp4
  • myvideo_320x180.mp4

Step 1: Fragmenting the Video

The first step in using Bento4 is to ensure that the video is fragmented and uses the fragmented mp4 (fmp4) file format. Bento4 provides a command-line tool called mp4info that can inspect your videos and tell you if it is fragmented or not.

Run mp4info as follows:

$ mp4info myvideo_1920x1080.mp4

As you can see, mp4info shows a lot of information about the video. At his point we are interested in whether or not the video is fragments. As the 12th line of the report shows our video isn’t fragmented, so we will need to use the mp4fragment tool to fragment it.

File:
  major brand:      isom
  minor version:    200
  compatible brand: isom
  compatible brand: iso2
  compatible brand: avc1
  compatible brand: mp41
  fast start:       no

Movie:
  duration:   339244 ms
  time scale: 1000
  fragments:  no

Found 2 Tracks
Track 1:
  flags:        3 ENABLED IN-MOVIE
  id:           1
  type:         Video
  duration: 339240 ms
  language: und
...
...
...

When you are fragmenting the video you have the opportunity to set the segment duration using the --fragment-duration parameter. The value is in mS, so to get 4-second segments, you need to use the value 4000.

I like to append _frag to the end of the file names to note that they are fragmented.

Related:  OTT Content Consumption Patterns Pre and Post-COVID

Run mp4fragment for each of the resolutions as follows to get fragmented videos.

$ mp4fragment --fragment-duration 4000 myvideo_1920x1080.mp4 myvideo_1920x1080_frag.mp4
$ mp4fragment --fragment-duration 4000 myvideo_1280x720.mp4 myvideo_1280x720_frag.mp4
$ mp4fragment --fragment-duration 4000 myvideo_720x360.mp4 myvideo_720x360_frag.mp4
$ mp4fragment --fragment-duration 4000 myvideo_360x180.mp4 myvideo_360x180_frag.mp4

Now, we can use mp4info to confirm that the video is fragmented.

$ mp4info myvideo_1920x1080_frag.mp4

File:
  major brand:      isom
  minor version:    200
  compatible brand: isom
  compatible brand: iso2
  compatible brand: avc1
  compatible brand: mp41
  compatible brand: iso5
  fast start:       yes

Movie:
  duration:   339244 ms
  time scale: 1000
  fragments:  yes

Step 2: Packaging the Video

Now that you have completed fragmenting your videos, it is time to package them into MPEG-DASH. As you probably know, after you package a video, you are left with a MPEG-DASH manifest (.mpd) file that describes how the video is segmented, the different profiles that are available to stream, which order the segments are to be delivered, and so on.

Using mp4dash, it is trivial to package your videos into MPEG-DASH. 

The --mpd-name parameter lets you specify the name of the DASH MPD file.

Here’s how –

$ mp4dash --mpd-name myvideo.mpd myvideo_1920x1080_frag.mp4 myvideo_1280x720_frag.mp4 myvideo_640x360_frag.mp4 myvideo_320x180_frag.mp4

The packager will create an output directory containing the MPD file and subdirectories for the audio and video segments. 

xcnxiAFJ9Ip7UykfbUnTWciMlIEzKbhGqYKUNxAEQO63VkPjNKA2ykCUehWvl7eOwVHiFXTwTwY8laceo5BQketONE3dFWWKC

Here is the resulting DASH MPD file myvideo.mpd.

<?xml version="1.0" ?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT4.00S" mediaPresentationDuration="PT5M39.240S" type="static">
  <!-- Created with Bento4 mp4-dash.py, VERSION=2.0.0-637 -->
  <Period>
    <!-- Video -->
    <AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" maxWidth="1920" maxHeight="1080">
      <SegmentTemplate timescale="1000" duration="4000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
      <Representation id="video/avc1/1" codecs="avc1.64002A" width="1920" height="1080" scanType="progressive" frameRate="50" bandwidth="3975652"/>
      <Representation id="video/avc1/2" codecs="avc1.640020" width="1280" height="720" scanType="progressive" frameRate="50" bandwidth="2313670"/>
      <Representation id="video/avc1/3" codecs="avc1.64001F" width="640" height="360" scanType="progressive" frameRate="50" bandwidth="645330"/>
      <Representation id="video/avc1/4" codecs="avc1.640015" width="320" height="180" scanType="progressive" frameRate="50" bandwidth="188018"/>
    </AdaptationSet>
    <!-- Audio -->
    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true">
      <SegmentTemplate timescale="1000" duration="4000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
      <Representation id="audio/und/mp4a" codecs="mp4a.40.2" bandwidth="132388" audioSamplingRate="44100">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

Let’s take a closer look at the MPD entries and verify that it matches what we wanted.

When we fragmented the videos we told it to use 4000 msec fragments. This is shown near the top of the MPD with the entry minBufferTime="PT4.00S".

The MPD contains one video Adaptation Set that matches our original video files.

<AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" maxWidth="1920" maxHeight="1080">

The Adaptation Set uses a Segment Template so that it doesn’t need to list all of the individual segments for each representation. The Segment Template is at the Segment Template level, so a single template will apply to all of the representations. Each segment has a duration of 4000 msec. Each Representation has an initialization segment, and the segments are numbered starting with 1.

<SegmentTemplate timescale="1000" duration="4000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>

The first representation has an ID of  that matches the directory structure.

<Representation id="video/avc1/1" codecs="avc1.64002A" width="1920" height="1080" scanType="progressive" frameRate="50" bandwidth="3975652"/>

We can combine the Representation and Segment Template information to predict what the file names will be. We should expect to find an initialization segment named video/avc1/1/init.mp4 and the first segment should be named video/avc1/1/seg-1.m4s.  Sure enough, if we dig down into the files we find them exactly where we expect. Since each segment file is only 4 seconds long, there can be a lot of them.

3rdhMgjLgTjYsQ9g vRP1egYy8DGMXLkx5C6Wb UWThGSd2dFOAk4SPQSEee3k7JOtn58mSzPlxflFe0p MMSqjvUaZNCLU0bOzmbdf9IJm4 iUvRCWOIndJZG J KFAiebhKTkp

Step 3: Publishing the video

Now that we have the video packaged the final step is to put it onto a web server for streaming.  Copy the entire contents of the output directory to your web server, and make sure to set the MIME TYPE of .mpd files to application/dash+xml so that the web browser will know to send it to the DASH player.

Go here for a list of DASH-compliant players that you can use for free testing online.

Conclusion

Thanks for reading this tutorial on MPEG-DASH packaging using Bento4 mp4dash. I hope this helped you create DASH-compliant bitstreams and you were able to successfully stream your content to a DASH-compliant player.

If you are eager to learn MPEG-DASH, then these articles will interest you for sure!

Until next time, stay safe, and happy streaming!

Ron Garrison
Ron Garrison

Ron has lead streaming optimization Product Management teams at companies including Ortiva Wireless, Allot Communications, and MediaMelon.

Be the first to comment

Leave a Reply

Your email address will not be published.


*