How to Produce CMAF Output and Testing Playback
We've been talking about the Common Media Application Format (CMAF) for so long that it seemed essential to actually produce and test some CMAF output. So that's what we're doing in this tutorial. Specifically, we'll produce CMAF output using AWS Elemental MediaConvert and test playback on a range of native players, off-the-shelf players, and browser plugins.
Why AWS Elemental MediaConvert? Beyond AWS Elemental's credibility in the marketplace, MediaConvert is a cloud-based encoder that anyone with an AWS account can access to duplicate our tests. In addition, AWS Elemental MediaConvert has a GUI that makes it ideal for a visual tutorial and an application programming interface (API) that makes it ideal for high-volume production. By this point, CMAF is sufficiently mature that you should be able to get similar results with almost any commercial encoder, cloud or otherwise.
What's to Follow
For readers who have a TL;DR disposition (and who doesn't?), let me tell you what's to follow and where. When I first started experimenting with CMAF and AWS Elemental MediaConvert, my goal was to quickly create some CMAF output to test with a variety of players, so I used a system CMAF template with no modifications. Once I found the files to be compatible with a range of existing players (as detailed later in the article), I wanted to create a custom template to produce my own encoding ladder.
Figuring that at least some readers will want to duplicate one or both of these actions, I produced the tutorial in two tracks. Track 1 creates CMAF output from an existing template—no muss, no fuss. However, since I simply used a template, Track 1 doesn't explore the CMAF-related options.
In Track 2, I created a custom Job template from scratch and explored the CMAF-related options. If this is the “money content” from your perspective, jump to the discussion by Figure 14.
Before diving into AWS Elemental MediaConvert, let's briefly touch on CMAF.
Briefly, CMAF is a standard for segmented media delivery formalized as ISO/IEC 23000-19. Specifically, CMAF uses the ISO Base Media File Format (ISO BMFF) container—with common encryption (CENC); support for H.264, HEVC, and other codecs; and Web Video Text Tracks Format (WebVTT) and IMSC1 captioning.
Unlike DASH and HTTP Live Streaming (HLS), CMAF isn't a presentation format; it's a container format that can hold one set of audio/video files, with manifest files for multiple presentation formats and multiple DRMs. To publishers distributing multiple adaptive bitrate (ABR) formats like HLS, DASH, Smooth Streaming, and Adobe HTTP Dynamic Streaming (HDS), this makes CMAF the holy grail of streaming: a single file store you can distribute to all of your output points.
Perhaps the best way to explain CMAF is to show the output, which you can see in Figure 1. From the top down, the first .m3u8 files are the HLS media playlists for the individual rungs in our encoding ladder, ending in TOS_1080p.m3u8, which is the master manifest file you would link to initiate HLS playback. The next file is TOS_1080p.mpd, the single DASH manifest file. The cmfa (CMAF audio) and cmfv (CMAF video) files are the single audio and multiple video files called for playback by both sets of manifest files. I produced the audio/video content as single files retrieved via byte-range requests in the manifest files, which is why there is only a single file for each rung and the audio file, as opposed to multiple fMP4 files for each output.
Figure 1. The object of the exercise: a single set of CMAF outputs for distribution to HLS and DASH endpoints
The outputs created in this tutorial are without DRM and advertising insertion, so they represent the simplest test case for CMAF deployment, but one that applies to the widest group of readers. For more about how useful CMAF will be in the short term to different classes of streaming publishers, check out the article titled “The State of CMAF: The Holy Grail or Just Another Format?” (go2sm.com/cmafstate).
So the files shown in Figure 1 are the object of the exercise. Let's get started.
Producing Content in AWS Elemental MediaConvert
To produce content in AWS Elemental MediaConvert, you'll need an AWS account and an Identity and Access Management (IAM) role to allow MediaConvert access to your input files and the locations where you store your output files (bit.ly/aws_iam_mc). Once you're logged into AWS, you choose MediaConvert like any other AWS service. Basic operations are controlled by the three concepts shown on top of Figure 2—Jobs, Output presets, and Job templates:
- The Jobs tab contains all jobs executed by MediaConvert. Access this tab to track job success and completion.
- Output presets contain the encoding parameters for a single output stream of audio, video, or audio/video.
- Job templates contain multiple Output presets to form the complete encoding ladder, along with relevant configurations for the ABR formats supported in the output. The simplest way to start a job is to choose an existing Job template and add the input file.
Figure 2. Producing jobs in MediaConvert involves Jobs, Output presets, and Job templates.
Note that most MediaConvert customers use the API to encode the bulk of their production jobs. Since the API can call a Job template, the optimal workflow is to create a Job template in the GUI to test compatibility and quality and then use that template in the API. So the time it takes to create the Job template will be well-spent.
Track 1: Quick Proof of Concept
The fastest way to produce CMAF output is to choose a CMAF Job template, add an input file, select an output location, enter your IAM role, and create the job. Follow these steps to get this done.
- Choose your Job template (Figure 3). Click Job templates on the left of Figure 3, then use the drop-down boxes beneath Job templates to choose System Templates and OTT-CMAF. You'll see four templates, two each for AVC and HEVC, one encoding with constantbitrate (CBR) control, the other using AWS Elemental's Quality Defined Variable Bitrate Encoding, a “content-conscious version of VBR [variable bitrate] control” you can read about at (go.aws/3a8WhcB). I first tested with the top preset, which was AVC/CBR.
Figure 3. Choosing a job template
Choose the top template for AVC and CBR. Once you select the template, you'll see the options shown atop Figure 4. Click Create job.
Figure 4. Creating a job with a system Job template
- Add your input. In the Create job screen (see Figure 5), click the Add button to the right of Inputs to create Input 1, and then select Input 1. On the right, below Input 1, click Browse to open your AWS Simple Storage Service (S3) buckets.
Figure 5. Choosing the input file
After clicking Browse, MediaConvert opens the Choose a location window shown in Figure 6 on the next page. Use the S3 bucket drop-down list to select an S3 bucket. If you click your pointer in the search file input field, MediaConvert will list all files in the bucket. It's easiest to type in the first few letters of the file you're seeking. In Figure 6, you'll see that I typed capital T to reveal the four files shown in the list. Click to select the desired input file.
Figure 6. Choosing the input bucket and location
- Choose your output location. In the middle left of Figure 5, click CMAF to open the CMAF group settings shown in Figure 7. Click Browse, and choose a location for the CMAF output.
- Choose your IAM role. On the bottom left of the Create job screen (Figure 5), click Settings to reveal the Job settings menu shown in Figure 8 (on page 94). In the IAM role drop-down list, choose MediaConvert.
- Create the job. On the bottom right of the Create job screen, click Create (not shown in Figure 5). If
everything is correct, the screen will close and MediaConvert will add the job to the Jobs list. If not, MediaConvert is very specific about errors and will let you know what you did wrong and how to fix it.
Figure 7. Choosing an output location
Figure 8. Choosing the IAM role
Use a short test file, and MediaConvert will be done before you know it. Using your S3 explorer of choice, make all the files public in the folder so the player can play them, and click one of the main manifest files in the S3 Explorer in your browser (see Figure 9). Note that AWS provides an HTTPS URL so you can test with players that require HTTPS input like the Bitmovin web test player. Also note that if you retrieve the URL in a third-party explorer utility like CloudBerry, which I did initially, you'll get an HTTP URL that you can't test with test players that require HTTPS.
Figure 9. Here’s the HTTPS URL from the browser-based S3 Explorer.
Figure 10 shows the HLS stream playing in the JW Player test player, where the Music Player Daemon (MPD) also played. The only hiccup was that if you want to play the video from an S3 bucket, you have to set your cross-origin resource sharing (CORS) configuration, which is described at go2sm.com/cors. After getting this done, the CMAF files played successfully in the Bitmovin player (HLS and DASH), natively on my iPhone 10 (HLS), in Microsoft Edge (HLS), and in Chrome using the Native MPEG-Dash + HLS Playback plug-in (HLS and DASH), all without any adjustments whatsoever. The only player that didn't work was the THEOplayer, although AWS Elemental was in discussions with THEO Technologies about this, and I'm sure the issue will be resolved long before you read this article.
Figure 10. The HLS output in the CMAF package playing in the JW Player test player
Track 2: Creating Your Own Custom CMAF Job Template
Time and space dictate that we keep this next section short and sweet. At a high level, making your own CMAF Job template involves four steps:
- Creating your presets.The easiest way to create a custom preset is to choose an existing Output presetthat's close to the desired output parameters and modify that. For example, I wanted to change from CBR encoding to VBR encoding. So I found a CBR template close to my target output parameters and changed that to VBR. Once I had that preset customized as needed, I duplicated it, changed the parameters as required for the next rung on the ladder, and then rinsed and repeated until I completed all video rungs (I used an existing MediaConvert audio template). Note that if you're creating presets for use in a CMAF Job template, you should create video-only and audio-only templates, since CMAF only works with demuxed audio and video.
To browse through MediaConvert's Output presets, click Output presets and choose System Presets and OTT-CMAF presets in the Output presets menu (looks like Figure 3 but for Output presets). You can differentiate the presets based on their names or descriptions. Click the desired Output preset to load it, and then click Duplicate to create your custom version. In Figure 11, I had selected the 8Mbps 1080p CBR CMAF preset and converted it to 6Mbps VBR, leaving all other settings untouched.
Figure 11. Converting a CBR preset to VBR
Once I produced the initial preset, I duplicated it and created the next rung on the ladder. I used a 96Kbps audio preset as is for my custom Job template.
- Create the custom Job template.Click Job templates to open that tab, and then click Create template. This opens the screen shown in Figure 12. Enter the General information shown on the right of the figure so you can find the template later.
Figure 12. Creating the custom CMAF template
In the middle left of Figure 12, click Add to the right of the Output groups. This opens the Add output group selector (see Figure 13). Choose CMAF and then Select. You've created your CMAF Job template.
Figure 13. Creating the CMAF output group
- Configure your CMAF options.Once you create the CMAF output group, MediaConvert will open to the CMAF options screen shown in Figure 14.
Figure 14. Configuring the CMAF options
The options are as follows:
- Segment control—If you choose Single file, you'll output a single file for each audio/video output that the manifest files will access via byte-range requests. If you choose segmented files, you'll produce individual files for each segment that the manifests will retrieve as such.
- Fragment length—DASH players can switch streams on a fragment boundary, rather than waiting for the end of a segment. This option sets fragment duration, which should be the same duration as your I-frame interval or a multiple thereof.
- Segment length—This is the duration of the traditional segment for HLS and DASH, which should be the same duration or a multiple of the I-frame interval used to produce the files (I used a GOP size of 2 seconds).
- Minimum final segment length—Use 0 unless debugging a player issue.
- Write HLS manifest—Enable if using MediaConvert to produce your HLS manifest files.
- Write DASH manifest—Enable if using MediaConvert to produce your DASH manifest files.
- MPD manifest profile—Use Main unless your DASH player needs on demand.
Click Advanced for advanced HLS and DASH encoding options that are beyond the scope of this tutorial.
- Add custom presets tothe template, and save the template.With CMAF still selected on the left of Figure 14, scroll down until you see a list of all Outputs (Figure 15). On the upper right, click Add output until you have sufficient outputs for all video and audio Output presets.
Figure 15. Adding outputs to the Job template
On the left of Figure 14 below CMAF, all Outputs should be listed. Click each Output to open the Output settings dialog (see Figure 16), and then choose a preset from the drop-down list and type a name modifier, which you'll typically want to start with an underscore. The custom presets are the ones that you created in Step 1 of Track 2. The Name modifier is the text that MediaConvert will append to your source file during encoding to differentiate the content in the manifest files.
Figure 16. Choosing your preset and Name modifier
Repeat this task for all rungs in your encoding ladder, and click Create on the bottom right (shown in Figure 12) to produce the preset.
Once created, you can access the new preset in the Job templates tab (Figure 17) with Custom Templates selected and run the job as described in Track 1.
Figure 17. Here’s the new Job template available for production.