Skip to main content

Timeline

Struct Timeline 

Source
pub struct Timeline { /* private fields */ }
Expand description

A stateful conversion session.

Implementations§

Source§

impl Timeline

Source

pub fn new() -> Self

New session with no anchor.

Source

pub fn with_anchor(anchor: TimeAnchor) -> Self

New session with a wall-clock anchor.

Examples found in repository?
examples/scte35_to_hls.rs (line 29)
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}
More examples
Hide additional examples
examples/scte35_to_dash.rs (line 27)
15fn main() {
16    // Real Unified Streaming splice: ID 2002, out-of-network, break_duration 24 s.
17    let hex = "FC302100000000000000FFF01005000007D27FEF7F7E0020F580C0000000000088B9661D";
18    let raw: Vec<u8> = (0..hex.len())
19        .step_by(2)
20        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap())
21        .collect();
22
23    let anchor = TimeAnchor {
24        pts_90k: 0,
25        utc_epoch_ms: 1_705_320_000_000,
26    };
27    let mut timeline = Timeline::with_anchor(anchor);
28    let event = timeline.push_scte35(&raw).expect("valid splice");
29
30    // Build emsg config: 90 kHz timescale, segment-relative delta 0, 24 s duration.
31    let cfg = EmsgConfig {
32        timescale: 90_000,
33        presentation: PresentationTime::Delta(0),
34        event_duration: 2_160_000, // 24s * 90000
35        value: "34".to_string(),   // segmentation_type_id for Provider Ad Start
36        id: event.id.unwrap_or(0),
37    };
38
39    let emsg_bytes = timeline
40        .to_emsg(&event, &cfg)
41        .expect("SCTE-35-sourced event");
42
43    println!("Event kind  : {}", event.kind);
44    println!("Event id    : {:?}", event.id);
45    println!("emsg length : {} bytes", emsg_bytes.len());
46    println!();
47    println!(
48        "emsg hex: {}",
49        emsg_bytes
50            .iter()
51            .map(|b| format!("{:02X}", b))
52            .collect::<Vec<_>>()
53            .join("")
54    );
55
56    // Verify round-trip: extract the splice from the emsg and compare.
57    use timed_metadata::convert::emsg_to_scte35;
58    let extracted = emsg_to_scte35(&emsg_bytes).expect("round-trip");
59    assert_eq!(extracted, raw, "splice bytes must survive verbatim");
60    println!();
61    println!("Round-trip verified: splice bytes survive verbatim in emsg message_data.");
62}
Source

pub fn set_anchor(&mut self, anchor: TimeAnchor)

Set / replace the anchor.

Source

pub fn push_scte35(&mut self, bytes: &[u8]) -> Result<TimedEvent>

Parse a SCTE-35 section; unroll its PTS into an absolute MediaTime.

Examples found in repository?
examples/scte35_to_hls.rs (line 32)
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}
More examples
Hide additional examples
examples/scte35_to_dash.rs (line 28)
15fn main() {
16    // Real Unified Streaming splice: ID 2002, out-of-network, break_duration 24 s.
17    let hex = "FC302100000000000000FFF01005000007D27FEF7F7E0020F580C0000000000088B9661D";
18    let raw: Vec<u8> = (0..hex.len())
19        .step_by(2)
20        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap())
21        .collect();
22
23    let anchor = TimeAnchor {
24        pts_90k: 0,
25        utc_epoch_ms: 1_705_320_000_000,
26    };
27    let mut timeline = Timeline::with_anchor(anchor);
28    let event = timeline.push_scte35(&raw).expect("valid splice");
29
30    // Build emsg config: 90 kHz timescale, segment-relative delta 0, 24 s duration.
31    let cfg = EmsgConfig {
32        timescale: 90_000,
33        presentation: PresentationTime::Delta(0),
34        event_duration: 2_160_000, // 24s * 90000
35        value: "34".to_string(),   // segmentation_type_id for Provider Ad Start
36        id: event.id.unwrap_or(0),
37    };
38
39    let emsg_bytes = timeline
40        .to_emsg(&event, &cfg)
41        .expect("SCTE-35-sourced event");
42
43    println!("Event kind  : {}", event.kind);
44    println!("Event id    : {:?}", event.id);
45    println!("emsg length : {} bytes", emsg_bytes.len());
46    println!();
47    println!(
48        "emsg hex: {}",
49        emsg_bytes
50            .iter()
51            .map(|b| format!("{:02X}", b))
52            .collect::<Vec<_>>()
53            .join("")
54    );
55
56    // Verify round-trip: extract the splice from the emsg and compare.
57    use timed_metadata::convert::emsg_to_scte35;
58    let extracted = emsg_to_scte35(&emsg_bytes).expect("round-trip");
59    assert_eq!(extracted, raw, "splice bytes must survive verbatim");
60    println!();
61    println!("Round-trip verified: splice bytes survive verbatim in emsg message_data.");
62}
Source

pub fn to_daterange(&self, ev: &TimedEvent) -> Result<DateRange>

Convert to a DATERANGE (requires an anchor).

Examples found in repository?
examples/scte35_to_hls.rs (line 35)
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}
Source

pub fn to_emsg(&self, ev: &TimedEvent, cfg: &EmsgConfig) -> Result<Vec<u8>>

Convert to a serialized SCTE-35 emsg box.

Examples found in repository?
examples/scte35_to_dash.rs (line 40)
15fn main() {
16    // Real Unified Streaming splice: ID 2002, out-of-network, break_duration 24 s.
17    let hex = "FC302100000000000000FFF01005000007D27FEF7F7E0020F580C0000000000088B9661D";
18    let raw: Vec<u8> = (0..hex.len())
19        .step_by(2)
20        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap())
21        .collect();
22
23    let anchor = TimeAnchor {
24        pts_90k: 0,
25        utc_epoch_ms: 1_705_320_000_000,
26    };
27    let mut timeline = Timeline::with_anchor(anchor);
28    let event = timeline.push_scte35(&raw).expect("valid splice");
29
30    // Build emsg config: 90 kHz timescale, segment-relative delta 0, 24 s duration.
31    let cfg = EmsgConfig {
32        timescale: 90_000,
33        presentation: PresentationTime::Delta(0),
34        event_duration: 2_160_000, // 24s * 90000
35        value: "34".to_string(),   // segmentation_type_id for Provider Ad Start
36        id: event.id.unwrap_or(0),
37    };
38
39    let emsg_bytes = timeline
40        .to_emsg(&event, &cfg)
41        .expect("SCTE-35-sourced event");
42
43    println!("Event kind  : {}", event.kind);
44    println!("Event id    : {:?}", event.id);
45    println!("emsg length : {} bytes", emsg_bytes.len());
46    println!();
47    println!(
48        "emsg hex: {}",
49        emsg_bytes
50            .iter()
51            .map(|b| format!("{:02X}", b))
52            .collect::<Vec<_>>()
53            .join("")
54    );
55
56    // Verify round-trip: extract the splice from the emsg and compare.
57    use timed_metadata::convert::emsg_to_scte35;
58    let extracted = emsg_to_scte35(&emsg_bytes).expect("round-trip");
59    assert_eq!(extracted, raw, "splice bytes must survive verbatim");
60    println!();
61    println!("Round-trip verified: splice bytes survive verbatim in emsg message_data.");
62}

Trait Implementations§

Source§

impl Debug for Timeline

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Timeline

Source§

fn default() -> Timeline

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.