How to use time metadata in Apple HLS streams with the Wowza Streaming Cloud REST API

The Wowza Streaming CloudTM service allows you use time metadata in Apple HLS streams. For example, you can display the time stamp on a stream in a player.

The best way to include time metadata in an HLS stream is to use the ID3 ProgramDateTime (PDT) tag, which is automatically injected into chunklist at the beginning of the stream; alternatively, you can use the PDT tag that's injected into each segment, or chunk, of the stream.

Contents


About time metadata in Wowza Streaming Cloud
ProgramDateTime properties in Wowza Streaming Cloud
Example PDT property requests
Example JavaScript that uses the PDT tag
Confirm the time stamp in the stream
More resources

About time metadata in Wowza Streaming Cloud


Apple HLS supports a metadata container called ID3, which includes a ProgramDateTime (PDT) tag. The PDT tag provides an absolute date and time marker synchronized to UTC time.

Wowza Streaming Cloud, whose servers are also synchronized to UTC time, inserts the PDT tag at the beginning of every transcoded Apple HLS stream as well as at the beginning of each HTTP chunk. Because the PDT tag offers accuracy to the millisecond, the offset from the moment the tag is injected at the server to the time it's added to the stream is miniscule. And because both the server and the PDT tag are synchronized to UTC, the stream and the tag stay aligned. This makes PDT tags a better mooring for timed, synchronized events than a time stamp injected from the source encoder, such as a Presentation Time Stamp (PTS) tag in an MPEG-TS stream or a PDT tag in an FFmpeg stream, which might incur increasing drift from the encoder to the transcoder over time.

ProgramDateTime properties in Wowza Streaming Cloud


The Wowza Streaming Cloud REST API has two transcoder properties related to PDT tags: one that controls them at the stream level and one that controls them at the chunk level. Both types of PDT tag are enabled by default. A third property allows you to adjust the offset that the client uses to synchronize playback.

Note: You can't view or manage transcoder HLS properties in the Wowza Streaming Cloud web-based UI. They can only be viewed and managed with the Wowza Streaming Cloud REST API.

Section Key Type Description
cupertino cupertinoEnableProgramDateTime Boolean Controls whether an EXT-X-PROGRAM-DATE-TIME header is added to the Apple HLS stream's chunklist. The default, true, includes the header in the chunklist at the beginning of the stream as an absolute date and time tag. Specify false to omit the header from the stream chunklist.
cupertino cupertinoEnableId3ProgramDateTime Boolean Controls whether an EXT-X-PROGRAM-DATE-TIME header is added to each stream segment's ID3 tag. The default, true, includes the header in the each segment (chunk) as an absolute date and time tag. Specify false to omit the PDT header from stream segments.
cupertino cupertinoProgramDateTimeOffset Integer, positive or negative Specifies the number of milliseconds allowed from the time stamp that the client can use to synchronize playback. The default, 0, applies no offset.

Example PDT property requests


To view the status of a PDT property, you must specify the ID of the transcoder whose PDT property you want to view, and you must specify the property_id. The property_id is a string that contains the property's section and key, connected by a dash. For example, cupertino-cupertinoEnableProgramDateTime or cupertino-cupertinoEnableId3ProgramDateTime.

Notes:

  • For [key], substitute your API key or your access key as appropriate. For more information, see Locating and using API and access keys.
  • For [version], substitute the version number of the API that you're using. For the current version, use v1.

To see if cupertinoEnableProgramDateTime is enabled for transcoder ab23cd78, for example, use the command:

curl -X GET --header "wsc-api-key: [key]" --header "wsc-access-key: [key]" https://api.cloud.wowza.com/api/[version]/transcoders/ab23cd78/properties/cupertino-cupertinoEnableProgramDateTime

The response should look something like this:

{
   "property": {
      "section": "cupertino",
      "key": "cupertinoEnableProgramDateTime",
      "value": true,
      "links": []
   }
}

To see if cupertinoEnableId3ProgramDateTime is enabled for transcoder ef90gh12, for example, use the command:

curl -X GET --header "wsc-api-key: [key]" --header "wsc-access-key: [key]" https://api.cloud.wowza.com/api/[version]/transcoders/ef90gh12/properties/cupertino-cupertinoEnableId3ProgramDateTime

The response should look something like this:

{
   "property": {
      "section": "cupertino",
      "key": "cupertinoEnableId3ProgramDateTime",
      "value": true,
      "links": []
   }
}

To change a PDT property, specify the section of the transcoder configuration table that contains the property (cupertino) and the property's key-value pair.

To turn off the cupertinoEnableId3ProgramDateTime property, for example:

curl -X POST --header "Content-Type: application/json" --header "wsc-api-key: [key]" --header "wsc-access-key: [key]" -d '{
   "property": {
      "section": "cupertino",
      "key": "cupertinoEnableId3ProgramDateTime",
      "value": false
   } 
}' "https://api.cloud.wowza.com/api/[version]/transcoders/[transcoder_id]/properties"

The response should look something like this:

{
    "property": {
        "section": "cupertino",
        "key": "cupertinoEnableId3ProgramDateTime",
        "value": false,
        "links": []
    }
}

