Start · Sprachen · JavaScript · Referenz · RTCOutboundRtpStreamStats.scalabilityMode

RTCOutboundRtpStreamStats.scalabilityMode

Eigenschaft

Liefert den Skalierungsmodus (SVC), z. B. <code>"L1T3"</code>, mit dem ein ausgehender Video-RTP-Stream kodiert wird. Ist kein Modus konfiguriert, fehlt die Eigenschaft.

seit JavaScript WebRTC-SVC; Chromium 111+, in anderen Browsern ein Kategorie: webapi

Signatur

RTCOutboundRtpStreamStats.scalabilityMode

Beschreibung

Die schreibgeschützte Eigenschaft scalabilityMode eines RTCOutboundRtpStreamStats-Objekts gibt an, mit welchem Skalierungsmodus (Scalable Video Coding, SVC) der Encoder den ausgehenden Video-Stream erzeugt. Der Wert ist eine Zeichenkette aus der Spezifikation WebRTC-SVC, etwa "L1T2", "L1T3", "L3T3", "L2T2_KEY" oder "S2T1".

Aufbau des Bezeichners: L steht für die Anzahl der räumlichen Schichten (Spatial Layers) mit gegenseitiger Abhängigkeit und S für unabhängige räumliche Schichten (Simulcast-ähnlich innerhalb eines Streams). T gibt die Anzahl der zeitlichen Schichten (Temporal Layers) an. Zusätze wie _KEY oder _KEY_SHIFT beschreiben, wie die Schichten über Keyframes voneinander abhängen. "L1T1" heißt also: keine Skalierung.

Gesetzt wird der Modus über sendEncodings[].scalabilityMode bei RTCPeerConnection.addTransceiver() oder später über RTCRtpSender.setParameters(). Welche Modi ein Codec unterstützt, verrät RTCRtpSender.getCapabilities("video").codecs[].scalabilityModes. Die Statistik-Eigenschaft zeigt, welcher Modus tatsächlich aktiv ist. Das ist nützlich, um die Konfiguration zu prüfen, Fehler in SFU-Setups zu finden (Selective Forwarding Unit) oder die Qualität zu überwachen.

Rückgabewert

Typ
string | undefined
Beschreibung
Der aktive Skalierungsmodus als Zeichenkette (z. B. "L1T3"). undefined, wenn kein Modus konfiguriert ist, der Stream kein Video ist oder der Browser die Eigenschaft nicht unterstützt.

Beispiele

Skalierungsmodus aus getStats() auslesen

const logScalabilityModes = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'outbound-rtp' && stats.kind === 'video') {
      console.log(`SSRC ${stats.ssrc}: ${stats.scalabilityMode ?? 'kein SVC konfiguriert'}`);
    }
  });
};

// pc ist eine bestehende, verbundene RTCPeerConnection
await logScalabilityModes(pc);
SSRC 1234567890: L1T3

SVC-Modus setzen und Übernahme überprüfen

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();
const pc = new RTCPeerConnection();

// Prüfen, ob ein Codec L1T3 unterstützt
const { codecs } = RTCRtpSender.getCapabilities('video');
const supportsL1T3 = codecs.some((c) => c.scalabilityModes?.includes('L1T3'));

const transceiver = pc.addTransceiver(track, {
  direction: 'sendonly',
  sendEncodings: [supportsL1T3 ? { scalabilityMode: 'L1T3' } : {}]
});

// ... Signalisierung / Verbindungsaufbau ...

const stats = await transceiver.sender.getStats();
for (const s of stats.values()) {
  if (s.type === 'outbound-rtp') {
    console.log('Aktiver Modus:', s.scalabilityMode);
  }
}
Aktiver Modus: L1T3

Moduswechsel zur Laufzeit überwachen

const watchScalabilityMode = (sender, intervalMs = 2000) => {
  let last;
  const timer = setInterval(async () => {
    const stats = await sender.getStats();
    for (const s of stats.values()) {
      if (s.type !== 'outbound-rtp') continue;
      if (s.scalabilityMode !== last) {
        console.log(`Modus geändert: ${last ?? '–'} → ${s.scalabilityMode ?? '–'}`);
        last = s.scalabilityMode;
      }
    }
  }, intervalMs);
  return () => clearInterval(timer);
};

const stop = watchScalabilityMode(pc.getSenders()[0]);

// Modus zur Laufzeit ändern
const params = pc.getSenders()[0].getParameters();
params.encodings[0].scalabilityMode = 'L1T2';
await pc.getSenders()[0].setParameters(params);
Modus geändert: – → L1T3 Modus geändert: L1T3 → L1T2

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Die Eigenschaft ist nicht Baseline. Chromium-basierte Browser unterstützen sie (ab etwa Version 111). In Firefox und Safari fehlt sie teilweise oder ganz. Prüfe deshalb immer auf undefined, zum Beispiel mit ?? 'L1T1' oder einem Hinweistext.
  • Die Eigenschaft gibt es nur für type === "outbound-rtp" mit kind === "video". Audio-Streams haben keinen Skalierungsmodus.
  • Nicht jeder Codec unterstützt jeden Modus. VP8 kennt nur temporale Schichten (L1T*). Räumliche Schichten (L2/L3) gibt es in der Regel nur bei VP9 und AV1. Ein nicht unterstützter Modus in addTransceiver() oder setParameters() löst eine OperationError aus oder wird ignoriert.
  • Der gemeldete Wert kann von der Anforderung abweichen, etwa wenn der Encoder (zum Beispiel ein Hardware-Encoder) auf einen anderen Modus zurückfällt. Verlass dich deshalb auf die Statistik und nicht auf die gesetzten Parameter.
  • Bei Simulcast mit mehreren encodings gibt es für jede Encoding ein eigenes outbound-rtp-Objekt mit eigenem scalabilityMode. Zuordnen lassen sie sich über rid.
  • Häufige getStats()-Aufrufe kosten Rechenzeit. Für die Überwachung reichen Intervalle von 1 bis 5 Sekunden.