Field parsers for individual SDP line values.
What problem this solves
Full SDP documents are long, but tests and tools often need to parse one a=
or c= value in isolation. Each helper maps the payload after a line prefix
into a typed struct or attribute tuple used by XMediaLib.SDP.Parser. Keeping
them separate avoids duplicating grammar rules across session and media
sections.
These pure functions turn the payload after the line prefix (o=, c=,
m=, or the value portion of a=) into typed structs or attribute tuples.
XMediaLib.SDP.Parser calls them while walking a full session description;
tests and tools may call them directly when only one line needs parsing.
Promoted WebRTC attributes (ICE, fingerprint, rtpmap, etc.) update
%XMediaLib.SDP.Media{} fields. Unrecognized media attributes accumulate in
:attributes as {name, value} or {name, true}.
RFCs
Summary
Functions
Parses an ICE candidate attribute value into %XMediaLib.SDP.Candidate{}.
Parses a c= value (without the c= prefix) into %XMediaLib.SDP.Connection{}.
Parses an a=group: value (after group:) into %XMediaLib.SDP.Group{}.
Applies one media-level a= attribute to %XMediaLib.SDP.Media{}.
Parses an m= value (without the m= prefix) into a new %XMediaLib.SDP.Media{}.
Parses an o= value (without the o= prefix) into %XMediaLib.SDP.Origin{}.
Parses a session-level a= attribute into {name, value}.
Parses a t= value (without the t= prefix) into %XMediaLib.SDP.Time{}.
Functions
@spec parse_candidate(String.t()) :: XMediaLib.SDP.Candidate.t()
Parses an ICE candidate attribute value into %XMediaLib.SDP.Candidate{}.
Examples
iex> cand = "1 1 udp 2130706431 192.0.2.1 5000 typ host"
iex> XMediaLib.SDP.Parser.Helpers.parse_candidate(cand)
%XMediaLib.SDP.Candidate{foundation: "1", component_id: 1, transport: "udp",
priority: 2130706431, ip: "192.0.2.1", port: 5000, type: "host", rest: nil}
@spec parse_connection(String.t()) :: XMediaLib.SDP.Connection.t()
Parses a c= value (without the c= prefix) into %XMediaLib.SDP.Connection{}.
Examples
iex> XMediaLib.SDP.Parser.Helpers.parse_connection("IN IP4 192.0.2.1")
%XMediaLib.SDP.Connection{net_type: "IN", addr_type: "IP4", address: "192.0.2.1"}
@spec parse_group(String.t()) :: XMediaLib.SDP.Group.t()
Parses an a=group: value (after group:) into %XMediaLib.SDP.Group{}.
Examples
iex> XMediaLib.SDP.Parser.Helpers.parse_group("BUNDLE 0 1")
%XMediaLib.SDP.Group{semantics: "BUNDLE", mids: ["0", "1"]}
@spec parse_media_attribute(String.t(), XMediaLib.SDP.Media.t()) :: XMediaLib.SDP.Media.t()
Applies one media-level a= attribute to %XMediaLib.SDP.Media{}.
attr_line is the full attribute body after a= (e.g. mid:0 or
candidate:...). Known attributes update typed fields; others append to
:attributes.
Examples
iex> media = %XMediaLib.SDP.Media{type: :audio, port: 9}
iex> updated = XMediaLib.SDP.Parser.Helpers.parse_media_attribute("mid:0", media)
iex> updated.mid
"0"
@spec parse_media_header(String.t()) :: XMediaLib.SDP.Media.t()
Parses an m= value (without the m= prefix) into a new %XMediaLib.SDP.Media{}.
Known media types and transports are normalized to atoms; others remain strings.
Examples
iex> media = XMediaLib.SDP.Parser.Helpers.parse_media_header("audio 9 UDP/TLS/RTP/SAVPF 111")
iex> {media.type, media.port, media.protocol, media.formats}
{:audio, 9, :UDP_TLS_RTP_SAVPF, ["111"]}
@spec parse_origin(String.t()) :: XMediaLib.SDP.Origin.t()
Parses an o= value (without the o= prefix) into %XMediaLib.SDP.Origin{}.
Examples
iex> XMediaLib.SDP.Parser.Helpers.parse_origin("- 0 0 IN IP4 127.0.0.1")
%XMediaLib.SDP.Origin{username: "-", session_id: "0", session_version: "0",
net_type: "IN", addr_type: "IP4", unicast_address: "127.0.0.1"}
Parses a session-level a= attribute into {name, value}.
Flag attributes without a colon value return {name, true}.
Examples
iex> XMediaLib.SDP.Parser.Helpers.parse_session_attribute("ice-lite")
{"ice-lite", true}
iex> XMediaLib.SDP.Parser.Helpers.parse_session_attribute("msid-semantic: WMS stream")
{"msid-semantic", " WMS stream"}
@spec parse_time(String.t()) :: XMediaLib.SDP.Time.t()
Parses a t= value (without the t= prefix) into %XMediaLib.SDP.Time{}.
Examples
iex> XMediaLib.SDP.Parser.Helpers.parse_time("0 0")
%XMediaLib.SDP.Time{start: 0, stop: 0}