PlayReady 2.x Premium and IIS Media Services 5.0 Premium have enabled the following four key features which are needed for scalable live TV service:
The author and his colleagues have written the following documents to cover the first three features:
The purpose of this blog is to cover network DVR feature. These documents provide a thorough coverage of the how-to aspects of these important live TV features in IIS Media Services Premium and PlayReady Server SDK Premium.
Network DVR (NDVR), Network Personal Video Recorder (NPVR), or Remote Storage DVR (RS-DVR) refers to a DVR feature with DVR content stored on TV service providers’ servers rather than at users’ homes.
Understanding NDVR feature involves understanding the following archives and quantities:
The following table summarizes the relationship among the two types of NDVR, archive, DVR content storage, DVR window length, manifest window length and segment length.
NDVR Type
Archive
DVR Content Storage
DVR Window
Client Manifest
Continuous NDVR
Archive must be enabled:
DVR content shares with archive.
Physical storage is used (Default location: C:\inetpub\media\archives\)
Due to Segmented manifest, small manifest regardless of the DVR window length.
Session NDVR
If archive is disabled:
DVR content is in memory.
Memory size depends on DVRWindowLength, bitrates & buffer overhead. E.g. 5 min can mean 350MB w3wp memory for 5 bitrates.
= Fragment TTL
= Manifest Window Length;
A very large DVR window can result in a very large client manifest, which can impact startup and channel switch times.
If archive is enabled:
Both under date folder.
IIS Media Services v5 Premium provides GUI for network DVR configuration as shown below:
In addition, client manifest window length can also be configured in the management GUI (in multiple of segment length), as shown below.
The corresponding network DVR configuration in the live channel configuration file is shown below:
<Archive enabled="true" continuousNetworkDVR="true" autoDelete="false">
<SegmentLength>PT2M0S</SegmentLength>
<Path credentials="" useEventIdOnPath="false" />
</Archive>
where
The URL format for accessing the client manifest of a segment ishttp://server/channel.isml/Segments({segmentStartTime})/manifest . For example, the following URL’s are for 8 corresponding consecutive segments of archive/DVR content with segment length being 2 minutes:
Note: In the above URL’s, if we add left-padding like in 0007200000000, it does not work. This is by design: if left-padded URL also works, CDN needs to have multiple entries for each segment, which is not optimal.
Now how can I start from a point in the middle of a segment?
The actual URL for a fragment is as below:
http://localhost/LiveSmoothStreaming/LiveSmoothStreamingScalableLicense.isml/Segments(1200000000)/QualityLevels(2962000)/Fragments(video-101=2360000000)
http://localhost/LiveSmoothStreaming/LiveSmoothStreamingScalableLicense.isml/Segments(1200000000)/QualityLevels(160000)/Fragments(audio=2360076190)
The following code segment illustrates how the archived segments are retrieved and how their URL’s are constructured:
protected DataTable CreateDataTable()
{
DataTable objDataTable = new DataTable("NDVR");
objDataTable.Columns.Add(new DataColumn("Original Air Time", typeof(string)));
objDataTable.Columns.Add(new DataColumn("1st Fragment Timestamp", typeof(long)));
objDataTable.Columns.Add(new DataColumn("URL", typeof(string)));
string dvrFolder = System.Configuration.ConfigurationManager.AppSettings["nDVR"];
string[] segmentFolders = Directory.EnumerateDirectories(dvrFolder).ToArray<string>();
string channelUrl = ddlChannel.SelectedItem.Value;
int index;
DateTime dateTime;
DataRow objDataRow;
foreach (string folder in segmentFolders)
index = folder.IndexOf(@"\Segment") + 8;
dateTime = this.Timestamp2DateTime(folder.Substring(index));
objDataRow = objDataTable.NewRow();
objDataRow[0] = string.Format("{0}", dateTime.ToString("MM-dd-yyyy HH:mm:ss"));
objDataRow[1] = long.Parse(folder.Substring(index));
objDataRow[2] = string.Format("SmoothStreamingPlayerTestPage.aspx?MediaSource={0}/Segments({1})/manifest", channelUrl, long.Parse(folder.Substring(index)).ToString());
objDataTable.Rows.Add(objDataRow);
}
return objDataTable;
How does a playback navigate across multiple archive segments? The “magic” is in IIS Media Services 5 (yes, server side instead of client side) which knows how to navigate across segments to expose a single timeline.
There is a separate tool called IIS Media Services Archive Stitching Tool (available to MCT licensees only). The "stitching" tool can be used to combine segments from live archives into a single consolidated Smooth Streaming file. The tool allows you to point at an existing live archive folder, set the start time and end time, and output a new directory of stitched .ismv, and manifest files for use in on-demand or encoding scenarios.
If original live TV broadcast is PlayReady protected with scalable licenses, the segmented presentation archive (NDVR content) is also PlayReady protected with the leaf content keys used when the original live TV smooth streaming occurs. The client manifest for each segment contains Protection Header which, unlike regular VOD client manifest, does not contain license acquisition URL (LAURL) because this is scalable license scenario. The protection header content is shown below.
ǮǤ<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.1.0.0"><DATA><CUSTOMATTRIBUTES><IIS_DRM_VERSION>7.1.1654.5</IIS_DRM_VERSION></CUSTOMATTRIBUTES><DECRYPTORSETUP>ONDEMAND</DECRYPTORSETUP></DATA></WRMHEADER>
The following diagram shows the DRM portion of a MCT lab:
Since the corresponding root licenses are required for decrypting the leaf content keys in segmented archive, all the needed root licenses must be present in client hashed data store. This implies we must keep all the needed root licenses on clients for the desired window of DVR support. If you set MediaLicense.RemovalDate property in your root license server, a proper value needs to be given so that those root licenses needed for DVR content are not removed from client secure hashed data store.
Let’s consider a hypothetical example: suppose root license rotates weekly during weekend and we need to make four weeks of NDVR contents available to subscribers. Suppose it is Monday today. Then a client needs to keep not only the root license for the current week, but also the four root licenses, one for each of the past four weeks, in order for subscribers to view not only the current live content and NDVR content for this week but also all NDVR contents for last four weeks.
If the original live TV content is protected by leaf licenses, the following facts hold true:
In order to create a publishing point to serve archived content as VOD, all we have to do is to create a copy of the live channel but without live stream ingest.
When playing each segment, the segment length is identical to VOD DVR window length (2 minutes in this example). The two screenshots below show two consecutive segments during playback.
If you restart the live channel, the DVR content both before and after the restart will still be available.
The folder names are in the format of “Segment{timestamp}”, with time stamp increasing in the multiple of DVR segment length, which in this particular case, 2 minutes, or 120 seconds (1200000000 unit: 100 nanoseconds). This naming convention insures that archive folders are identical across multiple origin servers for a live channel as long as the particular channels on all servers use the same segment length.
To ensure that each timestamp in folder names increases continuously, the input source must ensure that there is a continuously increasing timestamp on audio/video packets. Currently, only the Multicast - MPEG-2 TS source module in IIS Media Services v 5 Premium supports this behavior.
If you use TSMulticast tool to generate MPEG-2 TS stream using a set of multi-bitrate content, the tool will generate a time stamp consistent with machine time. For example, if TSMulticast generates a time stamp at UTC time 12-23-2012 01:18:00:00000, the time stamp will be 7250734800000000 and the resulting segment folder name will be Segment7250734800000000.
The conversion from timestamp to UTC time is through the following code:
protected DateTime Timestamp2DateTime(string timestamp)
double seconds = long.Parse(timestamp) / 10000000;
DateTime start = new DateTime(1990, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return start.AddSeconds(seconds);
In this blog we have covered the following aspects of continuous Network DVR feature in IIS Media Services 5 Premium and PlayReady Premium: