timed-metadata
Convert DPI / timed-metadata signalling between SCTE-35, HLS
EXT-X-DATERANGE, and DASH emsg — losslessly. no_std, independently
versioned.
Install
[]
= "0.1"
What is timed-metadata?
Ad insertion and content-segmentation signalling flows through three formats across the OTT delivery chain:
| Format | Standard | Carrier |
|---|---|---|
SCTE-35 splice_info_section |
ANSI/SCTE 35 2023r1 | MPEG-2 TS |
HLS EXT-X-DATERANGE |
RFC 8216 / draft-pantos-hls-rfc8216bis §4.4.5.1 | HLS playlist |
DASH emsg |
SCTE 214-3; scheme urn:scte:scte35:2013:bin |
MP4/CMAF segment |
timed-metadata translates between all three. Conversions are lossless: the
original splice_info_section bytes travel verbatim as the SCTE35-OUT hex in
DATERANGE or as the message_data payload in emsg. No re-encoding, no
interpretation loss.
The three edges
Edge 1 — SCTE-35 → HLS EXT-X-DATERANGE
use ;
// Wall-clock anchor: PTS 0 == 2024-01-15T12:00:00 UTC.
let anchor = TimeAnchor ;
let mut timeline = with_anchor;
// Real Unified Streaming splice ID 2002 (24-second break).
let splice_hex = "FC302100000000000000FFF01005000007D27FEF7F7E0020F580C0000000000088B9661D";
let raw: = .step_by
.map
.collect;
let event = timeline.push_scte35.unwrap;
let daterange = timeline.to_daterange.unwrap;
println!;
// #EXT-X-DATERANGE:ID="2002",START-DATE="2024-01-15T12:00:00.000Z",
// PLANNED-DURATION=24,SCTE35-OUT=0xFC302100...
Edge 2 — SCTE-35 → DASH emsg
use PresentationTime;
use ;
let anchor = TimeAnchor ;
let mut timeline = with_anchor;
let event = timeline.push_scte35.unwrap;
let cfg = EmsgConfig ;
let emsg_bytes = timeline.to_emsg.unwrap;
// emsg_bytes is an ISO BMFF 'emsg' box ready to inject into a CMAF segment.
Edge 3 — DASH emsg → SCTE-35
use emsg_to_scte35;
let splice_raw: = emsg_to_scte35.unwrap;
// splice_raw is the verbatim splice_info_section; feed to scte35_splice::SpliceInfoSection.
Timeline session
[Timeline] is a stateful conversion session. It holds a [TimeAnchor]
(a PTS↔UTC mapping) and unrolls 33-bit PTS wrap so timestamps stay
monotonically increasing across a long stream.
- [
Timeline::push_scte35] — parse a section, unroll PTS, return a [TimedEvent]. - [
Timeline::to_daterange] — convert to [DateRange] (requires an anchor). - [
Timeline::to_emsg] — serialize the event as anemsgbox.
The pure conversion functions live in [convert] for use without a session.
CEA-608/708 → WebVTT
[webvtt] converts closed captions to WebVTT cues: feed one access unit's
cc_data() triplets at a time to [webvtt::Cea608CueExtractor] (CC1
pop-on/roll-up/paint-on) or [webvtt::Cea708CueExtractor] (service 1), then
render the resulting [webvtt::Cue]s with [webvtt::write_document] or —
for HLS segmented delivery — [webvtt::write_segment], which emits the
RFC 8216 §3.5 X-TIMESTAMP-MAP=MPEGTS:<n>,LOCAL:00:00:00.000 header. Lossy
by design (no cue placement/styling in this first pass) — see the module
docs for the full list of documented losses. Requires the cc-data feature
(off by default).
EBU Teletext → WebVTT
[webvtt::TeletextCueExtractor] converts an EBU Teletext (ETSI EN 300 706)
Level-1 subtitle page to WebVTT cues: feed one access unit's
[dvb_vbi::TeletextDataField]s at a time, tagged with a (magazine, page).
dvb-vbi carries the packet framing only (EN 301 775 §4.5); the
[webvtt::teletext] module owns the EN 300 706 decode itself — Hamming-8/4 +
odd-parity FEC, the English national-option Latin G0 character set, and
basic page composition. See the module docs and
timed-metadata/docs/teletext-subtitles.md for full spec citations and
documented losses (no enhancement packets, no styling, English-only national
option). Requires the teletext feature (off by default).
Features
| Feature | Default | Description |
|---|---|---|
std |
yes | Enable std in all dependencies. |
serde |
yes | Serialize/Deserialize for all public types. |
chrono |
yes | chrono dependency (future wall-clock helpers). |
cc-data |
no | CEA-608/708 → WebVTT cue extraction ([webvtt]). |
teletext |
no | EBU Teletext (EN 300 706) → WebVTT cue extraction ([webvtt::teletext]). |
no_std + alloc when built with default-features = false. All conversions
are available in no_std mode.
Spec citations
- ANSI/SCTE 35 2023r1 —
splice_info_sectionwire format. - RFC 8216 / draft-pantos-hls-rfc8216bis §4.4.5.1 —
EXT-X-DATERANGE. - SCTE 214-3 — SCTE-35 binary carriage in DASH
emsg; schemeurn:scte:scte35:2013:bin. - ISO/IEC 23009-1 §5.10.3.3 — ISOBMFF Event Message Box (
emsg). - W3C WebVTT + RFC 8216 §3.5 — WebVTT cue syntax + HLS
X-TIMESTAMP-MAPsegmented delivery. - ANSI/CTA-608-E / ANSI/CTA-708-E — closed-caption semantics (decode
owned by the
cc-datacrate).
License
Licensed under either of MIT or Apache-2.0 at your option.