Packages
membrane_hls_plugin
2.1.2
3.0.10
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.1.9
2.1.8
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.16
2.0.15
2.0.14
2.0.13
2.0.12
2.0.11
2.0.10
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
Adaptive live streaming (HLS) plugin for the Membrane Framework.
Current section
Files
Jump to
Current section
Files
lib/membrane/hls/filler/text.ex
defmodule Membrane.HLS.Filler.Text do
use Membrane.Filter
def_input_pad(:input, accepted_format: Membrane.Text)
def_output_pad(:output, accepted_format: Membrane.Text)
@impl true
def handle_init(_ctx, _opts) do
state = %{
queue: :queue.new(),
time_reference: nil,
time_first_buffer: nil
}
{[], state}
end
@impl true
def handle_end_of_stream(:input, _ctx, state = %{time_reference: nil}) do
# We need parent notification first.
{[], state}
end
def handle_end_of_stream(:input, _ctx, state) do
{[end_of_stream: :output], state}
end
@impl true
def handle_buffer(:input, buffer, _ctx, state = %{time_reference: nil}) do
state = update_in(state, [:queue], fn q -> :queue.in(buffer, q) end)
{[], state}
end
def handle_buffer(:input, buffer, ctx, state = %{time_first_buffer: nil}) do
state =
state
|> update_in([:queue], fn q -> :queue.in(buffer, q) end)
|> put_in([:time_first_buffer], Membrane.Buffer.get_dts_or_pts(buffer))
fill_and_forward(ctx, state)
end
def handle_buffer(:input, buffer, _ctx, state) do
{[buffer: {:output, buffer}], state}
end
@impl true
def handle_parent_notification({:time_reference, t}, ctx, state = %{time_reference: nil}) do
state = put_in(state, [:time_reference], t)
cond do
state.time_first_buffer != nil ->
fill_and_forward(ctx, state)
ctx.pads.input.end_of_stream? ->
{[end_of_stream: :output], state}
true ->
{[], state}
end
end
def handle_parent_notification(_, _ctx, state) do
{[], state}
end
defp fill_and_forward(ctx, state) do
from = state.time_reference
to = state.time_first_buffer
filler_buffers =
if from < to and from > 0 do
buffer = %Membrane.Buffer{
payload: "",
pts: from,
metadata: %{to: to}
}
[buffer]
else
[]
end
{real_buffers, state} =
get_and_update_in(state, [:queue], fn q ->
{:queue.to_list(q), :queue.new()}
end)
buffers = filler_buffers ++ real_buffers
actions =
if ctx.pads.input.end_of_stream? do
[buffer: {:output, buffers}, end_of_stream: :output]
else
[buffer: {:output, buffers}]
end
{actions, state}
end
end