Boombox (Boombox v0.2.9)

View Source

Boombox is a tool for audio and video streaming.

See run/1 for details and examples.livemd for examples.

Summary

Types

When configuring a track for a media type (video or audio), the following options are used

In order to configure a RTP input a receiving port MUST be provided and the media that will be received MUST be configured. Media configuration is explained further in common_rtp_opt/0.

In order to configure a RTP output the target port and address MUST be provided (can be provided in :target option as a <address>:<port> string) and the media that will be sent MUST be configured. Media configuration is explained further in common_rtp_opt/0.

If true the incoming streams will be passed to the output according to their timestamps, if not they will be passed as fast as possible. True by default.

Functions

Asynchronous version of run/2.

Gracefully terminates Boombox when using :reader or :writer endpoints before a response of type :finished has been received.

Runs boombox with given input and plays audio and video streams on your computer.

Reads a packet from Boombox.

Runs boombox with given input and output.

Runs boombox with CLI arguments.

Writes provided packet to Boombox.

Types

boombox_server()

@opaque boombox_server()

common_rtp_opt()

@type common_rtp_opt() ::
  {:video_encoding, Membrane.RTP.encoding_name()}
  | {:video_payload_type, Membrane.RTP.payload_type()}
  | {:video_clock_rate, Membrane.RTP.clock_rate()}
  | {:audio_encoding, Membrane.RTP.encoding_name()}
  | {:audio_payload_type, Membrane.RTP.payload_type()}
  | {:audio_clock_rate, Membrane.RTP.clock_rate()}
  | {:aac_bitrate_mode, Membrane.RTP.AAC.Utils.mode()}

When configuring a track for a media type (video or audio), the following options are used:

  • <media_type>_encoding - MUST be provided to configure given media type. Some options are encoding-specific. Currently supported encodings are: AAC, Opus, H264, H265.
  • <media_type>_payload_type, <media_type>_clock rate - MAY be provided. If not, an unofficial default will be used. The following encoding-specific parameters are available for both RTP input and output:
  • aac_bitrate_mode - MUST be provided for AAC encoding. Defines which mode should be assumed/set when depayloading/payloading.

elixir_input()

@type elixir_input() :: {:stream | :writer | :message, in_raw_data_opts()}

elixir_output()

@type elixir_output() :: {:stream | :reader | :message, out_raw_data_opts()}

hls_mode_opt()

@type hls_mode_opt() :: {:mode, :live | :vod}

hls_variant_selection_policy_opt()

@type hls_variant_selection_policy_opt() ::
  {:variant_selection_policy,
   Membrane.HTTPAdaptiveStream.Source.variant_selection_policy()}

in_raw_data_opts()

@type in_raw_data_opts() :: [
  audio: :binary | boolean(),
  video: :image | boolean(),
  is_live: boolean()
]

in_rtp_opts()

@type in_rtp_opts() :: [
  common_rtp_opt()
  | {:port, :inet.port_number()}
  | {:audio_specific_config, binary()}
  | {:vps, binary()}
  | {:pps, binary()}
  | {:sps, binary()}
]

In order to configure a RTP input a receiving port MUST be provided and the media that will be received MUST be configured. Media configuration is explained further in common_rtp_opt/0.

The following encoding-specific parameters are available for RTP input:

  • audio_specific_config - MUST be provided for AAC encoding. Contains crucial information about the stream and has to be obtained from a side channel.
  • vps (H265 only), pps, sps - MAY be provided for H264 or H265 encodings. Parameter sets, could be obtained from a side channel. They contain information about the encoded stream.

input()

