# 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](https://img.shields.io/crates/v/pssh-box)](https://crates.io/crates/pssh-box) [![Released API docs](https://docs.rs/pssh-box/badge.svg)](https://docs.rs/pssh-box/) [![CI](https://github.com/emarsden/pssh-box-rs/workflows/build/badge.svg)](https://github.com/emarsden/pssh-box-rs/workflows/build/badge.svg) [![Dependency status](https://deps.rs/repo/github/emarsden/pssh-box-rs/status.svg)](https://deps.rs/repo/github/emarsden/pssh-box-rs) [![Recent crates.io downloads](https://img.shields.io/crates/dr/pssh-box?label=crates.io%20recent%20downloads)](https://img.shields.io/crates/dr/pssh-box?label=crates.io%20recent%20downloads) [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) PSSH boxes are used: - in an MP4 box of type `pssh` in an MP4 fragment (CMAF/MP4/ISOBMFF containers) - in a `` element in a DASH MPD manifest - in DRM initialization data passed to the Encrypted Media Extension of a web browser - in an EXT-X-SESSION-KEY field of an m3u8 playlist. 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 `` 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`. If you wish to use this functionality in web applications, you may be interested in the [pssh-box-wasm](https://github.com/emarsden/pssh-box-wasm/) library, which provides functionality for using this code as WebAssembly. ## 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 uses a **prebuilt protobuf compiler**, which must be locally installed (from Debian package `protobuf-compiler`, for example). As an alternative if the `vendored-protoc` feature is enabled, the `protobuf-src` crate is used to build a vendored version of the protoc compiler. This requires a working C++ compiler and cmake support, and tends to be rather unreliable (in particular, the abseil-cpp component of protobuf often causes build failures on any mildly unusual platform). To build on Windows, the simplest solution seems to be the UCRT64 environment of [MSYS2](https://www.msys2.org/); see our GitHub continuous integration workflow for one recipe that works. ## License This project is licensed under the MIT license. For more information, see the `LICENSE` file.