Current section

Files

Jump to
membrane_mpeg_ts_plugin lib membrane mpeg ts av_demuxer.ex
Raw

lib/membrane/mpeg/ts/av_demuxer.ex

defmodule Membrane.MPEG.TS.AVDemuxer do
@moduledoc """
Utility module for extracting the first audio and video streams found in the
input TS stream.
"""
use Membrane.Bin
def_input_pad(:input,
accepted_format: Membrane.RemoteStream
)
def_output_pad(:video,
accepted_format: Membrane.RemoteStream
)
def_output_pad(:audio,
accepted_format: Membrane.RemoteStream
)
@impl true
def handle_init(_ctx, _opts) do
spec = [
bin_input(:input)
|> child(:demuxer, Membrane.MPEG.TS.Demuxer),
child({:audio, :funnel}, Membrane.Funnel)
|> bin_output(:audio),
child({:video, :funnel}, Membrane.Funnel)
|> bin_output(:video)
]
{[spec: spec], %{}}
end
@impl true
def handle_child_notification({:mpeg_ts_pmt, pmt}, _element, _context, state) do
audio_stream =
Enum.find_value(pmt.streams, fn {sid, x} ->
if x.stream_type == :AAC, do: sid
end)
video_stream =
Enum.find_value(pmt.streams, fn {sid, x} ->
if x.stream_type == :H264, do: sid
end)
spec = [
get_child(:demuxer)
|> via_out(Pad.ref(:output, {:stream_id, audio_stream}))
|> get_child({:audio, :funnel}),
get_child(:demuxer)
|> via_out(Pad.ref(:output, {:stream_id, video_stream}))
|> get_child({:video, :funnel})
]
{[spec: spec], state}
end
end