Skip to content
On this pageOPEN
  1. 01Goal
  2. 02Plain-language concept
  3. 03Interactive diagram
  4. 04Behind the scenes
  5. 05Code walkthrough
  6. 06Do & don't
  7. 07Practice
  8. 08Quick quiz
  9. 09Key takeaways
  10. 10Common errors
LESSON 06Core32 min read

SDP without the fog

Read a real session description line by line: m-lines, codecs, directions, ICE credentials, and fingerprints.

#SDP#offer/answer#codecs#m-line#renegotiation
01

Goal

  • 01Read an SDP offer well enough to know what is being proposed and what will break.
  • 02Understand m-lines, direction attributes, codecs, ICE credentials, and fingerprints.
  • 03Recognize when a change needs renegotiation instead of a track replacement.
02

The concept, plainly

is a text description of a session. The browser generates it from the peer connection's transceivers, codecs, and transport state. An offer proposes a session; an answer accepts or narrows it. The signaling channel carries these descriptions, but SDP does not itself create a network path. That is ICE's job.

An `m=` line defines one media section, in order. The order matters because `sdpMLineIndex` and the transceiver list refer to it. A typical offer has `m=audio` and `m=video`. Each section contains a payload type list, direction, codec parameters, and possibly ICE credentials and a DTLS fingerprint. Bundling commonly puts all media on one transport, but the m-lines still exist.

Direction attributes explain who sends what: `sendrecv`, `sendonly`, `recvonly`, or `inactive`. A video element can be black even though the connection is connected if the negotiated direction is `recvonly` on both sides or `inactive`. When you add a track after an offer, the existing transceiver direction may need to change, which requires negotiation.

Codec lines use `a=rtpmap:<payload> <name>/<clock>/<channels>` and `a=fmtp` for parameters. Browsers offer multiple codecs and choose based on the answer and `setCodecPreferences`. Do not assume the first payload type is the one selected. For debugging, look at the actual `RTCRtpSender.getParameters()` and the receiver's stats, not only the SDP text.

ICE credentials (`a=ice-ufrag`, `a=ice-pwd`) and the DTLS fingerprint (`a=fingerprint`) bind the signaling description to the transport that will be built. The fingerprint is how the peer verifies the certificate presented during the DTLS handshake. If an intermediary rewrites SDP fingerprints, the handshake fails even though the network path is fine.

Renegotiation is needed when the session shape changes: adding a track where no suitable transceiver exists, changing direction, adding a data channel after the initial negotiation, or restarting ICE. Replacing a live track of the same kind usually does not need it. SDP gets long, but the subset that matters for most incidents is small: m-lines, directions, codecs, ICE, and fingerprint.

03

See it move

PLAY / PAUSE / STEP

Interactive diagram

Reading an offer from the outside in

serializem-linesofferanswerBROWSEROfferlocal descriptionPROCESSSession blockv= o= s= t=PROCESSm= sectionsaudio · video · dataPROCESSDirectionsendrecv / recvonlyPROCESSCodecsrtpmap + fmtpNETWORKICE credentialsufrag + pwdPROCESSDTLS fingerprintbinds SDP to certificatePEERAnsweraccepts or narrowsSTORAGERemote descriptionsession becomes usable
STEP 01 / 08header

Session lines establish context

The v= line is the version, o= identifies the session origin, and s= is a name. Browser SDP mostly hides these details from you, but they are the header before the meaningful media sections.

Start with the m-lines and directions, then inspect codecs and transport credentials. The order is the contract.

04

Behind the scenes

01

Transceivers generate SDP

A transceiver is a sender/receiver pair with a direction and a mid. addTrack can reuse a compatible transceiver or create a new one depending on the connection state. When SDP is generated, each transceiver becomes an m-line. That is why a track added after negotiation may need a new offer: the contract has to be reissued with the new section or direction.

02

The answer is not a mirror

Browsers offer many codecs and several RTP header extensions. The answer selects what the responder supports and may choose a lower-cost codec. It can also reject a section or mark it inactive. If you compare offers by string equality, you will misread a perfectly valid answer.

