The core of the Membrane Framework, advanced multimedia processing framework
This release includes mostly API improvements. For some of them, breaking changes were necessary. To facilitate migration, we prepared the updating guide that should help adjust your code to the changes.
The following actions have changed:
Membrane.Element.Action.caps_t
-> Membrane.Element.Action.stream_format_t
(#468)Membrane.Bin.Action.notify_t
-> Membrane.Bin.Action.notify_parent_t
(#415)Membrane.Element.Action.notify_t
-> Membrane.Element.Action.notify_parent_t
(#415)Membrane.Pipeline.Action.forward_t
-> Membrane.Pipeline.Action.notify_child_t
(#415)Membrane.Bin.Action.forward_t
-> Membrane.Bin.Action.notify_child_t
(#415)From now on, the callbacks should return an {actions, state}
tuple. Returning errors is no longer supported - if a component can't recover from an error, it should raise (#471)
Furthermore, the following callbacks have changed:
handle_stopped_to_prepared/2
-> handle_setup/2
in all components (#432)Membrane.Element.Base.handle_caps/4
-> Membrane.Element.Base.handle_stream_format/4
(#432)handle_element_start_of_stream/3
-> handle_element_start_of_stream/4
and handle_element_end_of_stream/3
-> handle_element_end_of_stream/4
in pipelines and bins (#417)handle_init/1
-> handle_init/2
in all components (#432)handle_other/3
-> handle_info/3
in all components (#415)handle_notification/4
-> handle_child_notification/4
in pipelines and bins (#415)The following callbacks have been removed:
handle_playing_to_prepared/2
(#432)handle_prepared_to_stopped/2
(#432)handle_shutdown/2
(#432)Instead, Membrane.ResourceGuard
, Membrane.UtilitySupervisor
or handle_terminate_request/2
should be used.
What is more, messages sent with the :notify_parent
action (former :notify
action), are handled in a separate handle_parent_notification/3
callback instead of being handled in handle_other/3
, along with messages sent from any other processes. (#415)
In v0.11
:caps
option passed to def_input_pad/2
or def_output_pad/2
has been deleted. Instead of it, we have added a new option - :accepted_format
. The main principle of these two options is the same - validation of value passed to :caps
or :stream_format
action. While :caps
required a module name or specific tuple format as argument, :accepted_format
requires following types of terms:
Elixir pattern - eg. accepted_format: %My.Custom.Format{field: value} when value in [:some, :enumeration]
The value passed to :stream_format
action has to match the provided pattern. In this case, the requirement above would
be satisfied by eg. stream_format: %My.Custom.Format{field: :some}
Module name - eg. accepted_format: My.Custom.Format
This would be equal to the match on the struct of the passed module, in this case accepted_format: %My.Custom.Format{}
Call to any_of
function - you can pass as many arguments to it, as you want. Each argument should be an Elixir pattern
or a module name, eg. stream_format: any_of(My.Custom.Format, %My.Another.Custom.Format{field: :value})
If you use any_of
, the value passed to :stream_format
will have to match at least one of the passed
arguments. In this case, stream_format: %My.Custom.Format{frequency: 1}
would be ok, but
stream_format: %My.Another.Custom.Format{field: :not_allowed_value}
would fail
Option :accepted_format
is required. If you don't want to perform any check on stream_format
, you can always write accepted_format: _any
, but it is not suggested.
Checks on stream_format
will be performed on both, intput
and output
pads, just as caps
were checked in those places.
Membrane.Bin.spec_t
and Membrane.Pipeline.spec_t
actions no more accept Membrane.ParentSpec
structure.
Instead, a tuple with the children structure and options needs to be passed. (#458)Membrane.ParentSpec
module, have been changed - till now on, the children structure needs to be defined with the use of child/3
, child/4
, get_child/2
and get_child/3
functions from the Membrane.ChildrenSpec
. (#458)Membrane.ParentSpec.link_bin_input/1
has been renamed to Membrane.ChildrenSpec.bin_input/1
(#458)Membrane.ParentSpec.link_bin_output/2
has been renamed to Membrane.ChildrenSpec.bin_output/2
(#458)Membrane.Time
moduleMembrane.Time.to_<unit name>/1
has been renamed to Membrane.Time.round_to_<unit name>/1
in order to indicate that the result will be rounded. (#435)def_options
macro:type
field from the def_options
keyword list has been removed, and the type specification of the option defined within the macro is determined by the :spec
field (#466)Membrane.Pipeline.start/3
and Membrane.Pipeline.start_link/3
now return {:ok, pipeline_supervisor, pipeline}
.(#432)Membrane.Testing
Membrane.Testing.Pipeline.start_link/1
has been changed to Membrane.Testing.Pipeline.start_link_supervised!/1
(#432)Membrane.Testing.Pipeline.options()
now have a single :structure
field allowing to specify the test pipeline's children structure, in place of the former :links
and :children
fields.handle_call/3
callback in the pipeline and areply
and :reply_to
actions. (#334)Membrane.Source
, Membrane.Filter
, Membrane.Endpoint
and Membrane.Sink
there is a list of all the callbacks available to be implemented for these modules.Membrane.Time.<plural unit name>/1
now accepts Ratio
structure as an argument. (#435)Membrane.Time.round_to_timebase/2
function has been added. (#435)Membrane.FilterAggregator
that allows running multiple filters sequentially within one process has been added (still experimental) (#355)Membrane.Testing.MockResourceGuard
has been added, to help write tests with the new way of handling resources. (#478)The changes that do not affect API:
{:error, ...}
monadsMembrane.Testing.Pipeline
with a custom module injected behaves in a desired way once Membrane.Testing.Pipeline.execute_actions/2
function is called (the custom module does not need to implement handle_other({:execute_actions, actions}, ...)
anymore)Full changelog: v0.10.0 ... v0.10.1
Membrane.ParentSpec{}
from handle_init/1
context
argument in Pipeline
and Bin
Membrane.Element.WithInputPads.def_input_pads/1
Membrane.Element.WithOutputPads.def_output_pads/1
Membrane.Log.*
Membrane.ParentSpec.link_bin_input/2
Membrane.ParentSpec.to_bin_output/2
Membrane.Time
: is_t/1
, system_time/0
, native_unit/1
, day/1
, hour/1
, minute/1
, second/1
, millisecond/1
, microsecond/1
, nanosecond/1
Membrane.Pipeline.{prepare, play, stop}
deprecated and adding :playback
action insteadMembrane.Pipeline.stop_and_terminate/2
deprecated and adding Membrane.Pipeline.terminate/2
insteadMembrane.RemoteControlled.Pipeline
- a basic implementation of a Membrane.Pipeline
that
can be spawned and controlled by an external process #366
Membrane.ElementError
exception if such a situation occurs #341
Membrane.Testing.Pipeline
API - deprecating the Membrane.Testing.Pipeline.Options
usage, allowing to use pipeline_keyword_list_t
as options in Membrane.Testing.Pipeline.start/1
and Membrane.Testing.Pipeline.start_link/1
Full changelog: v0.9.0 ... v0.10.0
The Membrane Core can now handle the demands in filters for you! :tada:
To enable this, use demand_mode: :auto
in your pad's definition:
def_input_pad :input,
demand_mode: :auto,
caps: :any
This will make the Core send a demand automatically, no need to use :demand
action anymore.
By adding the same option to the output pad, the Core will also handle any incoming demands and demands on all input pads, so it is suitable for cases when a filter consumes data from all inputs uniformly.
See how automatic demands are used in funnel
:stopped
will result
in runtime error (previously only a warning was printed out). #389
Full Changelog: https://github.com/membraneframework/membrane_core/compare/v0.8.2...v0.9.0
Release includes:
Release includes:
Membrane.Logger
metadata in the Membrane.ParentSpec
. All children spawned from that Membrane.ParentSpec
will receive specified metadata.Membrane.Buffer
structure explicitly. Timestamps should no longer live in Membrane.Buffer.metadata field #335.From v0.7.0 of membrane_core
it's possible to group elements and bins into crash groups.
Crash group is a logical entity that prevents the whole pipeline from crashing when one of its children crashes.
children = %{
{:endpoint_bin, endpoint_id} => %EndpointBin{
# ...
}
}
spec = %ParentSpec{children: children, crash_group: {endpoint_id, :temporary}}
In this case we create a new children - EndpointBin and we add it to crash group with id endpoint_id
. When EndpointBin crashes the whole pipeline will still be alive.
When some child in a crash group crashes the callback handle_crash_group_down/3
is called.
@impl true
def handle_crash_group_down(crash_group_id, ctx, state) do
Membrane.Logger.info("Crash group: #{inspect(crash_group_id)} is down.")
# do some stuff
end
At this moment Crash Groups are only useful for elements with dynamic pads.
In this version we also introduce an enhancement in linking elements. Sometimes there is a situation you want to link or create an element only when some requirements are met. To make it easier we introduce a new syntax that looks like below
encoding_specific_links =
case encoding do
# when encoding is :H264 we want to add one additional element -- H264 parser.
:H264 -> &to(&1, {:h264_parser, ssrc}, %Membrane.H264.FFmpeg.Parser{alignment: :nal})
# when encoding is :OPUS we just passes what we got
:OPUS -> & &1
end
links = [
link_bin_input(pad)
|> pipe_fun(encoding_specific_links)
|> to({:track_filter, track_id}, %Membrane.WebRTC.TrackFilter{enabled: track_enabled})
# ...
]
defp pipe_fun(term, fun), do: fun.(term)
From now Testing.Source sends a new type of caps - RemoteStream. This can break some of your already existing tests.
This release includes several bug fixes:
context
argument #278Membrane.Event.{StartOfStream, EndOfStream}
events. Since v0.5.0 they're replaced with dedicated action and callbacks #280forward
action in pipelines and bins now accepts list #279