@type input() ::
  (path_or_uri :: String.t())
  | {path_or_uri :: String.t(),
     [hls_variant_selection_policy_opt()]
     | [{:framerate, Membrane.H264.framerate() | Membrane.H265.framerate_t()}]}
  | {:mp4 | :aac | :wav | :mp3 | :ivf | :ogg | :h264 | :h265,
     location :: String.t()}
  | {:mp4 | :aac | :wav | :mp3 | :ivf | :ogg, location :: String.t(),
     [{:transport, :file | :http}]}
  | {:h264, location :: String.t(),
     transport: :file | :http, framerate: Membrane.H264.framerate()}
  | {:h265, location :: String.t(),
     transport: :file | :http, framerate: Membrane.H265.framerate_t()}
  | {:webrtc, webrtc_signaling()}
  | {:whip, uri :: String.t(), [{:token, String.t()}]}
  | {:rtmp, (uri :: String.t()) | (client_handler :: pid())}
  | {:rtsp, url :: String.t()}
  | {:rtp, in_rtp_opts()}
  | {:hls, url :: String.t()}
  | {:hls, url :: String.t(), [hls_variant_selection_policy_opt()]}
  | {:srt, url :: String.t()}
  | {:srt, url :: String.t(), srt_auth_opts()}
  | {:srt, server_awaiting_accept :: ExLibSRT.Server.t()}

out_raw_data_opts()

@type out_raw_data_opts() :: [
  {:audio, :binary | boolean()}
  | {:video, :image | boolean()}
  | {:audio_format, Membrane.RawAudio.SampleFormat.t()}
  | {:audio_rate, Membrane.RawAudio.sample_rate_t()}
  | {:audio_channels, Membrane.RawAudio.channels_t()}
  | {:video_width, non_neg_integer()}
  | {:video_height, non_neg_integer()}
  | pace_control_opt()
]

out_rtp_opts()

@type out_rtp_opts() :: [
  common_rtp_opt()
  | {:address, :inet.ip_address() | String.t()}
  | {:port, :inet.port_number()}
  | {:target, String.t()}
  | transcoding_policy_opt()
]

In order to configure a RTP output the target port and address MUST be provided (can be provided in :target option as a <address>:<port> string) and the media that will be sent MUST be configured. Media configuration is explained further in common_rtp_opt/0.

output()

@type output() ::
  (path_or_uri :: String.t())
  | {path_or_uri :: String.t(), [transcoding_policy_opt() | hls_mode_opt()]}
  | {:mp4 | :aac | :wav | :mp3 | :ivf | :ogg | :h264 | :h265,
     location :: String.t()}
  | {:mp4 | :aac | :wav | :mp3 | :ivf | :ogg | :h264 | :h265,
     location :: String.t(), [transcoding_policy_opt()]}
  | {:webrtc, webrtc_signaling()}
  | {:webrtc, webrtc_signaling(), [transcoding_policy_opt()]}
  | {:whip, uri :: String.t(),
     [
       {:token, String.t()}
       | {bandit_option :: atom(), term()}
       | transcoding_policy_opt()
     ]}
  | {:hls, location :: String.t()}
  | {:hls, location :: String.t(), [hls_mode_opt() | transcoding_policy_opt()]}
  | {:rtp, out_rtp_opts()}
  | {:srt, url :: String.t()}
  | {:srt, url :: String.t(), srt_auth_opts()}
  | :player

pace_control_opt()

@type pace_control_opt() :: {:pace_control, boolean()}

If true the incoming streams will be passed to the output according to their timestamps, if not they will be passed as fast as possible. True by default.

srt_auth_opts()

@type srt_auth_opts() :: [stream_id: String.t(), password: String.t()]

transcoding_policy_opt()

@type transcoding_policy_opt() :: {:transcoding_policy, :always | :if_needed | :never}

webrtc_signaling()

@type webrtc_signaling() :: Membrane.WebRTC.Signaling.t() | String.t()

Functions

async(stream \\ nil, opts)

@spec async(Enumerable.t() | nil, input: input(), output: output()) ::
  Task.t() | Enumerable.t()

Asynchronous version of run/2.

Doesn't block the calling process until the termination of the processing.

It returns a Task.t() that can be awaited later.

