Skip to main content

HlsOriginBuilder

Struct HlsOriginBuilder 

Source
pub struct HlsOriginBuilder { /* private fields */ }
Available on crate feature 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

Source

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).

Source

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).

Source

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.

Source

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.

Source

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).

Source

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.

Source

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).

Source

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).

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn closed_caption_overrides(self, overrides: Vec<ClosedCaptionDecl>) -> Self

Override NAME/LANGUAGE of detected caption streams (see ClosedCaptionDecl). Empty by default.

Source

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.

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more