HDS & Bootstrap Data


Working with HDS Bootstrap Data

I’ve always been curious about the bootstrap data for HDS content. Recently, I had the chance to find out more about it and get in some fun development with Node.js. We’ve been kicking around the idea of building a tool set for Adobe Media Server using Node.js and possibly socket.io. Last weekend we got some of the ideas going and one of those was parsing the hds bootstrap data created when content is packages for HDS delivery.

The bootstrap data can live in a couple of places:

  1. In the <metadata> node of an F4M file
  2. In an external .bootstrap file

The .bootstap file contains binary data and the F4M file contains the same binary data that has been Base64 encoded. So, getting to the data is pretty trivial – either read in the .bootstrap file or un-encode the string in that is in the F4M. Getting to the data contained in the bootstrap binary data is the fun part.

Understanding the bootstrap data

To do so, check out the F4V file format specification. This PDF gives you the details for the entire F4V file format. If you read through the PDF, you’ll  see that it is built using what are called “boxes”. These boxes are given identifiers such as “abst”,  “adaf”,  “adkm”,  “aeib”,  “afra”,  & “afrt” to name a few. Each box contains a header, that header identifies the box by its identifier and lets you know how much data is contained in the box. These boxes are also arranged into a hierarchy, so each box has some data that is specific to some part of the data contained in the file.

It is all in the boxes

The boxes that we are concerned with are “abst” or the bootstrap information box, “asrt” or the segement run table box, and “afrt” or the fragment run table box.

The abst box

The bootstrap information box contains information needed to bootstrap playing of HDS content – specifically to construct the URLs necessary to retrieve the fragments for playback. This includes information about the server, media, & segment information.

The asrt box

The segment run table box contains data about the segments for the media item. There can be multiple ASRT boxes – each representing a different quality level. There are some rules that you’ll want to pay attention to for the data in the asrt box:

  • An asrt box can represent fragment runs for several quality levels.
  • Each entry gives the first segment number for a run of segments with the same count of fragments.
    • The count of segments having this same count of fragments can be calculated by subtracting the first segment number in this entry from the first segment number in the next entry.

The afrt box

The fragment run table box is used to find the fragment corresponding to a given time. Similar to the asrt box, there are some rules that you’ll want to pay attention to:

  • Fragments are individually identifiable by the URL scheme based on segment number and fragments number.
  • Fragments may vary both in duration and in number of samples.
  • Duration of the fragments are stored in the this box.
  • A Fragment Run Table may represent fragments for more than one quality level.
  • Each fragment run table entry gives the first fragment number for a run of fragments with the same duration.
    • The count of fragments having this same duration can be calculated by subtracting the first fragment number in this entry from the first fragment number in the next entry.

Parsing the bootstrap data using Node.js

Parsing binary data in Node.js can be done using “Buffer”. For the most part parsing the bootstrap data was pretty straight forward. There is one issue that I ran into with 64bit Integers which was solved easily enough (there are node modules for just about anything) using the node-int64 module to represent the 64Bit Integers. Once that was solved it was just a matter of parsing through the box header to figure out where you are in the dataset, and then creating the appropriate data structures to represent what you want and need in from the bootstrap data.

In our case we want to be able to monitor live events across multiple servers to make sure that they are all on the same segment and fragment. We’re building a services that in the case that something happens to a server and it goes haywire, will notify another service that can then restart or shut down that particular server or let caching servers know that they need to flush or refresh cache. We’re still dreaming up things we can use this type of data for.

Just want to get to that data?

If you have a .bootstrap file you can use the f4fpackager.exe that is part of the Adobe Media Server toolset to inspect the bootstrap data. All you need to do is run the tool with the argument “–inspect-bootstrap”. So the command looks something like the following if you have a bootstrap file named mydata.bootstrap:

[shell].f4fpackager.exe –input-file=mydata.bootstrap –inspect-bootstrap[/shell]

