# `Membrane.Transcoder`
[🔗](https://github.com/membraneframework/membrane_transcoder_plugin/blob/v0.3.3/lib/transcoder.ex#L1)

Provides transcoding capabilities for audio and video streams in Membrane.

The bin takes an incoming stream on its input and converts it into the desired one
as specified by the option. Transcoding is applied only if it is neccessary.
The following video stream formats are supported:
* `Membrane.H264`
* `Membrane.H265`
* `Membrane.VP8`
* `Membrane.VP9`
* `Membrane.RawVideo`
* `Membrane.RemoteStream{content_format: Membrane.VP8}` (only as an input stream)
* `Membrane.RemoteStream{content_format: Membrane.VP9}` (only as an input stream)

The following audio stream formats are supported:
* `Membrane.AAC`
* `Membrane.Opus`
* `Membrane.MPEGAudio`
* `Membrane.RawAudio`
* `Membrane.RemoteStream{content_format: Membrane.Opus}` (only as an input stream)
* `Membrane.RemoteStream{content_format: Membrane.MPEGAudio}` (only as an input stream)

While `Membrane.Transcoder` can transcode between different stream formats, it can also be used
to change some parameters of the stream format.
Now, the only supported stream parameters are:
* `:pixel_format` in `Membrane.RawVideo`
* `:alignment` and `:stream_structure` in `Membrane.H264` and `Membrane.H265`
## Bin options

Passed via struct `t:Membrane.Transcoder.t/0`

- `output_stream_format`  

  ```
  stream_format() | stream_format_module() | stream_format_tuple() | stream_format_resolver()
  ```
  
  ***Required***  
  An option specifying desired output format.
  
  Can be either:
  * a struct being a Membrane stream format,
  * a module in which Membrane stream format struct is defined,
  * a function which receives input stream format as an input argument
  and is supposed to return the desired output stream format or its module.

- `transcoding_policy`  

  ```
  :always | :if_needed | :never | (stream_format() -> :always | :if_needed | :never)
  ```
  
  Default value: `:if_needed`  
  Specifies, when transcoding should be applied.
  
  Can be either:
  * an atom: `:always`, `:if_needed` (default) or `:never`,
  * a function that receives the input stream format and returns either `:always`,
    `:if_needed` or `:never`.
  
  If set to `:always`, the input media stream will be decoded and encoded, even
  if the input stream format and the output stream format are the same type.
  
  If set to `:if_needed`, the input media stream will be transcoded only if the input
  stream format and the output stream format are different types.
  This is the default behavior.
  
  If set to `:never`, the input media stream won't be neither decoded nor encoded.
  Changing alignment, encapsulation or stream structure is still possible. This option
  is helpful when you want to ensure that Membrane.Transcoder will not use too much
  of resources, e.g. CPU or memory.
  
  If the transition from the input stream format to the output stream format is not
  possible without decoding or encoding the stream, an error will be raised.

- `assumed_input_stream_format`  

  ```
  struct() | nil
  ```
  
  Default value: `nil`  
  Allows to override stream format of the input stream.
  
  Overriding will fail, the stream format sent on the Membrane.Transcoder's input
  pad is not `Membrane.RemoteStream`
  
  If nil or not set, the input stream format won't be overriden.

## Pads

### `:input`

Accepted formats:
```
format
when Audio.is_audio_format(format) or Video.is_video_format(format) or
       format.__struct__ == RemoteStream
```

Direction: | `:input`
Availability: | `:always`

### `:output`

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

Direction: | `:output`
Availability: | `:always`

# `stream_format`

```elixir
@type stream_format() ::
  Membrane.H264.t()
  | Membrane.H265.t()
  | Membrane.VP8.t()
  | Membrane.VP9.t()
  | Membrane.RawVideo.t()
  | Membrane.AAC.t()
  | Membrane.Opus.t()
  | Membrane.MPEGAudio.t()
  | Membrane.RemoteStream.t()
  | Membrane.RawAudio.t()
```

Describes stream formats acceptable on the bin's input and output.

# `stream_format_module`

```elixir
@type stream_format_module() ::
  Membrane.H264
  | Membrane.H265
  | Membrane.VP8
  | Membrane.VP9
  | Membrane.RawVideo
  | Membrane.AAC
  | Membrane.Opus
  | Membrane.MPEGAudio
  | Membrane.RawAudio
```

Describes stream format modules that can be used to define inputs and outputs of the bin.

# `stream_format_resolver`

```elixir
@type stream_format_resolver() :: (stream_format() -&gt;
                               stream_format() | stream_format_module())
```

Describes a function which can be used to provide output format based on the input format.

# `stream_format_tuple`

```elixir
@type stream_format_tuple() :: {stream_format_module(), keyword()}
```

Describes a tuple consisting of a stream format module and its options.

An alternative to `t:Membrane.Transcoder.stream_format/0`.

Allows you to specify some fields of the output stream format, without the need to
set all keys required by the struct.

# `t`

```elixir
@type t() :: %Membrane.Transcoder{
  assumed_input_stream_format: struct() | nil,
  output_stream_format:
    stream_format()
    | stream_format_module()
    | stream_format_tuple()
    | stream_format_resolver(),
  transcoding_policy:
    :always
    | :if_needed
    | :never
    | (stream_format() -&gt; :always | :if_needed | :never)
}
```

Struct containing options for `Membrane.Transcoder`

# `options`

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

Returns description of options available for this module

---

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