# `XMediaLib.SDP.Parser`
[🔗](https://github.com/Lazarus404/xmedialib/blob/main/lib/sdp/parser.ex#L25)

Line-oriented SDP parser.

## What problem this solves

Incoming SDP arrives as a multiline string from SIP INVITE bodies or trickle
ICE updates. Turning that into structs requires walking session and media lines
in order and promoting WebRTC attributes into typed fields. This module is the
line-oriented parser behind `XMediaLib.SDP.parse/1`.

Walks CRLF- or LF-separated lines, building `%XMediaLib.SDP{}` and nested
media structs. Session lines (`v=`, `o=`, `s=`, `c=`, `t=`, session `a=`)
update the root struct. Each `m=` starts a new `%XMediaLib.SDP.Media{}`;
following lines until the next `m=` belong to that section.

Well-known WebRTC attributes are promoted to typed fields via
`XMediaLib.SDP.Parser.Helpers`. By default, unrecognized non-`a=` lines are
skipped; `:strict` mode surfaces them as errors instead.

Prefer `XMediaLib.SDP.parse/1` at application boundaries; use this module
when you need parser-specific options or tests.

## RFCs

* [RFC 4566](https://www.rfc-editor.org/rfc/rfc4566) - SDP grammar
* [RFC 8866](https://www.rfc-editor.org/rfc/rfc8866) - SDP (current)
* [RFC 8445](https://www.rfc-editor.org/rfc/rfc8445) - ICE attributes
* [RFC 8122](https://www.rfc-editor.org/rfc/rfc8122) - DTLS fingerprint/setup
* [RFC 8841](https://www.rfc-editor.org/rfc/rfc8841) - SCTP/data channel attributes

# `parse_result`

```elixir
@type parse_result() :: {:ok, XMediaLib.SDP.t()} | {:error, term()}
```

SDP parse result: `{:ok, %SDP{}}` or `{:error, reason}`.

# `parse`

```elixir
@spec parse(binary()) :: parse_result()
```

Parses an SDP binary into `%XMediaLib.SDP{}`.

Equivalent to `parse/2` with default options (non-strict).

## Examples

    iex> {:ok, sdp} = XMediaLib.SDP.Parser.parse("v=0\r\no=- 0 0 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n")
    iex> sdp.version
    0

# `parse`

```elixir
@spec parse(
  binary(),
  keyword()
) :: parse_result()
```

Parses an SDP binary with options.

Options:

  * `:strict` - when `true`, unknown non-`a=` lines return
    `{:error, {:unsupported_line, line}}` instead of being skipped

Malformed numeric fields or invalid promoted attributes raise internally
and surface as `{:error, :parse_failed}`.

## Examples

    iex> raw = "v=0\r\no=- 0 0 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\nz=bad\r\n"
    iex> {:error, {:unsupported_line, "z=bad"}} = XMediaLib.SDP.Parser.parse(raw, strict: true)

---

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