# `Membrane.Bin`
[🔗](https://github.com/membraneframework/membrane-core/blob/v1.2.7/lib/membrane/bin.ex#L1)

Bins, similarly to pipelines, are containers for elements.
However, at the same time, they can be placed and linked within pipelines.
Although bin is a separate Membrane entity, it can be perceived as a pipeline within an element.
Bins can also be nested within one another.

There are two main reasons why bins are useful:
* they enable creating reusable element groups
* they allow managing their children, for instance by dynamically spawning or replacing them as the stream changes.

In order to create bin `use Membrane.Bin` in your callback module.

# `callback_return`

```elixir
@type callback_return() :: {[Membrane.Bin.Action.t()], state()}
```

# `name`

```elixir
@type name() :: tuple() | atom()
```

Type that defines a bin name by which it is identified.

# `options`

```elixir
@type options() :: struct() | nil
```

Defines options that can be passed to `start_link/3` and received
in `c:handle_init/2` callback.

# `state`

```elixir
@type state() :: any()
```

# `handle_child_notification`
*optional* 

```elixir
@callback handle_child_notification(
  notification :: Membrane.ChildNotification.t(),
  element :: Membrane.Child.name(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when a notification comes in from an element.
By default, it ignores the received message.

# `handle_child_pad_removed`
*optional* 

```elixir
@callback handle_child_pad_removed(
  child :: Membrane.Child.name(),
  pad :: Membrane.Pad.ref(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when a child removes its pad.

The callback won't be invoked, when you have initiated the pad removal,
eg. when you have returned `t:Membrane.Bin.Action.remove_link()` action
which made one of your children's pads be removed.
By default, it does nothing.

# `handle_child_playing`
*optional* 

```elixir
@callback handle_child_playing(
  child :: Membrane.Child.name(),
  context :: Membrane.Bin.CallbackContext.t(),
  state()
) :: callback_return()
```

Callback invoked when a child enters `playing` playback.

By default, it does nothing.

# `handle_child_setup_completed`
*optional* 

```elixir
@callback handle_child_setup_completed(
  child :: Membrane.Child.name(),
  context :: Membrane.Bin.CallbackContext.t(),
  state()
) :: callback_return()
```

Callback invoked when a child complete its setup.

By default, it does nothing.

# `handle_child_terminated`
*optional* 

```elixir
@callback handle_child_terminated(
  child :: Membrane.Child.name(),
  context :: Membrane.Bin.CallbackContext.t(),
  state()
) :: callback_return()
```

Callback invoked after a child terminates.

Context passed to this callback contains 3 additional fields: `:exit_reason`, `:group_name` and `:crash_initiator`.
Terminated child won't be present in the context of this callback. It is allowed to spawn a new
child with the same name.
By default, it does nothing.

# `handle_crash_group_down`
*optional* 

```elixir
@callback handle_crash_group_down(
  group_name :: Membrane.Child.group(),
  context :: Membrane.Bin.CallbackContext.t(),
  state()
) :: callback_return()
```

Callback invoked when crash of the crash group happens.

Context passed to this callback contains 3 additional fields: `:members`, `:crash_initiator` and `:crash_reason`.

# `handle_element_end_of_stream`
*optional* 

```elixir
@callback handle_element_end_of_stream(
  child :: Membrane.Child.name(),
  pad :: Membrane.Pad.ref(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when a child element finishes processing stream via given pad.

By default, it does nothing.

# `handle_element_start_of_stream`
*optional* 

```elixir
@callback handle_element_start_of_stream(
  child :: Membrane.Child.name(),
  pad :: Membrane.Pad.ref(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when a child element starts processing stream via given pad.
By default, it does nothing.

# `handle_info`
*optional* 

```elixir
@callback handle_info(
  message :: any(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when bin receives a message that is not recognized
as an internal membrane message.

Can be used for receiving data from non-membrane processes.
By default, it logs and ignores the received message.

# `handle_init`
*optional* 

```elixir
@callback handle_init(context :: Membrane.Bin.CallbackContext.t(), options :: options()) ::
  callback_return()
```

Callback invoked on initialization of bin.

This callback is synchronous: the parent waits until it finishes. Also, any failures
that happen in this callback crash the parent as well, regardless of crash groups.
For these reasons, it's important to do any long-lasting or complex work in `c:handle_setup/2`,
while `handle_init` should be used for things like parsing options, initializing state or
spawning children.
By default, it converts the opts struct to a map and sets them as the bin's state.

# `handle_pad_added`
*optional* 

```elixir
@callback handle_pad_added(
  pad :: Membrane.Pad.ref(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback that is called when new pad has been added to bin. Executed
ONLY for dynamic pads.

Context passed to this callback contains additional field `:pad_options`.
By default, it does nothing.

# `handle_pad_removed`
*optional* 

```elixir
@callback handle_pad_removed(
  pad :: Membrane.Pad.ref(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback that is called when some pad of the bin has been removed. Executed
ONLY for dynamic pads.

Context passed to this callback contains additional field `:pad_options`.
By default, it does nothing.

# `handle_parent_notification`
*optional* 

```elixir
@callback handle_parent_notification(
  notification :: Membrane.ParentNotification.t(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when a notification comes in from an parent.
By default, it ignores the received message.

# `handle_playing`
*optional* 

```elixir
@callback handle_playing(
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked when bin switches the playback to `:playing`.
By default, it does nothing.

# `handle_setup`
*optional* 

```elixir
@callback handle_setup(
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked on bin startup, right after `c:handle_init/2`.

Any long-lasting or complex initialization should happen here.
By default, it does nothing.

# `handle_spec_started`
*optional* 

```elixir
@callback handle_spec_started(
  children :: [Membrane.Child.name()],
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

This callback is deprecated since v1.1.0.

Callback invoked when children of `Membrane.ChildrenSpec` are started.

It is invoked, only if pipeline module contains its definition. Otherwise, nothing happens.

# `handle_terminate_request`
*optional* 

```elixir
@callback handle_terminate_request(
  context :: Membrane.Bin.CallbackContext.t(),
  state()
) :: callback_return()
```

A callback invoked when the bin is being removed by its parent.

By default, it returns `t:Membrane.Bin.Action.terminate/0` with reason `:normal`.

# `handle_tick`
*optional* 

```elixir
@callback handle_tick(
  timer_id :: any(),
  context :: Membrane.Bin.CallbackContext.t(),
  state :: state()
) :: callback_return()
```

Callback invoked upon each timer tick. A timer can be started with `t:Membrane.Bin.Action.start_timer/0`
action.

# `__using__`
*macro* 

Brings all the stuff necessary to implement a bin.

Options:
  - `:bring_spec?` - if true (default) imports and aliases `Membrane.ChildrenSpec`
  - `:bring_pad?` - if true (default) requires and aliases `Membrane.Pad`

# `bin?`

```elixir
@spec bin?(module()) :: boolean()
```

Checks whether module is a bin.

# `def_clock`
*macro* 

Defines that bin exposes a clock which is a proxy to one of its children.

If this macro is not called, no ticks will be forwarded to parent, regardless
of clock definitions in its children.

# `def_input_pad`
*macro* 

Macro that defines input pad for the bin.

It automatically generates documentation from the given definition
and adds compile-time stream format specs validation.

The type `t:Membrane.Pad.bin_spec/0` describes how the definition of pads should look.

# `def_options`
*macro* 

Macro defining options that parametrize bin.

It automatically generates appropriate struct and documentation.

Options are defined by a keyword list, where each key is an option name and
is described by another keyword list with following fields:

  * `spec:` typespec for value in struct
  * `default:` default value for option. If not present, value for this option
    will have to be provided each time options struct is created
  * `inspector:` function converting fields' value to a string. Used when
    creating documentation instead of `inspect/1`, eg. `inspector: &Membrane.Time.inspect/1`
  * `description:` string describing an option. It will be used for generating the docs

# `def_output_pad`
*macro* 

Macro that defines output pad for the bin.

It automatically generates documentation from the given definition
and adds compile-time stream format specs validation.

The type `t:Membrane.Pad.bin_spec/0` describes how the definition of pads should look.

# `is_bin_name?`
*macro* 

---

*Consult [api-reference.md](api-reference.md) for complete listing*
