# `Boombox.Bin`
[🔗](https://github.com/membraneframework/boombox/blob/v0.2.11/lib/boombox/bin.ex#L1)

`Boombox.Bin` is a Membrane Bin for audio and video streaming.
It can be used as a Sink or Source in your Membrane Pipeline.

If you use it as a Membrane Source and link `:output` pad, you
have to specify `:input` option, e.g.
```elixir
child(:boombox, %Boombox.Bin{
  input: "path/to/input/file.mp4"
})
|> via_out(:output, options: [kind: :audio])
|> child(:my_audio_sink, My.Audio.Sink)
```

If you use it as a Membrane Sink and link `:input` pad, you have
to specify `:output` option, e.g.
```elixir
child(:my_video_source, My.Video.Source)
|> via_in(:input, options: [kind: :video])
|> child(:boombox, %Boombox.Bin{
  output: "path/to/output/file.mp4"
})
```

`Boombox.Bin` cannot have `:input` and `:output` pads linked at
the same time.

`Boombox.Bin` cannot have `:input` and `:output` options set
at the same time.

If you use Boombox.Bin as a source, you can either:
  * link output pads in the same spec where you spawn it
  * or wait until Boombox.Bin returns a notification `{:new_tracks, [:audio | :video]}`
    and then link the pads according to the notification.
## Bin options

Passed via struct `t:Boombox.Bin.t/0`

- `input`  

  ```
  Boombox.Endpoints.input() | nil
  ```
  
  Default value: `nil`  
  

- `output`  

  ```
  Boombox.Endpoints.output() | nil
  ```
  
  Default value: `nil`  
  

## Pads

### `:input`

Accepted formats:
```
format when Transcoder.Audio.is_audio_format(format) or Transcoder.Video.is_video_format(format)
```

Direction: | `:input`
Availability: | `:on_request`
Pad options:

- `kind`  

  ```
  :video | :audio
  ```
  
  ***Required***  
  Specifies, if the input pad is for audio or video.
  
  There might be up to one pad of each kind at the time.

### `:output`

Accepted formats:
```
format when Transcoder.Audio.is_audio_format(format) or Transcoder.Video.is_video_format(format)
```

Direction: | `:output`
Availability: | `:on_request`
Pad options:

- `kind`  

  ```
  :video | :audio
  ```
  
  ***Required***  
  Specifies, if the output pad is for audio or video.
  
  There might be up to one pad of each kind at the time.

- `codec`  

  ```
  H264
  | VP8
  | VP9
  | AAC
  | Opus
  | RawVideo
  | RawAudio
  | [H264 | VP8 | VP9 | AAC | Opus | RawVideo | RawAudio]
  | nil
  ```
  
  Default value: `nil`  
  Specifies the codec of the stream flowing through the pad.
  
  Can be either a single codec or a list of codecs.
  
  If a list is provided
    * and the stream matches one of the codecs, the matching codec will be used,
    * and the stream doesn't match any of the codecs, it will be transcoded to
      the first codec in the list.
  
  If the codec is not specified, it will be resolved to:
    * `Membrane.H264` for video,
    * `Membrane.AAC` for audio, if the input is not WebRTC,
    * `Membrane.Opus` for audio, if the input is WebRTC.

- `transcoding_policy`  

  ```
  :always | :if_needed | :never
  ```
  
  Default value: `:if_needed`  
  Specifies the transcoding policy for the stream flowing through the pad.
  
  Can be either `:always`, `:if_needed`, or `:never`.
  
  If set to `:always`, the media stream will be decoded and/or encoded, even if the
  format of the stream arriving at the Boombox.Bin endpoint matches the
  output pad codec. This option is useful when you want to make sure keyframe request
  events going upstream the output pad are handled in Boombox when the Boombox input
  itself cannot handle them (i.e. when the input is not WebRTC).
  
  If set to `:if_needed`, the media stream will be transcoded only if the format of
  the stream arriving at the Boombox.Bin endpoint doesn't match the output
  pad codec.
  This is the default behavior.
  
  If set to `:never`, the input media stream won't be decoded or encoded.
  Changing alignment, encapsulation, or stream structure is still possible. This option
  is helpful when you want to ensure that Boombox.Bin will not use too many
  resources, e.g., CPU or memory.
  
  If the stream arriving at the Boombox.Bin endpoint doesn't match the output
  pad codec, an error will be raised.

# `input_pad_opts`

```elixir
@type input_pad_opts() :: [{:kind, :video | :audio}]
```

Options for pad `:input`

# `new_tracks`

```elixir
@type new_tracks() :: {:new_tracks, [:video | :audio]}
```

Type of notification sent to the parent of Boombox.Bin when new tracks arrive.

It is sent only when Boombox.Bin is used as a source (the `:input` option is set).

This notification is sent by Boombox.Bin only if its pads weren't linked
before `handle_playing/2` callback.

# `output_pad_opts`

```elixir
@type output_pad_opts() :: [
  kind: :video | :audio,
  codec:
    Membrane.H264
    | Membrane.VP8
    | Membrane.VP9
    | Membrane.AAC
    | Membrane.Opus
    | Membrane.RawVideo
    | Membrane.RawAudio
    | [
        Membrane.H264
        | Membrane.VP8
        | Membrane.VP9
        | Membrane.AAC
        | Membrane.Opus
        | Membrane.RawVideo
        | Membrane.RawAudio
      ]
    | nil,
  transcoding_policy: :always | :if_needed | :never
]
```

Options for pad `:output`

# `t`

```elixir
@type t() :: %Boombox.Bin{
  input: Boombox.Endpoints.input() | nil,
  output: Boombox.Endpoints.output() | nil
}
```

Struct containing options for `Boombox.Bin`

# `options`

```elixir
@spec options() :: keyword()
```

Returns description of options available for this module

---

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