One SDP media section (m= line) and its media-level attributes.
What problem this solves
A WebRTC offer contains one or more m= sections (audio, video, application).
Each section lists ports, transports, payload types, and dozens of a=
attributes for ICE, codecs, and SSRC metadata. This struct holds one parsed
media block so SFU and gateway code can read or patch a single stream without
reparsing the whole session.
Each m= block describes a single media stream: type (audio, video,
application), port, transport protocol, and format list. Following a=
lines carry ICE credentials, DTLS fingerprints, codec mappings, SSRC
metadata, and WebRTC-specific extensions. The parser promotes well-known
attributes into typed fields; anything else remains in :attributes.
RFCs
Summary
Types
Unpromoted media-level attribute as {name, value} or {name, true}.
Media direction from a=sendrecv, a=sendonly, a=recvonly, or a=inactive.
Transport protocol from the m= line.
Media description fields for one m= section.
Media kind from the m= line; known atoms or the raw string.
Types
Unpromoted media-level attribute as {name, value} or {name, true}.
@type direction() :: :sendrecv | :sendonly | :recvonly | :inactive
Media direction from a=sendrecv, a=sendonly, a=recvonly, or a=inactive.
@type protocol() :: :UDP_TLS_RTP_SAVPF | :RTP_SAVPF | :UDP_DTLS_SCTP | String.t()
Transport protocol from the m= line.
Known WebRTC values include :UDP_TLS_RTP_SAVPF (DTLS-SRTP), :RTP_SAVPF,
and :UDP_DTLS_SCTP (data channels). Other strings pass through unchanged.
@type t() :: %XMediaLib.SDP.Media{ attributes: [attribute()], candidates: [XMediaLib.SDP.Candidate.t()], codecs: [XMediaLib.SDP.Codec.t()], connection: XMediaLib.SDP.Connection.t() | nil, dcmap: [XMediaLib.SDP.Dcmap.t()], direction: direction() | nil, extmaps: [XMediaLib.SDP.Extmap.t()], fingerprint: XMediaLib.SDP.Fingerprint.t() | nil, fmtp: [XMediaLib.SDP.Fmtp.t()], formats: [String.t()], ice_pwd: String.t() | nil, ice_ufrag: String.t() | nil, max_message_size: non_neg_integer() | nil, mid: String.t() | nil, port: non_neg_integer() | nil, protocol: protocol() | nil, rtcp_fb: [XMediaLib.SDP.RtcpFb.t()], rtcp_mux: boolean(), sctp_port: non_neg_integer() | nil, setup: :active | :passive | :actpass | nil, ssrcs: [XMediaLib.SDP.Ssrc.t()], type: type() | nil }
Media description fields for one m= section.
Fields
:type- media kind (:audio,:video,:application, or string):port- port number from them=line (0means rejected/hold):protocol- transport, e.g.:UDP_TLS_RTP_SAVPF:formats- payload type or format tokens from them=line:connection- optional media-levelc=override:ice_ufrag- ICE username fragment (a=ice-ufrag):ice_pwd- ICE password (a=ice-pwd):candidates- parseda=candidatelines:fingerprint- DTLS certificate fingerprint (a=fingerprint):setup- DTLS role hint (a=setup::active,:passive, or:actpass):mid- media identification tag for BUNDLE (a=mid):direction- send/receive direction attribute:rtcp_mux- true whena=rtcp-muxis present:codecs- dynamic payload mappings froma=rtpmap:fmtp- format parameters froma=fmtp:rtcp_fb- RTCP feedback tokens froma=rtcp-fb:extmaps- RTP header extension maps froma=extmap:ssrcs- SSRC attributes froma=ssrc:sctp_port- SCTP port for data channels (a=sctp-port):max_message_size- SCTP max message size (a=max-message-size):dcmap- data channel maps froma=dcmap:attributes- other media-levela=lines
@type type() :: :audio | :video | :application | String.t()
Media kind from the m= line; known atoms or the raw string.