Packages
membrane_core
1.2.7
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.7
1.2.6
1.2.5
retired
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc1
1.1.2
1.1.1
1.1.0
1.1.0-rc1
1.1.0-rc0
1.0.1
1.0.0
1.0.0-rc1
1.0.0-rc0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
retired
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
Membrane Multimedia Framework (Core)
Current section
Files
Jump to
Current section
Files
lib/membrane/funnel.ex
defmodule Membrane.Funnel do
@moduledoc """
Element that can be used for collecting data from multiple inputs and sending it through one
output.
When a new input connects in the `:playing` state, the funnel sends
`#{inspect(__MODULE__)}.NewInputEvent` via output.
"""
use Membrane.Filter
def_input_pad :input, accepted_format: _any, flow_control: :auto, availability: :on_request
def_output_pad :output, accepted_format: _any, flow_control: :auto
def_options end_of_stream: [spec: :on_last_pad | :on_first_pad | :never, default: :on_last_pad]
@impl true
def handle_init(_ctx, opts) do
{[], %{end_of_stream: opts.end_of_stream}}
end
@impl true
def handle_buffer(Pad.ref(:input, _id), buffer, _ctx, state) do
{[buffer: {:output, buffer}], state}
end
@impl true
def handle_pad_added(Pad.ref(:input, _id), %{playback_state: :playing}, state) do
{[event: {:output, %__MODULE__.NewInputEvent{}}], state}
end
@impl true
def handle_pad_added(Pad.ref(:input, _id), _ctx, state) do
{[], state}
end
@impl true
def handle_end_of_stream(Pad.ref(:input, _id), _ctx, %{end_of_stream: :never} = state) do
{[], state}
end
@impl true
def handle_end_of_stream(Pad.ref(:input, _id), ctx, %{end_of_stream: :on_first_pad} = state) do
if ctx.pads.output.end_of_stream? do
{[], state}
else
{[end_of_stream: :output], state}
end
end
@impl true
def handle_end_of_stream(Pad.ref(:input, _id), ctx, %{end_of_stream: :on_last_pad} = state) do
if ctx |> inputs_data() |> Enum.all?(& &1.end_of_stream?) do
{[end_of_stream: :output], state}
else
{[], state}
end
end
defp inputs_data(ctx) do
Enum.flat_map(ctx.pads, fn
{Pad.ref(:input, _id), data} -> [data]
_output -> []
end)
end
end