Anyways, if you have any questions or input let me know in the comments.

Getting Started with HTTP Dynamic Streaming

As described in the first post in this series: What is Dynamic Streaming?, HTTP Dynamic Streaming (HDS) allows for the delivery of streaming content over the HTTP protocol. Streaming video over HTTP requires some knowledge and preparation. The following is a rundown and description for each of the components involved with HTTP streaming.

The files: The F4F and F4M file formats

The F4F file format specification (http://www.adobe.com/devnet/f4v.html) describes how to divide media content into segments and fragments. These segments and fragments are what make ‘streaming’ content over HTTP possible. Basically, the file is broken up into multiple pieces and parts when it is prepared for for HTTP streaming.

A sample segment and its fragments
A sample segment and its fragments

These way the segments and each segments fragments are created is based on multiple factors such as the length of the video content, the the number of keyframes and the length specified for each segment. The result of packaging your video content for HDS delivery is a set of files that look similar to the following for a simple, single bit-rate file:

HTTP Dynamic Streaming Packaged Files for a short video file
The set of files created by the f4fpackager for a short video clip.

From the image above:

  • sample.f4m: This is an XML file created by the f4fpackager that contains the information necessary for a client player to playback the video file. There will be only one of these for each source video file.
  • sampleSeg1.f4f: This segment file contains the fragments that the client player will request for playback. There can be multiple of these files for each source video file.
  • sampleSeg1.f4x: This is an index file that contains specific information about the fragments inside the segment files. There will be one of these types of files for each segment file. The HTTP Origin Module uses the data in this file to determine the fragment to send back to the client after a request.

Each F4F file is a single segment and the segment can contain multiple fragments. So, if you inspect the HTTP requests as a media item is being played back you will see files being requested that map to a fragment within a segment. For example:

Segments and fragments being requested over HTTP
Segments and fragments being requested for HDS video

This request specifies to the HTTP Origin Module what segment’s fragment to pull out of the F4F file and deliver to the client for playback. These requests are based on where the time code of where the media item is during playback. So if you scrub to later in the video, the Requests might look something like the following:

Scrubbing HTTP Dynamic Streaming Video Content
Segments and fragment requests while scrubbing HDS video content

This allows the client to request any piece of the video content and start playing back almost immediately. You can control how the files are segmented and fragmented when preparing content with the f4fpackager. The basic concept is to balance the size of the fragment being delivered and the number of HTTP requests that a client needs to make for playback. Please note, the fragments may not be sequential, so you cannot rely on this when requesting content. The the fragments are based on the settings passed into the packager and can skip fragment numbers. So , you can expect to see fragment sequences like the following (no scrubbing involved):

  1. sampleSeg1-Frag1
  2. sampleSeg1-Frag2
  3. sampleSeg1-Frag3
  4. sampleSeg1-Frag5
  5. sampleSeg1-Frag6

This doesn’t mean that the file is incomplete, it is just how the fragments were created by the packager.

The Details

The F4M File Format

The F4M or Flash Media Manifest file format contains the information about the package of files created when video content is packaged for HDS. The information included in the manifest file can include some or all of the following:

  • Media location
  • Media type
  • Media bootstrap
  • Multi-bitrate (MBR) availability
  • Codecs
  • Resolutions
  • Digital Rights Management (DRM) authentication
  • DVR information
  • moov atom, metadata block and XMP metadata block

When playing back HDS video content, the F4M file is expected to be loaded as the ‘media file’. The client is responsible for inspecting the data included in the F4M file to authenticate (if DRM authentication is required), determine if MBR content is available and select the best MBR version of the content and then request the media from the server.

Sample of a simple F4M file with a single media item:

Installing and configuring the Apache HTTP Origin Module: http://help.adobe.com/en_US/HTTPStreaming/1.0/Using/WS7b362c044b7dd076-735e76121260080a90e-8000.html