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

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

It expects an SDP offer to be sent by the other peer at the beginning
of playback and each time new tracks are added. For more information
about signaling, see the `signaling` option.

Pads connected immediately when the bin is created
(in the same spec `t:Membrane.ChildrenSpec.t/0`) need to have the `kind`
option set to `:audio` or `:video`. Each of those pads will be associated
with the first WebRTC track of the given kind that arrives.

When a WebRTC tracks arrive and there's no pad to link them to,
the `t:new_tracks/0` notification is sent. Then, the corresponding pads
should be linked - the id of each pad should match one of the track ids.

## Bin options

Passed via struct `t:Membrane.WebRTC.Source.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}` - Starts a WHIP server, see `t:whip_options/0` for details.
  - `{:websocket, options}` - Spawns Membrane.WebRTC.SimpleWebSocketServer,
  see there for details.

- `allowed_video_codecs`  

  ```
  :vp8 | :h264 | :h265 | :av1 | [:vp8 | :h264 | :h265 | :av1]
  ```
  
  Default value: `:vp8`  
  Specifies, which video codecs can be accepted by the source during the SDP
  negotiaion.
  
  Either `:vp8`, `:h264`, `:h265` or a list containing these options.
  
  Event if it is set to `[:h264, :vp8]`, the source will negotiate at most
  one video codec. Negotiated codec can be deduced from
  `{:negotiated_video_codecs, codecs}` notification sent to the parent.
  
  If prefer to receive one video codec over another, but you are still able
  to handle both of them, use `:preferred_video_codec` option.
  
  By default only `:vp8`.

- `preferred_video_codec`  

  ```
  :vp8 | :h264 | :h265
  ```
  
  Default value: `:vp8`  
  Specyfies, which video codec will be preferred by the source, if both of
  them will be available.
  
  Usage of this option makes sense only if there are at least 2 codecs
  specified in the `:allowed_video_codecs` option.
  
  Defaults to `:vp8`.

- `keyframe_interval`  

  ```
  Membrane.Time.t() | nil
  ```
  
  Default value: `nil`  
  If set, a keyframe will be requested as often as specified on each video
  track.

- `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.Source.default_ice_ip_filter/1`  
  

- `depayload_rtp`  

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

- `sdp_candidates_timeout`  

  ```
  Membrane.Time.t()
  ```
  
  Default value: `1000000000`  
  

## Pads

### `:output`

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

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

- `kind`  

  ```
  any
  ```
  
  Default value: `nil`  
  

# `new_tracks`

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

Notification sent when new tracks arrive.

See moduledoc for details.

# `output_pad_opts`

```elixir
@type output_pad_opts() :: [{:kind, any()}]
```

Options for pad `:output`

# `t`

```elixir
@type t() :: %Membrane.WebRTC.Source{
  allowed_video_codecs:
    :vp8 | :h264 | :h265 | :av1 | [:vp8 | :h264 | :h265 | :av1],
  depayload_rtp: boolean(),
  ice_ip_filter: (:inet.ip_address() -&gt; boolean()),
  ice_port_range: Enumerable.t(non_neg_integer()),
  ice_servers: [ExWebRTC.PeerConnection.Configuration.ice_server()],
  keyframe_interval: Membrane.Time.t() | nil,
  preferred_video_codec: :vp8 | :h264 | :h265,
  sdp_candidates_timeout: Membrane.Time.t(),
  signaling:
    Membrane.WebRTC.Signaling.t()
    | {:whip, whip_options()}
    | {:websocket, Membrane.WebRTC.SimpleWebSocketServer.options()}
}
```

Struct containing options for `Membrane.WebRTC.Source`

# `whip_options`

```elixir
@type whip_options() :: [
  {:token, String.t() | (String.t() -&gt; boolean())}
  | {:serve_static, String.t()}
  | {atom(), term()}
]
```

Options for WHIP server input.

The server accepts a single connection and the stream is received by this source. The options are:

- `token` - either expected WHIP token or a function returning true if the token is valid, otherwise false
- `serve_static` - make WHIP server also serve static content, such as an HTML page under `/static` endpoint
- Any of `t:Bandit.options/0` - in particular `ip` and `port`

To handle multiple connections and have more control over the server, see `Membrane.WebRTC.WhipServer`.

# `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*
