private static IEnumerable <byte[]> MicrosoftPlayReadyObjectHeader(byte[] data) { // PlayReady Header specs: // https://docs.microsoft.com/en-us/playready/specifications/playready-header-specification ushort playReadyObjectRecordCount = LittleEndian.AsUShort16(data, 4); var offset = 6; for (var i = 0; i < playReadyObjectRecordCount; i++) { ushort recordType = LittleEndian.AsUShort16(data, offset); ushort recordLength = LittleEndian.AsUShort16(data, offset + 2); // Reserved/Unspecified record type... ignoring if (recordType == 0 || recordType > 3) { offset += recordLength; continue; } var playReadyHeader = Encoding.Unicode.GetString(data, offset + 4, recordLength); var xDoc = XDocument.Parse(playReadyHeader); if (xDoc.Root == null) { continue; } var kids = xDoc.Descendants(xDoc.Root.Name.Namespace + "KID"); foreach (XElement kid in kids) { Logger.Info(kid.Value); // PlayReady KeyIds are in LE format. (each uuid block) // Pssh box KeyIds are in BE format // // Use BE as common format - more human friendly - byte // ordering as in cannonical mpd form // // UUID Note: // Last 8 bytes of UUID are provided "as is" (i.e. BE form) yield return (LittleEndian.AsCanonicalUuid(Convert.FromBase64String(kid.Value), 0, DashUuidFormat)); } } }