If the output is a :stream, :reader or :message endpoint, or the input is a :writer or :message endpoint, the behaviour is identical to run/2.

close(writer)

@spec close(Boombox.Writer.t() | Boombox.Reader.t()) ::
  :ok | {:error, :incompatible_mode | :already_finished}

Gracefully terminates Boombox when using :reader or :writer endpoints before a response of type :finished has been received.

When using :reader endpoint on output informs Boombox that no more packets will be read from it with read/1 and that it should terminate accordingly.

When using :writer endpoint on input informs Boombox that it will not be provided any more packets with write/2 and should terminate accordingly.

play(stream \\ nil, input)

@spec play(Enumerable.t() | nil, input() | elixir_input()) :: :ok

Runs boombox with given input and plays audio and video streams on your computer.

Boombox.play(input) is idiomatic to Boombox.run(input: input, output: :player).

Example

Boombox.play("rtmp://localhost:5432")

read(reader)

@spec read(Boombox.Reader.t()) ::
  {:ok, Boombox.Packet.t()} | :finished | {:error, :incompatible_mode}

Reads a packet from Boombox.

If returned with :ok, then this function can be called again to request the next packet, and if returned with :finished, then Boombox finished it's operation and will not produce any more packets.

Can be called only when using :reader endpoint on output.

run(stream \\ nil, opts)

@spec run(Enumerable.t() | nil,
  input: input() | elixir_input(),
  output: output() | elixir_output()
) ::
  :ok | Enumerable.t() | Boombox.Writer.t() | Boombox.Reader.t() | pid()

Runs boombox with given input and output.

Example

Boombox.run(input: "rtmp://localhost:5432", output: "index.m3u8")

Boombox.run(
  input: "path/to/file.mp4",
  output: {:webrtc, "ws://0.0.0.0:1234"}
)

See input/0 and output/0 for available inputs and outputs and examples.livemd for examples.

Calling this function results in it blocking until the media flow is finished and then returning :ok, except for when an endpoint with special behavior is used.

Input endpoints with special behaviours:

  • :stream - a Stream or other Enumerable containing Boombox.Packets is expected as the first argument.
  • :writer - this function will return a Boombox.Writer struct, which is used to write media packets to boombox with write/2 and to finish writing with close/1.
  • :message - this function returns a PID of a process to communicate with. The process accepts the following types of messages:
    • {:boombox_packet, packet :: Boombox.Packet.t()} - provides boombox with a media packet. The process will a {:boombox_finished, boombox_pid :: pid()} message to sender_pid if it has finished processing packets and should not be provided any more.
    • :boombox_close - tells boombox that no more packets will be provided and that it should terminate.

Output endpoints with special behaviours:

  • :stream - this function will return a Stream that contains Boombox.Packets
  • :reader - this function will return a Boombox.Reader struct, which is used to read media packets from boombox with read/1 and to stop reading with close/1.
  • :message - this function returns a PID of a process to communicate with. The process will send the following types of messages to the process that called this function:
    • {:boombox_packet, boombox_pid :: pid(), packet :: Boombox.Packet.t()} - contains a packet produced by boombox.
    • {:boombox_finished, boombox_pid :: pid()} - informs that boombox has finished producing packets and will begin terminating. No more messages will be sent.

run_cli(argv \\ System.argv())

@spec run_cli([String.t()]) :: :ok

Runs boombox with CLI arguments.

Example

# boombox.exs
Mix.install([:boombox])
Boombox.run_cli()
elixir boombox.exs -i "rtmp://localhost:5432" -o "index.m3u8"

write(writer, packet)

@spec write(Boombox.Writer.t(), Boombox.Packet.t()) ::
  :ok | :finished | {:error, :incompatible_mode}

Writes provided packet to Boombox.

Returns :ok if more packets can be provided, and :finished when Boombox finished consuming and will not accept any more packets. Returns synchronously once the packet has been ingested and Boombox is ready for more packets.

Can be called only when using :writer endpoint on input.