Start · Sprachen · JavaScript · Referenz · RTCInboundRtpStreamStats.framesAssembledFromMultiplePackets

RTCInboundRtpStreamStats.framesAssembledFromMultiplePackets

Eigenschaft

Zählt die korrekt decodierten Video-Frames eines eingehenden RTP-Streams, die aus mehr als einem RTP-Paket zusammengesetzt wurden.

seit JavaScript WebRTC Statistics (Chromium-basierte Browser); nic Kategorie: webapi

Signatur

RTCInboundRtpStreamStats.framesAssembledFromMultiplePackets

Beschreibung

Die Eigenschaft framesAssembledFromMultiplePackets eines RTCInboundRtpStreamStats-Objekts (Statistiktyp "inbound-rtp") gibt an, wie viele korrekt decodierte Frames dieses RTP-Streams aus mehr als einem RTP-Paket zusammengesetzt werden mussten. Der Wert ist ein fortlaufender Zähler, der seit Beginn des Streams nur steigt.

Frames, die in ein einzelnes Paket passen (typisch bei kleinen Delta-Frames mit niedriger Auflösung), werden nicht mitgezählt. Große Frames – etwa Keyframes oder hochaufgelöstes Video – werden dagegen auf mehrere Pakete verteilt und müssen vom Empfänger wieder zusammengesetzt werden. Genau diese Frames erfasst der Zähler.

Seine eigentliche Stärke spielt der Wert im Zusammenspiel mit totalAssemblyTime aus: Teilt man totalAssemblyTime durch framesAssembledFromMultiplePackets, erhält man die durchschnittliche Zeit zwischen dem Eintreffen des ersten und des letzten Pakets eines Frames. So lassen sich Netzwerk-Jitter, Paketverzögerungen und Engpässe beim Empfang diagnostizieren.

Die Eigenschaft ist nur für Video-Streams definiert (kind === "video"). Bei Audio-Streams fehlt sie.

Rückgabewert

Typ
number | undefined
Beschreibung
Ganzzahliger, monoton steigender Zähler (unsigned long) der aus mehreren Paketen zusammengesetzten, erfolgreich decodierten Frames. undefined bei Audio-Streams oder in Browsern, die die Kennzahl nicht unterstützen.

Beispiele

Zähler aus den Empfangsstatistiken auslesen

// pc ist eine verbundene RTCPeerConnection mit eingehendem Video
const logAssembledFrames = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'inbound-rtp' && stats.kind === 'video') {
      console.log(
        `Frames aus mehreren Paketen: ${stats.framesAssembledFromMultiplePackets ?? 'nicht verfügbar'}`
      );
    }
  });
};

await logAssembledFrames(pc);
Frames aus mehreren Paketen: 1834

Durchschnittliche Zusammensetzungszeit pro Frame berechnen

const getAverageAssemblyTime = async (receiver) => {
  const report = await receiver.getStats();
  for (const stats of report.values()) {
    if (stats.type !== 'inbound-rtp') continue;
    const { framesAssembledFromMultiplePackets: frames, totalAssemblyTime } = stats;
    if (!frames || totalAssemblyTime === undefined) return null;
    // totalAssemblyTime ist in Sekunden angegeben
    return (totalAssemblyTime / frames) * 1000;
  }
  return null;
};

const [videoReceiver] = pc.getReceivers().filter((r) => r.track.kind === 'video');
const avgMs = await getAverageAssemblyTime(videoReceiver);
console.log(avgMs !== null ? `Ø Zusammensetzung: ${avgMs.toFixed(2)} ms` : 'Keine Daten');
Ø Zusammensetzung: 3.47 ms

Intervall-Werte (Delta) statt Gesamtsumme überwachen

let previous = null;

const monitor = setInterval(async () => {
  const report = await pc.getStats();
  const video = [...report.values()].find(
    (s) => s.type === 'inbound-rtp' && s.kind === 'video'
  );
  if (!video || video.framesAssembledFromMultiplePackets === undefined) return;

  if (previous) {
    const frames = video.framesAssembledFromMultiplePackets - previous.frames;
    const time = video.totalAssemblyTime - previous.time;
    const avg = frames > 0 ? ((time / frames) * 1000).toFixed(2) : '–';
    console.log(`Letzte Sekunde: ${frames} Frames, Ø ${avg} ms`);
  }
  previous = {
    frames: video.framesAssembledFromMultiplePackets,
    time: video.totalAssemblyTime,
  };
}, 1000);

// Später beenden: clearInterval(monitor);
Letzte Sekunde: 28 Frames, Ø 2.91 ms

// Wichtig · Fallstricke

  • Kompatibilität: Die Kennzahl wird derzeit vor allem von Chromium-basierten Browsern (Chrome, Edge, Opera) geliefert. In Firefox und Safari kann sie fehlen – immer auf undefined prüfen, z. B. mit ??.
  • Nur Video: Bei kind === "audio" ist die Eigenschaft nicht vorhanden.
  • Kumulativer Zähler: Der Wert wächst seit Streambeginn. Für aussagekräftige Live-Werte die Differenz zweier Messungen bilden (siehe Beispiel 3).
  • Division durch null: Solange noch kein Frame aus mehreren Paketen zusammengesetzt wurde, ist der Wert 0 – bei der Berechnung mit totalAssemblyTime vorher abfangen.
  • Nur korrekt decodierte Frames zählen; verworfene oder fehlerhafte Frames tauchen hier nicht auf (siehe dafür framesDropped).