pub struct HlsOriginBuilder { /* private fields */ }std only.Expand description
Fluent builder for HlsOrigin (issue #873) — replaces the old
four-positional HlsOrigin::new (deleted; this crate is at 0.4.0
unpublished, so there is no compatibility burden), which could not
express “classic HLS, no low latency” at all since part_target_ms was a
mandatory positional argument.
let classic_ts = HlsOrigin::builder(Arc::clone(&trunk))
.target_duration_secs(6.0)
.window_segments(nz(4))
.container(Container::MpegTs)
// `.low_latency(..)` omitted entirely -> classic HLS.
.build()
.expect("both required fields were set");Implementations§
Source§impl HlsOriginBuilder
impl HlsOriginBuilder
Sourcepub fn target_duration_secs(self, target_duration_secs: f64) -> Self
pub fn target_duration_secs(self, target_duration_secs: f64) -> Self
#EXT-X-TARGETDURATION’s configured floor (RFC 8216bis §4.4.3.1) —
required; HlsOriginBuilder::build errors if this is never called.
The actually-rendered value is raised to the largest real segment
duration seen, if that ever exceeds this (see render_playlist).
Sourcepub fn window_segments(self, window_segments: NonZeroUsize) -> Self
pub fn window_segments(self, window_segments: NonZeroUsize) -> Self
How many closed segments this origin advertises in a rendered Media
Playlist — required; independent of
media_plane::trunk::TrunkConfig::segment_capacity (the Trunk’s
own retention bound): a caller may legitimately want a shorter
advertised window than the Trunk retains for other consumers (e.g. a
DVR SegmentEgress reading the same Trunk).
Sourcepub fn container(self, container: Container) -> Self
pub fn container(self, container: Container) -> Self
Which container this origin serves segments/parts as. Defaults to
Container::Fmp4 if never called, matching every pre-#873 caller’s
behaviour. Orthogonal to Self::low_latency — all four
{Fmp4, MpegTs} x {classic, low-latency} combinations are valid.
Sourcepub fn low_latency(self, part_target_ms: u32) -> Self
pub fn low_latency(self, part_target_ms: u32) -> Self
Opt into LL-HLS: part_target_ms becomes #EXT-X-PART-INF’s
PART-TARGET (milliseconds). Omit this call entirely for classic
HLS — no #EXT-X-PART/#EXT-X-PART-INF/#EXT-X-SERVER-CONTROL/
#EXT-X-PRELOAD-HINT tags are then rendered, regardless of
Self::container. This is what the old constructor’s mandatory
part_target_ms positional could not express.
Sourcepub fn media_sequence_offset(self, offset: u64) -> Self
pub fn media_sequence_offset(self, offset: u64) -> Self
Add offset to every Media Sequence Number this origin shows: the
playlist’s EXT-X-MEDIA-SEQUENCE, the numbers in segment/part URIs and
the _HLS_msn it answers to. Default 0.
A fresh Trunk restarts its segment numbers at 1; the offset is
the mechanism that keeps the Media Sequence Number a client sees
increasing across a replacement origin (RFC 8216bis §6.2.2: it MUST NOT
decrease). Pass previous.next_media_sequence() — not - 1: the number
the previous origin’s open segment was shown with is skipped too, as
its parts were already served (see HlsOrigin::next_media_sequence).
Sourcepub fn instance(self, token: u64) -> Self
pub fn instance(self, token: u64) -> Self
Override the per-origin HlsOrigin::instance token (default: a fresh
wall-clock-seeded one per build). For deterministic tests and for an
embedder that wants names stable across a rebuild it knows is the
same media.
Sourcepub fn program_date_time_arrival(
self,
clock: Arc<dyn Fn() -> i64 + Send + Sync>,
) -> Self
pub fn program_date_time_arrival( self, clock: Arc<dyn Fn() -> i64 + Send + Sync>, ) -> Self
Configure an arrival wall-clock source for #EXT-X-PROGRAM-DATE-TIME
(Apple authoring 8.4 MUST — PDT present in live playlists). clock
returns Unix epoch milliseconds; it is invoked at most once over the
origin’s lifetime (to stamp the first drained segment), never per
request, so the caller supplies whatever wall clock it wants (e.g. a
closure over std::time::SystemTime or a test counter) without the
sans-IO engine touching a clock itself. When omitted (the default) no
arrival source is used and PDTs come only from an explicit trunk
time_anchor (B1); when both are absent no PDT is emitted.
The arrival source anchors PDTs to the trunk’s own continuous segment timeline rather than to a (possibly jumping) source media clock, so a source-clock discontinuity never makes the date↔segment mapping ambiguous (server-requirements.md item 26).
Sourcepub fn declared_bandwidth_bps(self, declared_bandwidth_bps: u64) -> Self
pub fn declared_bandwidth_bps(self, declared_bandwidth_bps: u64) -> Self
Operator-declared peak bitrate (bits/second) for this origin’s
variant stream, used as a floor for BANDWIDTH in the master
playlist before any segment with a measurable duration has been
published (and as a lower bound afterwards). Validated at
Self::build (> 0 and <= u32::MAX).
Sourcepub fn audio_renditions(self, audio_renditions: Vec<AudioRenditionDecl>) -> Self
pub fn audio_renditions(self, audio_renditions: Vec<AudioRenditionDecl>) -> Self
Declare the audio renditions this origin’s master playlist advertises
(RFC 8216bis §4.4.6.1). Each entry becomes one #EXT-X-MEDIA:TYPE=AUDIO
line, emitted before the variants; the video variant’s AUDIO attribute
is set to the entry’s group_id. Empty by default (no audio
rendition lines, byte-identical to the pre-existing output).
Sourcepub fn audio_sibling_origins(self, origins: Vec<Arc<HlsOrigin>>) -> Self
pub fn audio_sibling_origins(self, origins: Vec<Arc<HlsOrigin>>) -> Self
Sibling audio origins (issue #1428 slice 3) whose measured peak/average
bandwidth and CODECS are folded into this (video) origin’s
multivariant playlist for split-audio routes. One per declared
rendition, in the same order. Each group’s EXT-X-STREAM-INF carries
BANDWIDTH = video peak + the group’s largest audio peak and
AVERAGE-BANDWIDTH likewise over averages (Apple authoring items
9.13/9.14); CODECS is the video codec plus the group’s distinct audio
codecs. HlsOriginBuilder::declared_bandwidth_bps floors the video
part only, never the audio part. Empty (the default) keeps the slice 1
behaviour: declared-only CODECS/BANDWIDTH.
Sourcepub fn subtitle_renditions(
self,
subtitle_renditions: Vec<SubtitleRenditionDecl>,
) -> Self
pub fn subtitle_renditions( self, subtitle_renditions: Vec<SubtitleRenditionDecl>, ) -> Self
Declare the WebVTT subtitle renditions this origin’s master playlist
advertises: one #EXT-X-MEDIA:TYPE=SUBTITLES per declaration in group
SUBTITLES_GROUP_ID, placed after the audio renditions, with every
variant’s SUBTITLES attribute set and wvtt added to its CODECS
(Apple HLS Authoring Spec item 5.10) when CODECS is known. Empty by
default: the master is byte-identical to the pre-existing output.
Sourcepub fn subtitle_sibling_origins(self, origins: Vec<Arc<HlsOrigin>>) -> Self
pub fn subtitle_sibling_origins(self, origins: Vec<Arc<HlsOrigin>>) -> Self
The Container::WebVtt origins serving the declared subtitle
renditions, one per declaration in the same order. Checked at
Self::build: each must be a WebVtt origin whose
EXT-X-TARGETDURATION equals this origin’s (Apple HLS Authoring Spec
item 5.6 — live subtitle playlists must match the other media).
Subtitle bandwidth is not folded into BANDWIDTH.
Sourcepub fn playlist_uri(self, playlist_uri: impl Into<String>) -> Self
pub fn playlist_uri(self, playlist_uri: impl Into<String>) -> Self
URI of this origin’s own media playlist, relative to the stream root
(e.g. "media.m3u8" or "audio/a0.m3u8"). Used to compute the
relative URI of RenditionSibling entries when rendering
#EXT-X-RENDITION-REPORT (RFC 8216bis §4.4.5.4). Defaults to
"media.m3u8" when unset.
Sourcepub fn rendition_siblings(self, siblings: Vec<RenditionSibling>) -> Self
pub fn rendition_siblings(self, siblings: Vec<RenditionSibling>) -> Self
Sibling renditions whose live edge is reported by this origin’s media playlist (RFC 8216bis §4.4.5.4). Each entry is a weak handle plus the sibling’s playlist URI. Empty by default.
Sourcepub fn closed_captions_none(self, closed_captions_none: bool) -> Self
pub fn closed_captions_none(self, closed_captions_none: bool) -> Self
When true, emit CLOSED-CAPTIONS=NONE on the video variant
(RFC 8216bis §4.4.6.2). Default false leaves the attribute omitted,
matching the pre-existing output.
Sourcepub fn closed_caption_overrides(self, overrides: Vec<ClosedCaptionDecl>) -> Self
pub fn closed_caption_overrides(self, overrides: Vec<ClosedCaptionDecl>) -> Self
Override NAME/LANGUAGE of detected caption streams (see
ClosedCaptionDecl). Empty by default.
Sourcepub fn build(self) -> Result<HlsOrigin, HlsOriginBuildError>
pub fn build(self) -> Result<HlsOrigin, HlsOriginBuildError>
Build the HlsOrigin, subscribing its one SegmentCursor
immediately (so the window starts empty but never misses a segment
published from this point on).
Errors, never silently defaults, if Self::target_duration_secs or
Self::window_segments was never called, for a zero
Self::low_latency part target, or for an offset that cannot hold
the u32 sequence range.
The advertised window is never shorter than three segments, whatever
Self::window_segments says (RFC 8216bis §6.2.2: a live Playlist
MUST NOT be shortened below three Target Durations). Part retention is
not checked here: the part ring’s capacity belongs to the Trunk
and is not observable from it; the playlist only advertises the parts
of a closed segment while all of them are still resident.