03

SDP and ICE candidates are separate

A non-trickle exchange waits for gathering and puts candidates into the SDP. A trickle exchange sends them as separate signaling messages and may leave the initial SDP with no candidates. Both are valid. The mistake is assuming an SDP with no candidate lines has failed; it may simply be trickling.

05

Code walkthrough

COPY-READY

You rarely need a full SDP parser. Extract the m-lines, directions, codecs, and transport facts for diagnostics.

lib/sdp-summary.ts
export function summarizeSdp(sdp: string) {
const lines = sdp.split(/\r?\n/);
const sections = [] as Array<{
kind: string;
direction: string;
codecs: string[];
mid?: string;
}>;
let current: (typeof sections)[number] | undefined;
for (const line of lines) {
if (line.startsWith("m=")) {
const [kind, , , ...payloads] = line.slice(2).split(" ");
current = { kind: kind ?? "unknown", direction: "sendrecv", codecs: payloads };
sections.push(current);
} else if (current && line.startsWith("a=mid:")) {
current.mid = line.slice(6);
} else if (current && /^a=(sendrecv|sendonly|recvonly|inactive)$/.test(line)) {
current.direction = line.slice(2);
} else if (current && line.startsWith("a=rtpmap:")) {
current.codecs.push(line.slice(9));
}
}
return {
sections,
iceUfrag: lines.find((line) => line.startsWith("a=ice-ufrag:"))?.slice(12),
fingerprint: lines.find((line) => line.startsWith("a=fingerprint:"))?.slice(14),
candidates: lines.filter((line) => line.startsWith("a=candidate:")).length,
};
}
06

Do and don't

Do

  • Check directions before codecs

    If both sides are recvonly or a section is inactive, no codec change will produce media. Read the direction first.

  • Keep the complete SDP

    Do not trim lines you do not recognize when relaying manually. Fingerprints, ICE credentials, and extensions are all load-bearing.

  • Log the negotiated sections

    A compact summary of m-lines, mids, directions, and candidate counts makes signaling logs diagnosable.

Don't

  • Don't hand-edit SDP without a reason

    Removing a fingerprint or changing a payload type can break the transport or produce silent media. Use browser APIs for preferences first.

  • Don't assume offer order equals track order

    The mids and transceiver mapping are authoritative. A renegotiation can add or recycle sections.

  • Don't treat an answer as a failed offer

    An answer with fewer codecs or an inactive section may be correct. Validate the session, not string equality.

07

Practice

Hands-on lab

Read your own offer

Open manual signaling in the 1:1 lab and create an offer bundle. Inspect the SDP in the textarea or copy it into a scratch file.

  1. 1Count the m= lines. Which one is audio, video, or application?
  2. 2Find each a=mid, direction, ice-ufrag, and fingerprint.
  3. 3List the rtpmap codecs offered for video and compare them with what the answer keeps.
  4. 4Reload and repeat. Notice which lines change every session and which stay stable.
Generate real SDP in the lab

Solo? Loopback generates a live SDP internally; the lab's peer-event log shows when the offer and answer are created.

08

Quick quiz

Knowledge check

0 of 4 answered

0%
  1. 01

    What does one m= line represent?

  2. 02

    A connection is connected but the remote video is black. Which SDP attribute should you inspect first?

  3. 03

    What is the DTLS fingerprint in SDP used for?

  4. 04

    When is renegotiation required?

Pick one answer per question to see instant feedback.
09

Key takeaways

  1. SDP is a contract: m-lines, directions, codecs, ICE credentials, and fingerprints are the parts that matter.01
  2. The answer can narrow or reject an offer; string equality is the wrong test.02
  3. Connected plus no video is often a direction or track problem, not a codec problem.03
  4. Renegotiation is for shape changes; replaceTrack handles same-kind source swaps.04
10

Common errors and fixes

Terms in this lesson

Done with this lesson?

Mark it complete, then keep the thread.