Highwinds SMIL Guide

Highwinds is a fast CDN that offers a wide range of solutions, including adaptive streaming of video. To make using Highwinds adaptive streaming integration easier we have added a method to generate SMIL files.

Overview

SMIL files are XML documents in a special format which are used for describing multimedia presentations. Highwinds uses a subset of SMIL to enable adaptive streaming.

SMIL and Zencoder

The following is an example of a Highwinds SMIL file which describes a video that has been encoded to multiple bitrates. All paths ("src") given are relative to where the SMIL will be served and all bitrates ("system-bitrate") are in bits per second (bps).


<smil>
<head>
</head>
<body>
<switch>
<video src="mp4:rel/path/file-440k.mp4"
system-bitrate="440000" width="720" height="406" />
<video src="mp4:rel/path/file-640k.mp4"
system-bitrate="640000" width="854" height="480" />
<video src="mp4:rel/path/file-240k.mp4"
system-bitrate="240000" width="640" height="360" />
<video src="mp4:rel/path/file-150k.mp4"
system-bitrate="150000" width="320" height="180" />
<video src="mp4:rel/path/file-64k.mp4"
system-bitrate="64000"/>
</switch>
</body>
</smil>

Each <video> tag in the above example represents a separate stream that can be served to the user. The first video listed will be streamed to the user until the available bandwidth can be determined, at which time the user will be switched to the appropriate stream.

Creating a Highwinds SMIL playlist with Zencoder is easy.


{
    "api_key": "asdf1234",
    "input": "s3://my-bucket/input/file.mov",
    "outputs": [
    {
        "type": "playlist",
        "format": "highwinds",
        "url": "s3://my-bucket/output/file.smil",
        "streams": [
        {
            "path": "rel/path/file-440k.mp4",
            "bandwidth": "440",
            "width": 720,
            "height": 406
        },
        {
            "path": "rel/path/file-640k.mp4",
            "bandwidth": "640",
            "width": 854,
            "height": 480
        },
        {
            "path": "rel/path/file-240k.mp4",
            "bandwidth": "240",
            "width": 640,
            "height": 360
        },
        {
            "path": "rel/path/file-150k.mp4",
            "bandwidth": "150",
            "width": 320,
            "height": 180
        },
        {
            "path": "rel/path/file-64k.mp4",
            "bandwidth": "64"
        }
        ]
    }
    ]
}

When you do this, you will need to include a non-playlist output as well.

  • "type" should be "playlist"
  • "format" should be "highwinds"
  • "url" (or "filename") should have an extension of "smil"
  • "streams" should be an array of JSON objects which each have the keys "bandwidth" and "path"
    • "path" should be the relative path to the mp4 file as it will be served by your server (notice that it doesn't include the leading "mp4:" that appears in the SMIL file)
    • "bandwidth" should be the bitrate of the file in kbps which we will convert to bps when creating the SMIL file
    • "width" is optional and should specify the horizontal resolution of the file
    • "height" is optional and should specify the vertical resolution of the file

The videos referenced by the playlist can be created separately from the job that generates the playlist, or they can be created as additional outputs on the same job.

The Whole Picture

Multiple outputs of different bitrates may be specified and referenced by the playlist.

{
    "api_key": "1234abcd",
    "input": "http://example.com/file.mp4",
    "output": [
    {
        "audio_bitrate": 56,
        "audio_sample_rate": 22050,
        "base_url": "s3://my-bucket/",
        "filename": "file-64k.mp4",
        "format": "aac",
        "public": 1
    },
    {
        "audio_bitrate": 56,
        "audio_sample_rate": 22050,
        "base_url": "s3://my-bucket/",
        "decoder_bitrate_cap": 165,
        "decoder_buffer_size": 440,
        "filename": "file-150k.mp4",
        "max_frame_rate": 10,
        "public": 1,
        "video_bitrate": 110,
        "width": 320
    },
    {
        "audio_bitrate": 56,
        "audio_sample_rate": 22050,
        "base_url": "s3://my-bucket/",
        "decoder_bitrate_cap": 300,
        "decoder_buffer_size": 800,
        "filename": "file-240k.mp4",
        "max_frame_rate": 15,
        "public": 1,
        "video_bitrate": 200,
        "width": 640
    },
    {
        "audio_bitrate": 56,
        "audio_sample_rate": 22050,
        "base_url": "s3://my-bucket/",
        "decoder_bitrate_cap": 600,
        "decoder_buffer_size": 1600,
        "filename": "file-440k.mp4",
        "max_frame_rate": 30,
        "public": 1,
        "video_bitrate": 400,
        "width": 720
    },
    {
        "audio_bitrate": 56,
        "audio_sample_rate": 22050,
        "base_url": "s3://my-bucket/",
        "decoder_bitrate_cap": 900,
        "decoder_buffer_size": 2400,
        "filename": "file-640k.mp4",
        "max_frame_rate": 30,
        "public": 1,
        "video_bitrate": 600,
        "width": 854
    },
    {
        "type": "playlist",
        "format": "highwinds",
        "url": "s3://my-bucket/file.smil",
        "streams": [
        {
            "path": "file-440k.mp4",
            "bandwidth": "440",
            "width": 720,
            "height": 406
        },
        {
            "path": "file-640k.mp4",
            "bandwidth": "640",
            "width": 854,
            "height": 480
        },
        {
            "path": "file-240k.mp4",
            "bandwidth": "240",
            "width": 640,
            "height": 360
        },
        {
            "path": "file-150k.mp4",
            "bandwidth": "150",
            "width": 320,
            "height": 180
        },
        {
            "path": "file-64k.mp4",
            "bandwidth": "64"
        }
        ]
    }
    ]
}

NOTES

  • The playlist generation currently uses no information from the other outputs in the job, but is simply a way to easily generate a correctly formatted adaptive-bitrate playlist and have it uploaded along with the other files.
  • decoder_bitrate_cap is set to 1.5x the target bitrate of the file. decoder_buffer_size is set to 3.5x to 5x the target bitrate of the file. These settings will help keep a consistent bitrate throughout the file, so that the segmented segments won't vary too much in size and bitrate.