bramley-engine 0.1.2

Playback engine that runs Apple's MusicKit JS in an embedded JavaScript runtime with native media and Widevine DRM host objects.
Documentation
use anyhow::{Result, anyhow, bail};

fn bytes<const N: usize>(b: &[u8], o: usize) -> Result<[u8; N]> {
    o.checked_add(N)
        .and_then(|e| b.get(o..e))
        .and_then(|s| s.try_into().ok())
        .ok_or_else(|| anyhow!("truncated box at {o}"))
}
fn byte(b: &[u8], o: usize) -> Result<u8> {
    Ok(bytes::<1>(b, o)?[0])
}
fn slice(b: &[u8], o: usize, len: usize) -> Result<&[u8]> {
    o.checked_add(len)
        .and_then(|e| b.get(o..e))
        .ok_or_else(|| anyhow!("truncated box at {o}"))
}
pub fn be16(b: &[u8], o: usize) -> Result<u16> {
    Ok(u16::from_be_bytes(bytes(b, o)?))
}
pub fn be32(b: &[u8], o: usize) -> Result<u32> {
    Ok(u32::from_be_bytes(bytes(b, o)?))
}
pub fn be64(b: &[u8], o: usize) -> Result<u64> {
    Ok(u64::from_be_bytes(bytes(b, o)?))
}

pub fn ticks_to_us(ticks: i64, timescale: u32) -> i64 {
    (ticks as i128 * 1_000_000 / timescale.max(1) as i128) as i64
}

pub struct BoxRef {
    pub typ: [u8; 4],
    pub start: usize,
    pub body: usize,
    pub end: usize,
}

impl BoxRef {
    pub fn is(&self, t: &str) -> bool {
        self.typ.as_slice() == t.as_bytes()
    }
}

fn box_size(b: &[u8], off: usize, end: usize) -> Option<(usize, usize)> {
    let mut size = be32(b, off).ok()? as usize;
    let mut hdr = 8;
    if size == 1 {
        size = usize::try_from(be64(b, off + 8).ok()?).ok()?;
        hdr = 16;
    } else if size == 0 {
        size = end - off;
    }
    (size >= hdr && off.checked_add(size)? <= end).then_some((size, hdr))
}

pub fn boxes(b: &[u8], start: usize, end: usize) -> Vec<BoxRef> {
    let end = end.min(b.len());
    let mut out = Vec::new();
    let mut off = start;
    while off + 8 <= end {
        let Some((size, hdr)) = box_size(b, off, end) else {
            break;
        };
        let typ: [u8; 4] = b[off + 4..off + 8].try_into().unwrap();
        out.push(BoxRef {
            typ,
            start: off,
            body: off + hdr,
            end: off + size,
        });
        off += size;
    }
    out
}

pub fn complete_top_level(b: &[u8]) -> usize {
    let mut off = 0usize;
    while off + 8 <= b.len() {
        if be32(b, off).ok() == Some(0) {
            break;
        }
        let Some((size, _)) = box_size(b, off, b.len()) else {
            break;
        };
        off += size;
    }
    off
}