To specify an offset of for the PDT time stamp:

curl -X POST --header "Content-Type: application/json" --header "wsc-api-key: [key]" --header "wsc-access-key: [key]" -d '{
   "property": {
      "section": "cupertino",
      "key": "cupertinoProgramDateTimeOffset",
      "value": 3
   } 
}' "https://api.cloud.wowza.com/api/[version]/transcoders/[transcoder_id]/properties"

The response should look something like this:

{
   "property": {
      "section": "cupertino",
      "key": "cupertinoProgramDateTimeOffset",
      "value": 3
      "links": []
   }
}

Example JavaScript that uses the PDT tag


To use the PDT tag, write a JavaScript. One way to use it is to sync two videos in two players. The following example script uses the tag to display a time stamp on a stream in the Wowza Player:

<html>
  <head>
    <script src="//player.wowza.com/player/latest/wowzaplayer.min.js"></script>
  </head>
  <body>
    <div style="width:500px;">
      <div id="player_container" style="width:100%; height:0; padding:0 0 56.25% 0"></div>
    </div>
    <div id="timer_container" style="font-size:2em;">

    </div>
    <script type="text/javascript">
      var timerID;
      var baseURL = "<akamai_base_url>" // example: https://subdomain-i.akamaihd.net/hls/live/
      var playlistPATH = "<akamai_playlist_path>"; //example: 267789/abcd1234/my_playlist.m3u8
      myPlayer = WowzaPlayer.create('player_container',
          {
          "license":"<wowza_player_license>",
          "title":"",
          "description":"",
          "sources":[{
          							"sourceURL": baseURL+playlistPATH
          							}],
          }
      );

    function startTimer(timeString){
      var time = new Date(timeString);
      document.getElementById('timer_container').innerHTML = time.toUTCString()
      time.setSeconds(time.getSeconds() + 1);

      timerID = window.setTimeout(function(){startTimer(time.toString())}, 1000);
    }

    function parseWowzaPlaylistHLS(playlist){
      //parse the playlist and get the first chunklist
      return playlist.split(/\r?\n/)[3].split('../../')[1];
    }

    function parseWowzaChunklistForPDT(chunklist){
      //parse the chunklist and return the PDT value
      return chunklist.match(/#EXT-X-PROGRAM-DATE-TIME:[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}/)[0].replace('#EXT-X-PROGRAM-DATE-TIME:','');
    }

    function getPDT(){
      var xhr = new XMLHttpRequest();
      xhr.open( "GET", baseURL+playlistPATH); // false for synchronous request
      xhr.onload = function () {
        var firstChunklistPATH = parseWowzaPlaylistHLS(xhr.responseText);
        xhr.open( "GET", baseURL+firstChunklistPATH);
        xhr.onload = function () {
          var pdtTime = parseWowzaChunklistForPDT(xhr.responseText);
          startTimer(pdtTime);
        };
        xhr.send();
      };
      xhr.send();
    }

    myPlayer.onPlay(function(){
      getPDT();
      //resync every 10 minutes to account for drift
      setInterval(function(){
        window.clearTimeout(timerID);
        getPDT();
      },600000)
    })
    </script>
  </body>
</html>

Confirm the time stamp in the stream


To confirm that the PDT is inserted into your stream, view the stream's chunklist. You can access chunklist URLs through the stream's Apple HLS playback URL (its playlist).

  1. While the stream is running, in Wowza Streaming Cloud, navigate to the detail page of the transcoder's Apple HLS stream target.
  2. On the Setup tab, locate the  Apple HLS Playback URL, which looks something like this:

https://[subdomain]-i.akamaihd.net/hls/live/268548/437b8484/playlist.m3u8

  1. View the playlist by executing the curl command
curl -X GET [playlist url]

For example:

curl -X GET https://[subdomain]-i.akamaihd.net/hls/live/268548/437b8484/playlist.m3u8

The playlist provides an index of all of the stream's chunklists and looks something like this:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=1192957,CODECS="avc1.77.42,mp4a.40.2",RESOLUTION=1280x720
../../268548/437b8484_1_2728/chunklist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1854710,CODECS="avc1.77.40,mp4a.40.2",RESOLUTION=854x480
../../268548/437b8484_1_1728/chunklist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1236918,CODECS="avc1.77.32,mp4a.40.2",RESOLUTION=640x360
../../268548/437b8484_1_1152/chunklist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=716945,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=512x288
../../268548/437b8484_1_640/chunklist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=499531,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=320x180
../../268548/437b8484_1_448/chunklist.m3u8
  1. View one of the chunklists by executing the command
curl -X GET [chunklist url]

For example:

curl -X GET https://[subdomain]-i.akamaihd.net/hls/live/268548/437b8484_1_2728/chunklist.m3u8
  1. Look for the ID3 marker that shows the date and time that Wowza Streaming Cloud created the stream or chunk. It looks something like this:

#EXT-X-PROGRAM-DATE-TIME:2017-11-02T23:16:27Z

More resources



If you're having problems or would like to discuss this article, post in our forum.