Packages
membrane_rtp_plugin
0.15.0
0.31.5
0.31.4
0.31.3
0.31.2
0.31.1
0.31.0
0.30.0
0.29.1
0.29.0
0.28.0
0.27.1
0.27.0
0.26.0
0.25.0
0.24.1
0.24.0
0.23.2
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.1
0.19.0
0.18.0
0.17.1
0.17.0
0.16.0
0.15.0
0.15.0-rc.1
0.14.0
0.13.0
0.12.2
0.12.1
0.12.0
0.11.0
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.1-alpha.3
0.7.1-alpha.2
0.7.0-alpha.2
0.7.0-alpha.1
0.7.0-alpha
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0-alpha
Membrane Multimedia Framework plugin for RTP
Current section
Files
Jump to
Current section
Files
lib/membrane/rtp/stream_send_bin.ex
defmodule Membrane.RTP.StreamSendBin do
@moduledoc """
Bin payloading and serializing media stream to RTP.
"""
use Membrane.Bin
alias Membrane.RTP
def_input_pad :input, demand_unit: :buffers, caps: :any
def_input_pad :rtcp_input, availability: :on_request, demand_unit: :buffers, caps: :any
def_output_pad :output, caps: :any, demand_unit: :buffers
def_output_pad :rtcp_output, availability: :on_request, caps: :any, demand_unit: :buffers
def_options payloader: [default: nil, spec: module],
payload_type: [spec: RTP.payload_type_t()],
ssrc: [spec: RTP.ssrc_t()],
clock_rate: [spec: RTP.clock_rate_t()],
rtcp_report_interval: [spec: Membrane.Time.t() | nil],
rtp_extension_mapping: [
default: nil,
spec: RTP.SessionBin.rtp_extension_mapping_t()
]
@impl true
def handle_init(opts) do
use_payloader = !is_nil(opts.payloader)
maybe_link_payloader_bin =
&to(&1, :payloader, %RTP.PayloaderBin{
payloader: opts.payloader,
ssrc: opts.ssrc,
clock_rate: opts.clock_rate,
payload_type: opts.payload_type
})
links = [
link_bin_input()
|> then(if use_payloader, do: maybe_link_payloader_bin, else: & &1)
|> to(:packet_tracker, %RTP.OutboundPacketTracker{
ssrc: opts.ssrc,
payload_type: opts.payload_type,
clock_rate: opts.clock_rate,
extension_mapping: opts.rtp_extension_mapping || %{}
})
|> to_bin_output()
]
spec = %ParentSpec{links: links}
{{:ok, spec: spec}, %{ssrc: opts.ssrc, rtcp_report_interval: opts.rtcp_report_interval}}
end
@impl true
def handle_prepared_to_playing(_context, %{rtcp_report_interval: nil} = state), do: {:ok, state}
@impl true
def handle_prepared_to_playing(_ctx, state) do
{{:ok, start_timer: {:report_timer, state.rtcp_report_interval}}, state}
end
@impl true
def handle_playing_to_prepared(_context, %{rtcp_report_interval: nil} = state), do: {:ok, state}
@impl true
def handle_playing_to_prepared(_context, state) do
{{:ok, stop_timer: :report_timer}, state}
end
@impl true
def handle_pad_added(Pad.ref(:rtcp_output, _id) = pad, _ctx, state) do
links = [
link(:packet_tracker)
|> via_out(:rtcp_output)
|> to_bin_output(pad)
]
spec = %ParentSpec{links: links}
{{:ok, spec: spec}, state}
end
@impl true
def handle_pad_added(Pad.ref(:rtcp_input, _id) = pad, _ctx, state) do
links = [
link_bin_input(pad)
|> via_in(:rtcp_input)
|> to(:packet_tracker)
]
spec = %ParentSpec{links: links}
{{:ok, spec: spec}, state}
end
@impl true
def handle_tick(:report_timer, _ctx, state) do
{{:ok, forward: {:packet_tracker, :send_stats}}, state}
end
end