#drm #streaming #dash #pssh #content-protection

pssh-box

Parsing and serialization support for PSSH boxes used in DRM systems

6 releases

0.1.5 Feb 27, 2024
0.1.4 Feb 21, 2024
0.1.0 Jan 28, 2024

#160 in Video

Download history 305/week @ 2024-02-02 207/week @ 2024-02-09 267/week @ 2024-02-16 416/week @ 2024-02-23 183/week @ 2024-03-01 103/week @ 2024-03-08 92/week @ 2024-03-15 59/week @ 2024-03-22 112/week @ 2024-03-29 59/week @ 2024-04-05 88/week @ 2024-04-12 27/week @ 2024-04-19

287 downloads per month
Used in 2 crates (via dash-mpd)

MIT license

53KB
1K SLoC

pssh-box

This crate defines Rust data structures allowing you to store, parse and serialize Protection System Specific Header (PSSH) boxes, which provide data for the initialization of a Digital Rights Management (DRM) system.

Crates.io Released API docs CI Dependency status LICENSE

PSSH boxes are used:

  • in an MP4 box of type pssh in an MP4 fragment (CMAF/MP4/ISOBMFF containers)

  • in a <cenc:pssh> element in a DASH MPD manifest

A PSSH box includes information for a single DRM system. This library supports the PSSH data formats for the following DRM systems:

  • Widevine, owned by Google, widely used for DASH streaming
  • PlayReady, owned by Microsoft, widely used for DASH streaming
  • WisePlay, owned by Huawei
  • Irdeto
  • Marlin
  • Nagra
  • The unofficial variant of Apple FairPlay that is used for DASH-like streaming by Netflix
  • Common Encryption

PSSH boxes contain (depending on the DRM system) information on the key_ID for which to obtain a content key, the encryption scheme used (e.g. cenc, cbc1, cens or cbcs), the URL of the licence server, and checksum data.

Features

This crate provides the following functionality:

  • parse PSSH boxes from binary buffers (as found in an MP4 fragment), or from a base64-encoded string (as found in a <cenc:pssh> element in an MPD manifest), or from a hex-encoded string.

  • scan a binary buffer for the location of a PSSH box, using the function find_iter.

  • pretty print a PSSH, using function pprint.

  • serialize a PSSH box to binary, base64 or hexadecimal (base 16) formats, using methods to_bytes(), to_base64() and to_hex() on a PsshBox struct.

A commandline utility for decoding PSSH boxes and PSSH data in various formats is available in example/decode-pssh.rs.

Usage

let boxes = from_base64("AAAAZ3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEcSEKqL5HpT2ymw4FM7KEUKHLsaA3NmciIkYWE4YmU0N2EtNTNkYi0yOWIwLWUwNTMtM2IyODQ1MGExY2JiKgJTREjj3JWbBg==")
     .unwrap();
assert_eq!(boxes.len(), 1);
let pssh = &boxes[0];
assert_eq!(pssh.system_id, WIDEVINE_SYSTEM_ID);
if let PsshData::Widevine(ref pd) = pssh.pssh_data {
    assert!(pd.provider.clone().is_some_and(|p| p.eq("sfr")));
    assert_eq!(pd.key_id[0], hex::decode("aa8be47a53db29b0e0533b28450a1cbb").unwrap());
    assert_eq!(pd.content_id, Some(hex::decode("61613862653437612d353364622d323962302d653035332d336232383435306131636262").unwrap()));
}

Build

The protoc compiler is used during the build process to translate the protobuf interface definition for Widevine PSSH data into Rust structs. This happens in the build.rs file.

The default configuration of this crate depends on the protobuf-src crate to build a vendored version of the protoc compiler. This requires a working C++ compiler and autoconf support. To build on Windows, the simplest solution seems to be the UCRT64 environment of MSYS2; see our GitHub continuous integration workflow for one recipe that works. Disable the default feature vendored-protoc to use a locally installed protoc compiler instead (from Debian package protobuf-compiler, for example).

License

This project is licensed under the MIT license. For more information, see the LICENSE file.

Dependencies

~5–8MB
~140K SLoC