View Source Upgrading to v0.12

Between v0.11 and v0.12 some breaking changes have occurred, so here comes the guide that will help you adjust your code to the new API. See the release notes for details.

deps-upgrade

Deps upgrade

Upgrade membrane_core to v0.12.

defp deps do
   [
     {:membrane_core, "~> 0.12.0"},
     ...
   ]
end

implement-handle_child_pad_removed-4-callback-in-bins-and-pipelines-if-it-is-needed

Implement handle_child_pad_removed/4 callback in bins and pipelines, if it is needed

Now, if bin removes its pad (e.g. by removing an element linked to the bin's inner pad), bin's parent has to have implemented proper handle_child_pad_removed/4 callback, to handle it. If there is no such a callback, default behaviour is to raise an error.

@impl true
def handle_child_pad_removed(:rtp, Pad.ref(:rtp_input, _ssrc), _ctx, state) do
  # ...
end

use-child-ref-2-if-you-want-to-refer-a-child-spawned-inside-a-group

Use Child.ref/2, if you want to refer a child spawned inside a group

Until now, name of a child spawned in a spec like this:

{child(:source, %My.Source{options: options}), crash_group: {:source_group, :temporary}}

would be just :source.

Since membrane_core v0.12, if you spawn a child inside a group (this includes crash group as well), the child name will also contain the name of the group. In the case above, the name of the My.Source will be Child.ref(:source, group: :source_group). If you want to send a notification to it or link it with another child, you can do it as follows:

- spec = 
-   get_child(:source)
-   |> child(:sink, My.Sink)
- 
- actions = [spec: spec, notify_child: {:source, :start_streaming}]  
- 
- {actions, state}

+ spec = 
+   get_child(Child.ref(:source, group: :source_group))
+   |> child(:sink, My.Sink)
+
+ actions = [
+   spec: spec,
+   notify_child: {Child.ref(:source, group: :source_group), :start_streaming}
+ ]  
+
+ {actions, state}

The key present in children map in the callback context changes as well.

- @impl true
- def handle_info(message, %{children: %{source: child_data}}, state) do
-   ...
- end

+ @impl true
+ def handle_info(message, %{children: %{Child.ref(:source, group: :source_group) => child_data}}, state) do
+   ...
+ end

Analogically, if a component is spawned inside a group, the value of the field name in its callback context changes as well, and becomes Child.ref(child_name, group: group_name).

- @impl true 
- def handle_init(%{name: :source} = _ctx, state) do
-   ...
- end

+ @impl true
+ def handle_init(%{name: Child.ref(:source, group: :source_group)} = _ctx, state) do
+   ...
+ end

For components spawned beyond groups, nothing changes.

remove-playback-action

Remove :playback action

Now, membrane pipelines enter the playing playback by default and they don't have to return a :playback action to do it.

- @impl true 
- def handle_setup(_ctx, state) do
- {[playback: :playing], state}
- end

Instead of it, there is a new action introduced in membrane_core v0.12, setup: :incomplete | :complete. If you want to defer a moment when a component enters the playing playback, you can return {:setup, :incomplete} action from handle_setup callback. If you do that, a component will enter the playing playback only when you return {:setup, :complete} action from another callback, e.g. handle_info.

- @impl true 
- def handle_setup(_ctx, state) do
-   Process.send_after(self(), :play, 1000)
-   {[], state}
- end
-
- @impl true 
- def handle_info(:play, _ctx, state) do
-   {[playback: :playing], state} 
- end

+ @impl true 
+ def handle_setup(_ctx, state) do
+   Process.send_after(self(), :play, 1000)
+   {[setup: :incomplete], state}
+ end
+
+ @impl true
+ def handle_info(:play, _ctx, state) do
+   {[setup: :complete], state}
+ end

:setup action is available not only in pipelines but in bins and elements as well.