Skip to content

membraneframework/ex_hls

Repository files navigation

ExHLS

Hex.pm API Docs CircleCI

This repository contains ExHLS - an Elixir package for handling HLS streams.

It's a part of the Membrane Framework.

Installation

The package can be installed by adding ex_hls to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_hls, "~> 0.1.2"}
  ]
end

Usage

To read HLS stream from the .m3u8 playlist, start the client with:

client = ExHLS.Client.new(<URI of the .m3u8 playlist>)

Then you can inspect the variants available in your playlist:

ExHLS.Client.get_variants(client)
# Returns:
#   %{
#     0 => %{
#       id: 0,
#       name: "720",
#       uri: "url_0/193039199_mp4_h264_aac_hd_7.m3u8",
#       codecs: "mp4a.40.2,avc1.64001f",
#       bandwidth: 2149280,
#       resolution: {1280, 720},
#       frame_rate: nil
#     },
#     ...
#   }

If there are multiple variants available, you need to choose one of them with:

ExHLS.Client.choose_variant(client, <id>)

where <id> is the id field of the entry returned by ExHLS.Client.get_variants/1.

Now you can get the Elixir stream containing media chunks:

stream = ExHLS.Client.generate_stream(client)
Enum.take(stream, 5)
# Returns: 
# [
#   %ExHLS.Chunk{
#     payload: <<220, 0, 76, 97, 118, 99, 54, 49, 46, 51, 46, 49, 48, 48, 0, 66,
#       32, 8, 193, 24, 56>>,
#     pts_ms: 0,
#     dts_ms: 0,
#     track_id: 2,
#     metadata: %{},
#     media_type: :audio
#   },
#   %ExHLS.Chunk{
#     payload: <<0, 0, 2, 171, 6, 5, 255, 255, 167, 220, 69, 233, 189, 230, 217,
#       72, 183, 150, 44, 216, 32, 217, 35, 238, 239, 120, 50, 54, 52, 32, 45, 32,
#       99, 111, 114, 101, 32, 49, 54, 52, 32, 114, 51, 49, 48, 56, 32, ...>>,
#     pts_ms: 0,
#     dts_ms: 0,
#     track_id: 1,
#     metadata: %{},
#     media_type: :video
#   },
#   %ExHLS.Chunk{
#     payload: <<33, 16, 4, 96, 140, 28>>,
#     pts_ms: 23,
#     dts_ms: 23,
#     track_id: 2,
#     metadata: %{},
#     media_type: :audio
#   },
#   %ExHLS.Chunk{
#     payload: <<0, 0, 1, 222, 65, 154, 34, 108, 67, 63, 254, 169, 150, 0, 4, 1,
#       131, 32, 3, 199, 34, 90, 245, 77, 218, 222, 66, 91, 35, 3, 208, 204, 165,
#       117, 149, 218, 168, 161, 173, 73, 104, 105, 159, 56, 151, ...>>,
#     pts_ms: 40,
#     dts_ms: 40,
#     track_id: 1,
#     metadata: %{},
#     media_type: :video
#   },
#   %ExHLS.Chunk{
#     payload: <<33, 16, 4, 96, 140, 28>>,
#     pts_ms: 46,
#     dts_ms: 46,
#     track_id: 2,
#     metadata: %{},
#     media_type: :audio
#   }
# ]

To pop only single elements from the stream containing ExHLS Chunks, you can use StreamSplit.pop/1.

Note: If the HLS playlist type is Live (not VoD), you can generate stream from single ExHLS.Client instance only once and only from the process, that created that ExHLS.Client. If you want to genereate more streams with Live HLS, you have to create a new ExHLS.Client each time.

Copyright and License

Copyright 2025, Software Mansion

Software Mansion

Licensed under the Apache License, Version 2.0