Adding Session Data to a Playlist

In this post we’ll look at how to add session data to a playlist and then how to access it from a client application. We can use this feature to add arbitrary metadata to the playlist, such as the title of the movie, who the director was, and so on. To add session data to a playlist, we can use the EXT-X-SESSION-DATA tag.

Let’s say we have our movie and we want to add the title and the name of the director as session data to the playlist. In this example, we’ll use the computer animated film, Sintel. Let’s start by embedding the values directly in the playlist:

#EXT-X-SESSION-DATA:DATA-ID="net.hlsbook.movie.title",VALUE="Sintel"
#EXT-X-SESSION-DATA:DATA-ID="net.hlsbook.movie.director",VALUE="Colin Levy"

The DATA-ID attribute is the key and the VALUE contains, surprisingly, the value. The convention is to use reverse DNS notation for the name of the DATA-ID attribute. In this instance, we’re using net.hlsbook.movie.title to represent the title of the movie and net.hlsbook.movie.director for the name of the director. (On the client – as you’ll see shortly – we’ll use the name of the DATA-ID attribute to look up its value.)

It’s also possible to provide the URI of a file that contains the data for a given DATA-ID. The contents of the file must be valid JSON. For example, instead of embedding the values directly in the playlist, we can add them to a file (data.json) like this:

{
"title":"Sintel",
"director":"Colin Levy"
}

Then we add a tag to the playlist setting the URI attribute to the location of the JSON file like so:

#EXT-X-SESSION-DATA:DATA-ID="net.hlsbook.movie.metadata",URI="data.json"

In this instance, the JSON file is in the same directory as the playlist so the URI is relative. Also note that the EXT-X-SESSION-DATA tag must contain either a VALUE or a URI attribute, but not both. You can choose to embed some values directly in the playlist and reference a JSON file for others if you prefer.

Retrieving the Session Data on the Client

Now that we know how to add session data to a playlist, how can we access it from a client application? If you are using AVFoundation you can retrieve the session data values from the metadata property of the underlying AVAsset. Let’s look at an example. (If you’ve already bought a copy of the book, you can follow along by modifying the code of the AV Foundation client example in chapter 5.)

First, we construct the AVAsset representing our movie:

NSString *movie = @"http://hlsbook.net/wp-content/examples/sintel/sintel_index.m3u8"; 
NSURL *url = [NSURL URLWithString:movie]; 
AVAsset *asset = [AVAsset assetWithURL:url];

Next, we define the loadValuesAsynchronouslyForKeys:completionHandler: method on the asset, passing in an array containing the metadata property – this is where we will access the session data. AVAsset defers loading the properties of an asset until they are requested. Property access is synchronous, so if a property is requested but hasn’t been loaded, it will block until it is ready. For this reason, we load the metadata property asynchronously. Here’s the complete code:

[asset loadValuesAsynchronouslyForKeys:@[@"metadata"] completionHandler:^{
	for (AVMetadataItem *item in asset.metadata) {
		NSString *keyString = (NSString *)[item key];
		if ([keyString isEqualToString:@"net.hlsbook.movie.metadata"]) {
			NSDictionary *dict = (NSDictionary *)[sessionItem value];
			NSLog(@"Title: %@", [dict valueForKey:@"title"]);
			NSLog(@"Directed by: %@", [dict valueForKey:@"director"]);
		}
		else if ([keyString isEqualToString:@"net.hlsbook.movie.title"]) {
			NSLog(@"Title: %@", [item value]);
		}
		else if ([keyString isEqualToString:@"net.hlsbook.movie.director"]) {
			NSLog(@"Directed by: %@", [item value]);
		}
	}
}];

As you can see from the code, we can retrieve the session data by comparing the value of the key to the name of the corresponding DATA-ID attribute(s) in the playlist; the value is returned as a string. If the value is (valid) JSON, we get back an NSDictionary. We then use the property names (in the JSON) to look up the appropriate values from the dictionary.

Summary

We’ve seen how to add session data to a playlist, either by embedding it directly or via a JSON file, and how to retrieve the data from a client application using AV Foundation. If you want to learn more, there’s a section in the book about how to add timed metadata to an HLS video. In the example in the book, you’ll learn how to add geo-location information to a video stream and plot the location dynamically on a map. Check it out.

Leave a Reply