pub fn find(b: &[u8], start: usize, end: usize, path: &[&str]) -> Option<BoxRef> {
    for x in boxes(b, start, end) {
        if x.is(path[0]) {
            if path.len() == 1 {
                return Some(x);
            }
            if let Some(r) = find(b, x.body, x.end, &path[1..]) {
                return Some(r);
            }
        }
    }
    None
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Protection {
    pub scheme: String,
    pub kid: Vec<u8>,
    pub iv_size: usize,
    pub constant_iv: Vec<u8>,
    pub crypt: u32,
    pub skip: u32,
}

#[derive(Clone, Debug, Default)]
pub struct TrackInit {
    pub track_id: u32,
    pub timescale: u32,
    pub codec: String,
    pub asc: Vec<u8>,
    pub channels: u16,
    pub sample_rate: u32,
    pub default_duration: u32,
    pub default_size: u32,
    pub protection: Option<Protection>,
    pub pssh: Vec<u8>,
    pub duration_secs: Option<f64>,
}

fn descriptor_len(b: &[u8], p: &mut usize) -> Result<usize> {
    let mut len = 0usize;
    for _ in 0..4 {
        let c = byte(b, *p)?;
        *p += 1;
        len = (len << 7) | (c & 0x7f) as usize;
        if c & 0x80 == 0 {
            break;
        }
    }
    Ok(len)
}

fn asc_from_esds(b: &[u8], body: usize, end: usize) -> Result<Vec<u8>> {
    let mut p = body + 4;
    while p < end {
        let tag = byte(b, p)?;
        p += 1;
        let len = descriptor_len(b, &mut p)?;
        match tag {
            0x03 => {
                let flags = byte(b, p + 2)?;
                p += 3;
                if flags & 0x80 != 0 {
                    p += 2;
                }
                if flags & 0x40 != 0 {
                    p += 1 + byte(b, p)? as usize;
                }
                if flags & 0x20 != 0 {
                    p += 2;
                }
            }
            0x04 => p += 13,
            0x05 => return Ok(slice(b, p, len)?.to_vec()),
            _ => p += len,
        }
    }
    bail!("no AudioSpecificConfig")
}

pub fn hex(b: &[u8]) -> String {
    b.iter().map(|x| format!("{x:02x}")).collect()
}

fn versioned32(b: &[u8], body: usize, v0: usize, v1: usize) -> Result<u32> {
    be32(b, body + if byte(b, body)? == 1 { v1 } else { v0 })
}

pub fn parse_init(b: &[u8], moov: &BoxRef) -> Result<TrackInit> {
    let mut t = TrackInit::default();
    for x in boxes(b, moov.body, moov.end) {
        if x.is("pssh") {
            t.pssh.extend_from_slice(&b[x.start..x.end]);
        }
    }
    if let Some(mvhd) = find(b, moov.body, moov.end, &["mvhd"]) {
        let (ts, dur) = if byte(b, mvhd.body)? == 1 {
            (be32(b, mvhd.body + 20)?, be64(b, mvhd.body + 24)?)
        } else {
            (be32(b, mvhd.body + 12)?, be32(b, mvhd.body + 16)? as u64)
        };
        if ts > 0 && dur > 0 && dur != u32::MAX as u64 && dur != u64::MAX {
            t.duration_secs = Some(dur as f64 / ts as f64);
        }
    }
    if let Some(trex) = find(b, moov.body, moov.end, &["mvex", "trex"]) {
        t.default_duration = be32(b, trex.body + 12)?;
        t.default_size = be32(b, trex.body + 16)?;
    }
    let trak = find(b, moov.body, moov.end, &["trak"]).ok_or_else(|| anyhow!("no trak"))?;
    if let Some(tkhd) = find(b, trak.body, trak.end, &["tkhd"]) {
        t.track_id = versioned32(b, tkhd.body, 12, 20)?;
    }
    let mdhd = find(b, trak.body, trak.end, &["mdia", "mdhd"]).ok_or_else(|| anyhow!("no mdhd"))?;
    t.timescale = versioned32(b, mdhd.body, 12, 20)?;
    let stsd = find(b, trak.body, trak.end, &["mdia", "minf", "stbl", "stsd"])
        .ok_or_else(|| anyhow!("no stsd"))?;
    let entries = boxes(b, stsd.body + 8, stsd.end);
    let entry = entries
        .iter()
        .find(|e| e.is("enca") || e.is("mp4a"))
        .ok_or_else(|| anyhow!("no mp4a/enca sample entry"))?;
    t.channels = be16(b, entry.body + 16)?;
    t.sample_rate = be32(b, entry.body + 24)? >> 16;
    let inner = entry.body + 28;
    let esds = find(b, inner, entry.end, &["esds"]).ok_or_else(|| anyhow!("no esds"))?;
    t.asc = asc_from_esds(b, esds.body, esds.end)?;
    t.codec = format!("mp4a.40.{}", t.asc.first().map(|x| x >> 3).unwrap_or(2));
    if entry.is("enca") {
        let sinf =
            find(b, inner, entry.end, &["sinf"]).ok_or_else(|| anyhow!("enca without sinf"))?;
        let mut p = Protection {
            scheme: "cenc".into(),
            ..Default::default()
        };
        if let Some(schm) = find(b, sinf.body, sinf.end, &["schm"]) {
            p.scheme = String::from_utf8_lossy(slice(b, schm.body + 4, 4)?).into_owned();
        }
        let tenc =
            find(b, sinf.body, sinf.end, &["schi", "tenc"]).ok_or_else(|| anyhow!("no tenc"))?;
        if byte(b, tenc.body)? >= 1 {
            let pat = byte(b, tenc.body + 5)?;
            p.crypt = (pat >> 4) as u32;
            p.skip = (pat & 0x0f) as u32;
        }
        p.iv_size = byte(b, tenc.body + 7)? as usize;
        p.kid = slice(b, tenc.body + 8, 16)?.to_vec();
        if p.iv_size == 0 {
            let n = byte(b, tenc.body + 24)? as usize;
            p.constant_iv = slice(b, tenc.body + 25, n)?.to_vec();
        }
        t.protection = Some(p);
    }
    Ok(t)
}

#[derive(Clone, Debug, PartialEq)]
pub struct SampleEnc {
    pub iv: Vec<u8>,
    pub subsamples: Vec<(u32, u32)>,
}

#[derive(Clone, Debug)]
pub struct Sample {
    pub dts: i64,
    pub dur: u32,
    pub data: Vec<u8>,
    pub enc: Option<SampleEnc>,
}

fn take32(b: &[u8], p: &mut usize) -> Result<u32> {
    let v = be32(b, *p)?;
    *p += 4;
    Ok(v)
}

fn bounded_count(b: &[u8], body: usize) -> Result<usize> {
    let count = be32(b, body + 4)? as usize;
    if count > b.len() {
        bail!("sample count {count} exceeds buffer");
    }
    Ok(count)
}

fn parse_senc(b: &[u8], x: &BoxRef, iv_size: usize) -> Result<Vec<SampleEnc>> {
    let flags = be32(b, x.body)? & 0xff_ffff;
    let count = bounded_count(b, x.body)?;
    let mut p = x.body + 8;
    let mut out = Vec::new();
    for _ in 0..count {
        let iv = slice(b, p, iv_size)?.to_vec();
        p += iv_size;
        let mut subsamples = Vec::new();
        if flags & 0x2 != 0 {
            let n = be16(b, p)? as usize;
            p += 2;
            for _ in 0..n {
                subsamples.push((be16(b, p)? as u32, be32(b, p + 2)?));
                p += 6;
            }
        }
        out.push(SampleEnc { iv, subsamples });
    }
    Ok(out)
}

pub fn parse_fragment(b: &[u8], moof: &BoxRef, track: &TrackInit) -> Result<Vec<Sample>> {
    let mut out = Vec::new();
    let protection = track.protection.as_ref();
    for traf in boxes(b, moof.body, moof.end)
        .into_iter()
        .filter(|x| x.is("traf"))
    {
        let mut default_size = track.default_size;
        let mut default_dur = track.default_duration;
        let mut base = moof.start as i64;
        let mut decode_time = 0u64;
        let mut runs: Vec<(i64, Vec<(u32, u32)>)> = Vec::new();
        let mut encs: Option<Vec<SampleEnc>> = None;
        for x in boxes(b, traf.body, traf.end) {
            if x.is("tfhd") {
                let flags = be32(b, x.body)? & 0xff_ffff;
                let mut p = x.body + 8;
                if flags & 0x1 != 0 {
                    base = be64(b, p)? as i64;
                    p += 8;
                }
                if flags & 0x2 != 0 {
                    p += 4;
                }
                if flags & 0x8 != 0 {
                    default_dur = take32(b, &mut p)?;
                }
                if flags & 0x10 != 0 {
                    default_size = be32(b, p)?;
                }
            } else if x.is("tfdt") {
                decode_time = if byte(b, x.body)? == 1 {
                    be64(b, x.body + 4)?
                } else {
                    be32(b, x.body + 4)? as u64
                };
            } else if x.is("trun") {
                let flags = be32(b, x.body)? & 0xff_ffff;
                let count = bounded_count(b, x.body)?;
                let mut p = x.body + 8;
                let data_offset = if flags & 0x1 != 0 {
                    take32(b, &mut p)? as i32 as i64
                } else {
                    0
                };
                if flags & 0x4 != 0 {
                    p += 4;
                }
                let mut entries = Vec::new();
                for _ in 0..count {
                    let dur = if flags & 0x100 != 0 {
                        take32(b, &mut p)?
                    } else {
                        default_dur
                    };
                    let size = if flags & 0x200 != 0 {
                        take32(b, &mut p)?
                    } else {
                        default_size
                    };
                    p += 4 * ((flags & 0x400 != 0) as usize + (flags & 0x800 != 0) as usize);
                    entries.push((dur, size));
                }
                runs.push((data_offset, entries));
            } else if x.is("senc") && protection.is_some() {
                encs = Some(parse_senc(
                    b,
                    &x,
                    protection.map(|p| p.iv_size).unwrap_or(0),
                )?);
            }
        }
        let mut dts = decode_time as i64;
        let mut idx = 0usize;
        for (data_offset, entries) in runs {
            let mut pos = base
                .checked_add(data_offset)
                .and_then(|p| usize::try_from(p).ok())
                .ok_or_else(|| anyhow!("bad data offset"))?;
            for (dur, size) in entries {
                let data = slice(b, pos, size as usize)?.to_vec();
                let enc = encs
                    .as_ref()
                    .and_then(|e| e.get(idx))
                    .cloned()
                    .map(|mut e| {
                        if e.iv.is_empty() {
                            e.iv = protection
                                .map(|p| p.constant_iv.clone())
                                .unwrap_or_default();
                        }
                        e
                    });
                out.push(Sample {
                    dts,
                    dur,
                    data,
                    enc,
                });
                dts = dts.wrapping_add(dur as i64);
                pos += size as usize;
                idx += 1;
            }
        }
    }
    Ok(out)
}