namespace OF_DL.Widevine; internal class PsshBox { private static readonly byte[] s_psshHeader = [0x70, 0x73, 0x73, 0x68]; private PsshBox(List kids, byte[] data) { KIDs = kids; Data = data; } public List KIDs { get; set; } 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.ReadExactly(header, 0, 4); if (!header.SequenceEqual(s_psshHeader)) { throw new Exception("Not a pssh box"); } stream.Seek(20, SeekOrigin.Current); byte[] kidCountBytes = new byte[4]; stream.ReadExactly(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.ReadExactly(kid); kids.Add(kid); } byte[] dataLengthBytes = new byte[4]; stream.ReadExactly(dataLengthBytes); if (BitConverter.IsLittleEndian) { Array.Reverse(dataLengthBytes); } uint dataLength = BitConverter.ToUInt32(dataLengthBytes); if (dataLength == 0) { return new PsshBox(kids, []); } byte[] data = new byte[dataLength]; stream.ReadExactly(data); return new PsshBox(kids, data); } }