# `Membrane.WebRTC.Sink`
[🔗](https://github.com/membraneframework/membrane_webrtc_plugin/blob/v0.26.7/lib/membrane_webrtc/sink.ex#L1)

Membrane Bin that allows sending audio and video tracks via WebRTC.

It sends an SDP offer and expects an answer during initialization and
each time when new tracks are added. For more information about signaling,
see the `signaling` option.

Before connecting pads, each audio and video track has to be negotiated.
Tracks passed via `tracks` option are negotiated during initialization.
You can negotiate more tracks by sending `t:add_tracks/0` notification
and waiting for `t:new_tracks/0` notification reply.

When the tracks are negotiated, pads can be linked. The pad either
has to have a `kind` option set or its id has to match the id of
the track received in `t:new_tracks/0` notification.

## Bin options

Passed via struct `t:Membrane.WebRTC.Sink.t/0`

- `signaling`  

  ```
  Signaling.t() | {:whip, whip_options} | {:websocket, SimpleWebSocketServer.options()}
  ```
  
  ***Required***  
  Signaling channel for passing WebRTC signaling messages (SDP and ICE).
  Either:
  - `Membrane.WebRTC.Signaling` - See its docs for details.
  - `{:whip, options}` - Acts as a WHIP client, see `t:whip_options/0` for details.
  - `{:websocket, options}` - Spawns Membrane.WebRTC.SimpleWebSocketServer,
  see there for details.

- `tracks`  

  ```
  [:audio | :video]
  ```
  
  Default value: `[:audio, :video]`  
  Tracks to be negotiated. By default one audio and one video track
  is negotiated, meaning that at most one audio and one video can be
  sent.

- `video_codec`  

  ```
  :vp8 | :h264 | :h265 | :av1 | [:vp8 | :h264 | :h265 | :av1]
  ```
  
  Default value: `[:vp8, :h264]`  
  Video codecs, that Membrane.WebRTC.Sink will try to negotiatie in SDP
  message exchange. Even if `[:vp8, :h264]` is passed to this option, there
  is a chance, that one of these codecs won't be approved by the second
  WebRTC peer.
  
  After SDP messages exchange, Membrane.WebRTC.Sink will send a parent
  notification `{:negotiated_video_codecs, codecs}` where `codecs` is
  a list of supported codecs.

- `ice_servers`  

  ```
  [ExWebRTC.PeerConnection.Configuration.ice_server()]
  ```
  
  Default value: `[%{urls: "stun:stun.l.google.com:19302"}]`  
  

- `ice_port_range`  

  ```
  Enumerable.t(non_neg_integer())
  ```
  
  Default value: `[0]`  
  

- `ice_ip_filter`  

  ```
  (:inet.ip_address() -> boolean())
  ```
  
  Default value: `&Membrane.WebRTC.Sink.default_ice_ip_filter/1`  
  

- `payload_rtp`  

  ```
  boolean()
  ```
  
  Default value: `true`  
  

## Pads

### `:input`

Accepted formats:
```
%Membrane.H264{alignment: :nalu}
```
```
%Membrane.H265{alignment: :nalu}
```
```
%Membrane.RemoteStream{content_format: Membrane.VP8}
```
```
%Membrane.RemoteStream{content_format: Membrane.RTP}
```
```
Membrane.VP8
```
```
Membrane.Opus
```
```
Membrane.RTP
```

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

- `kind`  

  ```
  :audio | :video | nil
  ```
  
  Default value: `nil`  
  When set, the pad is associated with the first negotiated track
  of the given kind. See the moduledoc for details.

# `add_tracks`

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

Notification that should be sent to the bin to negotiate new tracks.

See the moduledoc for details.

# `input_pad_opts`

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

Options for pad `:input`

# `new_tracks`

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

Notification sent when new tracks are negotiated.

See the moduledoc for details.

# `t`

```elixir
@type t() :: %Membrane.WebRTC.Sink{
  ice_ip_filter: (:inet.ip_address() -&gt; boolean()),
  ice_port_range: Enumerable.t(non_neg_integer()),
  ice_servers: [ExWebRTC.PeerConnection.Configuration.ice_server()],
  payload_rtp: boolean(),
  signaling:
    Membrane.WebRTC.Signaling.t()
    | {:whip, whip_options()}
    | {:websocket, Membrane.WebRTC.SimpleWebSocketServer.options()},
  tracks: [:audio | :video],
  video_codec: :vp8 | :h264 | :h265 | :av1 | [:vp8 | :h264 | :h265 | :av1]
}
```

Struct containing options for `Membrane.WebRTC.Sink`

# `whip_options`

```elixir
@type whip_options() :: [uri: String.t(), token: String.t()]
```

WHIP client options

- `uri` - Address of the WHIP server (HTTP/HTTPS)
- `token` - WHIP token, defaults to an empty string

# `default_ice_ip_filter`

# `options`

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

Returns description of options available for this module

---

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