namespace OF_DL.Widevine; internal class PSSHBox { private static readonly byte[] PSSH_HEADER = new byte[] { 0x70, 0x73, 0x73, 0x68 }; private PSSHBox(List kids, byte[] data) { KIDs = kids; Data = data; } public List KIDs { get; set; } = new(); public byte[] Data { get; set; } public static PSSHBox FromByteArray(byte[] psshbox) { using MemoryStream stream = new(psshbox); stream.Seek(4, SeekOrigin.Current); byte[] header = new byte[4]; stream.Read(header, 0, 4); if (!header.SequenceEqual(PSSH_HEADER)) { throw new Exception("Not a pssh box"); } stream.Seek(20, SeekOrigin.Current); byte[] kidCountBytes = new byte[4]; stream.Read(kidCountBytes, 0, 4); if (BitConverter.IsLittleEndian) { Array.Reverse(kidCountBytes); } uint kidCount = BitConverter.ToUInt32(kidCountBytes); List kids = new(); for (int i = 0; i < kidCount; i++) { byte[] kid = new byte[16]; stream.Read(kid); kids.Add(kid); } byte[] dataLengthBytes = new byte[4]; stream.Read(dataLengthBytes); if (BitConverter.IsLittleEndian) { Array.Reverse(dataLengthBytes); } uint dataLength = BitConverter.ToUInt32(dataLengthBytes); if (dataLength == 0) { return new PSSHBox(kids, null); } byte[] data = new byte[dataLength]; stream.Read(data); return new PSSHBox(kids, data); } }