Start · Sprachen · JavaScript · Referenz · RTCSessionDescription.sdp

RTCSessionDescription.sdp

Eigenschaft

Schreibgeschützter String mit der vollständigen SDP-Beschreibung (Session Description Protocol) einer WebRTC-Sitzung, also eines Angebots (Offer) oder einer Antwort (Answer).

seit JavaScript Baseline: alle modernen Browser Kategorie: webapi

Signatur

RTCSessionDescription.sdp

Beschreibung

Die Eigenschaft sdp eines RTCSessionDescription-Objekts enthält die Sitzungsbeschreibung im Textformat des Session Description Protocol (RFC 8866). Darin stehen unter anderem die Medienspuren (m=-Zeilen), die ausgehandelten Codecs (a=rtpmap), ICE-Zugangsdaten (a=ice-ufrag, a=ice-pwd), DTLS-Fingerabdrücke (a=fingerprint) und gegebenenfalls schon gesammelte ICE-Kandidaten.

In der Praxis braucht man sdp vor allem beim Signaling: Nach createOffer() oder createAnswer() wird die Beschreibung, meist zusammen mit type, über einen eigenen Kanal (WebSocket, HTTP, …) an die Gegenstelle geschickt. Diese übergibt sie dann an setRemoteDescription(). Die Zeichenkette ist mehrzeilig, die Zeilen sind durch \r\n getrennt.

Die Eigenschaft ist schreibgeschützt. Wer die SDP ändern will (sogenanntes „SDP-Munging“, z. B. um die Codec-Reihenfolge anzupassen), erzeugt ein neues Beschreibungsobjekt aus { type, sdp }. Seit einiger Zeit geben createOffer()/createAnswer() meist ein einfaches Objekt mit derselben Struktur zurück. Ein Aufruf von new RTCSessionDescription() ist heute in der Regel nicht mehr nötig.

Rückgabewert

Typ
string
Beschreibung
Die SDP-Beschreibung als mehrzeiliger String (Zeilenende \r\n). Ist leer (""), wenn das Objekt ohne sdp erzeugt wurde, z. B. bei type: "rollback".

Beispiele

Angebot erzeugen und SDP an den Signaling-Server senden

const pc = new RTCPeerConnection();
pc.addTransceiver('audio');

const socket = new WebSocket('wss://signal.example.com');

socket.addEventListener('open', async () => {
  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);

  // Nur type und sdp werden übertragen
  const { type, sdp } = pc.localDescription;
  socket.send(JSON.stringify({ type, sdp }));
  console.log(sdp.split('\r\n')[0]);
});
v=0

Entfernte Beschreibung empfangen und beantworten

const pc = new RTCPeerConnection();
const socket = new WebSocket('wss://signal.example.com');

socket.addEventListener('message', async (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type !== 'offer') return;

  await pc.setRemoteDescription({ type: msg.type, sdp: msg.sdp });
  const answer = await pc.createAnswer();
  await pc.setLocalDescription(answer);

  socket.send(JSON.stringify({
    type: pc.localDescription.type,
    sdp: pc.localDescription.sdp
  }));
});

Ausgehandelte Codecs aus der SDP auslesen

const pc = new RTCPeerConnection();
pc.addTransceiver('video');

const offer = await pc.createOffer();

const codecs = offer.sdp
  .split('\r\n')
  .filter((line) => line.startsWith('a=rtpmap:'))
  .map((line) => line.split(' ')[1]);

console.log(codecs.slice(0, 3));
[ 'VP8/90000', 'rtx/90000', 'VP9/90000' ] // je nach Browser unterschiedlich

SDP ändern (Munging): neues Objekt statt Zuweisung

const pc = new RTCPeerConnection();
pc.addTransceiver('audio');

const offer = await pc.createOffer();

// Fehler: offer.sdp = ... hat bei RTCSessionDescription keine Wirkung.
// Besser ein neues Objekt anlegen:
const mungedSdp = offer.sdp.replace(
  /a=fmtp:(\d+) (.*)/,
  'a=fmtp:$1 $2;stereo=1'
);

await pc.setLocalDescription({ type: offer.type, sdp: mungedSdp });
console.log(pc.localDescription.sdp.includes('stereo=1'));
true

// Wichtig · Fallstricke

  • Schreibgeschützt: Bei echten RTCSessionDescription-Instanzen bleibt eine Zuweisung an sdp ohne Wirkung, im Strict Mode wirft sie einen TypeError. Für Änderungen immer ein neues { type, sdp }-Objekt übergeben.
  • SDP-Munging ist riskant: Die Spezifikation erlaubt nur wenige Änderungen zwischen createOffer() und setLocalDescription(). Unerlaubte Änderungen können eine InvalidModificationError oder OperationError auslösen. Robuster ist die Codec-Steuerung per RTCRtpTransceiver.setCodecPreferences().
  • Datenschutz/Sicherheit: Die SDP kann ICE-Kandidaten mit lokalen oder öffentlichen IP-Adressen enthalten, außerdem ICE-Zugangsdaten. Sie sollte deshalb nur über einen verschlüsselten Signaling-Kanal (WSS/HTTPS) übertragen und nicht ungefiltert protokolliert werden. Moderne Browser verbergen lokale IP-Adressen mit mDNS-Namen (*.local).
  • Zeilenenden: SDP verwendet \r\n. Wer die Zeilen beim Transport oder Bearbeiten in \n umwandelt, riskiert Parse-Fehler in manchen Implementierungen.
  • Trickle ICE: localDescription.sdp enthält erst nach dem Sammeln der Kandidaten (iceGatheringState === "complete") alle Kandidaten. Die SDP direkt nach createOffer() enthält in der Regel noch keine.
  • Der Aufbau der SDP (Codec-Reihenfolge, Erweiterungen) unterscheidet sich je nach Browser. Keine feste Struktur annehmen.