Example #1
0
        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));
                }
            }
        }