1use crate::binary_format::pssh::{PSSHBox, PlayreadyHeader};
4use base64::prelude::*;
5use binrw::BinRead;
6use std::io::Cursor;
7
8#[derive(Debug, Clone)]
9pub struct WrmHeader(String);
11
12impl From<String> for WrmHeader {
13 fn from(value: String) -> Self {
14 WrmHeader(value)
15 }
16}
17
18impl From<WrmHeader> for String {
19 fn from(value: WrmHeader) -> Self {
20 value.0
21 }
22}
23
24#[derive(Debug, Clone)]
26pub struct Pssh {
27 parsed: PlayreadyHeader,
28}
29
30impl Pssh {
31 pub fn from_bytes(b: &[u8]) -> Result<Self, binrw::Error> {
33 let pssh_box = PSSHBox::read(&mut Cursor::new(b));
34
35 match pssh_box {
36 Ok(pssh_box) => Ok(Self {
37 parsed: pssh_box.data,
38 }),
39 Err(_) => Ok(Self {
40 parsed: PlayreadyHeader::read(&mut Cursor::new(b))?,
41 }),
42 }
43 }
44
45 pub fn from_b64(b64: &[u8]) -> Result<Self, crate::Error> {
47 let bytes = BASE64_STANDARD.decode(b64)?;
48 Self::from_bytes(&bytes).map_err(|e| e.into())
49 }
50
51 pub fn wrm_headers(&self) -> Vec<WrmHeader> {
53 self.parsed
54 .records
55 .iter()
56 .filter(|o| o.type_ == 1)
57 .filter_map(|o| {
58 String::from_utf16(&o.data)
59 .inspect_err(|e| {
60 log::error!("Failed create uf16 string from wrm header: {e:?}")
61 })
62 .map(WrmHeader)
63 .ok()
64 })
65 .collect()
66 }
67}
68
69impl TryFrom<&[u8]> for Pssh {
70 type Error = binrw::Error;
71
72 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
73 Self::from_bytes(value)
74 }
75}