Membrane.HLS.SinkBin (Membrane HLS Plugin v3.0.10)

Copy Markdown View Source

Bin responsible for receiving audio/video/text tracks, packaging them into CMAF/TS/AAC, and writing playlists/segments via the provided storage.

Timing contract

  • Upstream must provide monotonic, accurate PTS/DTS per track.
  • Tracks that produce segments at a given sync point must be aligned in time (minor AAC/H264 cut differences are tolerated within packager tolerance).
  • By default, the sink does not shift or trim timestamps.
  • Optional startup alignment trimming can be enabled with :trim_align?. This alignment is performed once at startup (not continuously). When H264 is present, alignment is anchored to H264 keyframes and advances to the next keyframe until all non-H264 tracks started at or before the selected cut point.

Operational modes

  • :vod syncs whenever the next segment group is ready and is strict about timing.
  • {:event, safety_delay} syncs on a target-duration cadence.
  • {:sliding, max_segments, safety_delay} syncs on cadence and keeps a rolling window.

Policy and error handling

  • All outputs are RFC-compliant.
  • :vod is strict: any packager error fails fast.
  • :event/:sliding are tolerant to recoverable timing issues by inserting discontinuities, but fail fast on missing mandatory track segments to avoid silent stalls.

Bin options

Passed via struct Membrane.HLS.SinkBin.t/0

  • storage

    HLS.Storage.t()

    Required
    Storage implementation used to write segments and playlists.

  • manifest_uri

    URI.t()

    Required
    URI of the master playlist written by the packager.

  • target_segment_duration

    Membrane.Time.t()

    Required
    Target duration for each HLS segment.

  • playlist_mode

    :vod | {:event, Membrane.Time.t()} | {:sliding, pos_integer(), Membrane.Time.t()}

    Default value: :vod

    • :vod - Segments are synced as soon as the next segment group is ready.
    • {:event, safety_delay} - Live event playlist, synced each target segment duration.
    • {:sliding, max_segments, safety_delay} - Live playlist with rolling window.
  • resume?

    boolean()

    Default value: false
    When true, attempt to resume from an existing master and media playlists in storage.

  • resume_on_error

    :start_new | :raise

    Default value: :start_new
    Policy for broken or missing initial playlists when resuming.

  • resume_as_live

    boolean()

    Default value: false
    When true, all media playlists loaded during resume have their finished flag reset to false and their type cleared before being handed to the packager. This allows resuming against a previously-finalized VOD playlist as if it were still a live event, preventing the packager from staying in VOD mode and silently dropping new segments.

    Only meaningful when resume? is also true.

  • flush_on_end

    boolean()

    Default value: true
    Automatically flush the packager when all streams ended. Set to false if flushing manually (via :flush notification).

  • trim_align?

    boolean()

    Default value: false
    When enabled, trims leading content once on startup before segmentation.

    If at least one H264 track is present, the cut point is selected on H264 keyframes. The aligner picks the earliest keyframe for which all non-H264 tracks have already started (first_ts <= cut_point). If needed, it waits for later keyframes.

    Without H264 tracks, the cut point is the latest first cuttable timestamp across inputs.

    For H264 tracks this requires parsed AU-aligned input with keyframe metadata (typically from Membrane.H264.Parser).

  • trim_align_max_leading_trim

    Membrane.Time.t()

    Default value: 3000000000
    Maximum amount of leading media that can be removed from a single track while aligning.

  • trim_align_max_queued_buffers

    pos_integer()

    Default value: 2000
    Maximum number of buffers queued per track while waiting for startup alignment. This guard is especially relevant when late non-H264 tracks force waiting for a later H264 keyframe cut point.

Pads

:input

Accepted formats:

Membrane.H264
Membrane.AAC
Membrane.Text
Membrane.RemoteStream
Direction::input
Availability::on_request

Pad options:

  • container

    :CMAF | :TS | :PACKED_AAC

    Default value: :CMAF
    How A/V tracks are packaged.

  • encoding

    :AAC | :H264 | :TEXT

    Required
    Encoding type determining which parser will be used for the given stream.

  • omit_subtitle_repetition

    boolean()

    Default value: false
    When writing subtitle playlists, subtitles that span over multiple segments are repeated in both segments. When this flag is turned on, subtitles appear only in the segment in which they start.

  • subtitle_min_duration

    Membrane.Time.t()

    Default value: 1500000000
    Forces subtitles to last at list the specified amount of time. If omitted, subtitles will last the duration of their content.

  • relative_mpeg_ts_timestamps

    boolean()

    Default value: false
    If true, each subtitle segment will have a X-TIMESTAMP-MAP header and its contents will be relative to that timing.

  • build_stream

    (track() -> HLS.VariantStream.t() | HLS.AlternativeRendition.t())

    Required
    Build either a HLS.VariantStream or a HLS.AlternativeRendition. VariantStream.bandwidth and VariantStream.codecs are deprecated and are now computed automatically when possible.

  • segment_duration

    Membrane.Time.t()

    Required
    Duration for a HLS segment.

Summary

Types

Options for pad :input

t()

Struct containing options for Membrane.HLS.SinkBin

Functions

Returns description of options available for this module

Types

input_pad_opts()

@type input_pad_opts() :: [
  container: :CMAF | :TS | :PACKED_AAC,
  encoding: :AAC | :H264 | :TEXT,
  omit_subtitle_repetition: boolean(),
  subtitle_min_duration: Membrane.Time.t(),
  relative_mpeg_ts_timestamps: boolean(),
  build_stream: (track() ->
                   HLS.VariantStream.t() | HLS.AlternativeRendition.t()),
  segment_duration: Membrane.Time.t()
]

Options for pad :input

t()

@type t() :: %Membrane.HLS.SinkBin{
  flush_on_end: boolean(),
  manifest_uri: URI.t(),
  playlist_mode:
    :vod
    | {:event, Membrane.Time.t()}
    | {:sliding, pos_integer(), Membrane.Time.t()},
  resume?: boolean(),
  resume_as_live: boolean(),
  resume_on_error: :start_new | :raise,
  storage: HLS.Storage.t(),
  target_segment_duration: Membrane.Time.t(),
  trim_align?: boolean(),
  trim_align_max_leading_trim: Membrane.Time.t(),
  trim_align_max_queued_buffers: pos_integer()
}

Struct containing options for Membrane.HLS.SinkBin

track()

@type track() :: Membrane.CMAF.Track.t() | map()

Functions

options()

@spec options() :: keyword()

Returns description of options available for this module