Skip to main content

scte35_to_hls/
scte35_to_hls.rs

1//! Demonstrate SCTE-35 → HLS `#EXT-X-DATERANGE` conversion.
2//!
3//! Parses a hex `splice_info_section` (Unified Streaming splice ID 2002),
4//! builds a [`Timeline`] with a wall-clock [`TimeAnchor`], and emits the
5//! `#EXT-X-DATERANGE:` tag line.
6//!
7//! Run with:
8//! ```text
9//! cargo run -p timed-metadata --example scte35_to_hls
10//! ```
11
12use timed_metadata::{TimeAnchor, Timeline};
13
14fn main() {
15    // Real Unified Streaming splice: ID 2002, out-of-network, break_duration 24 s.
16    let hex = "FC302100000000000000FFF01005000007D27FEF7F7E0020F580C0000000000088B9661D";
17    let raw: Vec<u8> = (0..hex.len())
18        .step_by(2)
19        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap())
20        .collect();
21
22    // Wall-clock anchor: assume PTS 0 == 2024-01-15T12:00:00.000Z (ms since epoch).
23    let utc_epoch_ms: i64 = 1_705_320_000_000; // 2024-01-15 12:00:00 UTC
24    let anchor = TimeAnchor {
25        pts_90k: 0,
26        utc_epoch_ms,
27    };
28
29    let mut timeline = Timeline::with_anchor(anchor);
30
31    // Parse the SCTE-35 section and unroll PTS wrap.
32    let event = timeline.push_scte35(&raw).expect("valid splice");
33
34    // Convert to a DATERANGE.
35    let daterange = timeline.to_daterange(&event).expect("anchor is set");
36
37    println!("Event kind  : {}", event.kind);
38    println!("Event id    : {:?}", event.id);
39    println!(
40        "Duration    : {:?}s",
41        event.duration.map(|d| d.as_seconds_f64())
42    );
43    println!();
44    println!("{}", daterange.to_tag_line());
45}