View Source HLS.Packager (HTTP Live Streaming (HLS) library v2.0.0)

The HLS.Packager module is responsible for managing and generating media and master playlists for HTTP Live Streaming (HLS). It handles various tasks such as loading and saving playlists, inserting new streams, uploading segments and maintaining synchronization points for different streams.

Summary

Functions

Adds a new track to the packager. Tracks can only be added as long as the master playlist has not been written yet.

Allows to append something to an URIs path.

Returns a specification to start this module under a supervisor.

Will force that the next added segment has an EXT-X-DISCONTINUITY tag.

Writes down the remaining segments and marks all playlists as finished (EXT-X-ENDLIST). Deletes pending playlists.

Checks if the given track already exists in the packager.

Returns the maximum track duration.

Returns the next synchronization point which can then be passed to the sync/2 function.

The put_init_section/3 function adds or updates the initialization section (such as an MPEG-4 ‘init’ section) for the given track. This section will be used for all upcoming segments and is essential for media formats like fragmented MP4 where an initial header is required before media segments can be played.

Adds a new segment asynchronously to the given track.

Generates a relative segment uri for the given playlist and segment index.

Initializes a new packager with a storage and its root manifest uri. By default, the packager will raise an exception when trying to resume a finished track. This behaviour can be controlled with the resume_finished_tracks option.

Synchronizes all media playlists and writes down the master playlist as soon as needed.

Returns the duration of the given track.

Returns a relative variant uri for a given track id.

Returns the tracks managed by the packager.

Types

@type add_track_opt() ::
  {:stream, HLS.VariantStream.t() | HLS.AlternativeRendition.t()}
  | {:segment_extension, String.t()}
  | {:target_segment_duration, float()}
  | {:codecs, [String.t()]}
@type t() :: %HLS.Packager{
  manifest_uri: URI.t(),
  master_written?: boolean(),
  master_written_callback: nil | (-> term()),
  storage: HLS.Storage.t(),
  tracks: %{required(track_id()) => Track.t()},
  upload_tasks_to_track: %{required(Task.ref()) => track_id()}
}
@type track_id() :: String.t()

Functions

Link to this function

add_track(packager, track_id, opts)

View Source
@spec add_track(GenServer.server(), track_id(), [add_track_opt()]) :: :ok

Adds a new track to the packager. Tracks can only be added as long as the master playlist has not been written yet.

Examples

Packager.add_track(
  packager,
  "416x234",
  stream: %HLS.VariantStream{
    uri: URI.new!("stream_416x234.m3u8"),
    bandwidth: 341_276,
    resolution: {416, 234},
    codecs: ["avc1.64000c", "mp4a.40.2"]
  },
  segment_extension: ".m4s",
  target_segment_duration: 7
)
Link to this function

append_to_path(uri, append)

View Source

Allows to append something to an URIs path.

Examples

iex> HLS.Packager.append_to_path(URI.new!("file://a.m3u8"), "_480p")
URI.new!("file://a_480p.m3u8")

iex> HLS.Packager.append_to_path(URI.new!("file://a/b.m3u8"), "_480p")
URI.new!("file://a/b_480p.m3u8")

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

discontinue_track(packager, track_id)

View Source
@spec discontinue_track(GenServer.server(), track_id()) :: :ok

Will force that the next added segment has an EXT-X-DISCONTINUITY tag.

@spec flush(GenServer.server()) :: :ok

Writes down the remaining segments and marks all playlists as finished (EXT-X-ENDLIST). Deletes pending playlists.

Link to this function

has_track?(packager, track_id)

View Source
@spec has_track?(GenServer.server(), track_id()) :: boolean()

Checks if the given track already exists in the packager.

Link to this function

max_track_duration(packager)

View Source
@spec max_track_duration(GenServer.server()) :: non_neg_integer()

Returns the maximum track duration.

Link to this function

next_sync_point(packager, target_duration)

View Source
@spec next_sync_point(GenServer.server(), pos_integer()) :: pos_integer()

Returns the next synchronization point which can then be passed to the sync/2 function.

Link to this function

put_init_section(packager, track_id, payload)

View Source
@spec put_init_section(GenServer.server(), track_id(), binary() | nil) :: :ok

The put_init_section/3 function adds or updates the initialization section (such as an MPEG-4 ‘init’ section) for the given track. This section will be used for all upcoming segments and is essential for media formats like fragmented MP4 where an initial header is required before media segments can be played.

If the init section has changed, it is uploaded and associated with future segments. If no payload is provided, the init section is removed.

Link to this function

put_segment(packager, track_id, payload, duration)

View Source
@spec put_segment(GenServer.server(), track_id(), binary(), float()) :: :ok

Adds a new segment asynchronously to the given track.

Link to this function

relative_segment_uri(playlist_uri, extname, segment_index)

View Source

Generates a relative segment uri for the given playlist and segment index.

Examples

iex> HLS.Packager.relative_segment_uri(
...>   URI.new!("file://x/stream_video_480p.m3u8"),
...>   ".aac",
...>   48
...> )
URI.new!("stream_video_480p/00000/stream_video_480p_00048.aac")

Initializes a new packager with a storage and its root manifest uri. By default, the packager will raise an exception when trying to resume a finished track. This behaviour can be controlled with the resume_finished_tracks option.

Examples

HLS.Packager.start_link(
  storage: HLS.Storage.File.new(),
  manifest_uri: URI.new!("file://stream.m3u8"),
  resume_finished_tracks: false,
  restore_pending_segments: true,
  master_written_callback: nil
)
Link to this function

sync(packager, sync_point)

View Source
@spec sync(GenServer.server(), pos_integer()) :: :ok

Synchronizes all media playlists and writes down the master playlist as soon as needed.

Link to this function

track_duration(packager, track_id)

View Source
@spec track_duration(GenServer.server(), track_id()) ::
  {:ok, non_neg_integer()} | {:error, :not_found}

Returns the duration of the given track.

Link to this function

track_variant_uri(packager, track_id)

View Source
@spec track_variant_uri(GenServer.server(), track_id()) :: URI.t()

Returns a relative variant uri for a given track id.

@spec tracks(GenServer.server()) :: %{required(track_id()) => HLS.Packager.Track.t()}

Returns the tracks managed by the packager.