Start · Sprachen · JavaScript · Referenz · ImageTrack.frameCount

ImageTrack.frameCount

Eigenschaft

Die schreibgeschützte Eigenschaft <code>frameCount</code> gibt an, wie viele Bilder (Frames) ein <code>ImageTrack</code> enthält.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Opera 80+, Firefo Kategorie: webapi

Signatur

get ImageTrack.frameCount

Beschreibung

Die Eigenschaft ImageTrack.frameCount gehört zur WebCodecs API. Sie liefert als Ganzzahl, wie viele Einzelbilder ein Bild-Track eines ImageDecoder enthält. Bei Standbildern wie JPEG oder einem nicht animierten PNG ist der Wert in der Regel 1. Bei animierten Formaten wie GIF, animiertem WebP oder APNG steht er für die Zahl der Animationsbilder.

Gebraucht wird der Wert vor allem dann, wenn man alle Frames einer Animation einzeln mit ImageDecoder.decode({ frameIndex }) decodieren will, etwa um sie auf einem <canvas> abzuspielen, Vorschaubilder zu erzeugen oder Frames zu analysieren. Zusammen mit ImageTrack.animated und ImageTrack.repetitionCount beschreibt frameCount den Aufbau einer Animation vollständig.

Wichtig: Wird der Decoder mit einem ReadableStream gefüttert, kann frameCount noch wachsen, solange Daten nachkommen. Verlässlich ist der Wert erst, wenn das Promise ImageDecoder.completed erfüllt ist. Vorher sollte man ihn nur als vorläufige Untergrenze behandeln.

Rückgabewert

Typ
number
Beschreibung
Eine nicht negative Ganzzahl (unsigned long) mit der Anzahl der Frames, die bisher im Track erkannt wurden.

Beispiele

Frame-Anzahl eines animierten GIF ermitteln

const response = await fetch('/bilder/lade-animation.gif');

const decoder = new ImageDecoder({
  data: response.body,
  type: 'image/gif'
});

// Warten, bis die Track-Informationen vorliegen
await decoder.tracks.ready;
// Warten, bis alle Daten geladen sind – erst dann ist frameCount endgültig
await decoder.completed;

const track = decoder.tracks.selectedTrack;
console.log(`Animiert: ${track.animated}`);
console.log(`Frames: ${track.frameCount}`);
Animiert: true Frames: 24

Alle Frames nacheinander auf ein Canvas zeichnen

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const playAnimation = async (url, type) => {
  const { body } = await fetch(url);
  const decoder = new ImageDecoder({ data: body, type });
  await decoder.completed;

  const { frameCount } = decoder.tracks.selectedTrack;

  for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
    const { image } = await decoder.decode({ frameIndex });
    ctx.drawImage(image, 0, 0);
    // duration steht in Mikrosekunden
    const delayMs = (image.duration ?? 100000) / 1000;
    image.close(); // Speicher des VideoFrame freigeben
    await new Promise((resolve) => setTimeout(resolve, delayMs));
  }

  decoder.close();
};

playAnimation('/bilder/katze.webp', 'image/webp');

Wachsenden Wert beim Streaming beobachten

const response = await fetch('/bilder/gross.gif');
const decoder = new ImageDecoder({ data: response.body, type: 'image/gif' });

await decoder.tracks.ready;
const track = decoder.tracks.selectedTrack;
console.log('Vorläufig:', track.frameCount);

await decoder.completed;
console.log('Endgültig:', track.frameCount);
Vorläufig: 3 Endgültig: 120

// Wichtig · Fallstricke

  • Vorläufiger Wert beim Streaming: Vor decoder.completed kann frameCount zu niedrig sein. Wer eine Schleife über alle Frames baut, sollte deshalb zuerst auf completed warten oder die Schleife bei einem RangeError von decode() sauber beenden.
  • Schreibgeschützt: Wenn man der Eigenschaft einen Wert zuweist, passiert nichts. Im Strict Mode wird ein TypeError ausgelöst.
  • Speicher: Jeder decodierte Frame ist ein VideoFrame. Ruft man image.close() nicht auf, wächst bei vielen Frames der Speicherverbrauch stark an.
  • Kompatibilität: ImageDecoder gibt es in Chromium-Browsern ab Version 94 und in Firefox ab Version 133, in Safari aber nicht. Die API funktioniert nur in sicheren Kontexten (HTTPS). Sie steht im Fenster und in Dedicated Workern zur Verfügung. Vor der Nutzung sollte man mit 'ImageDecoder' in globalThis prüfen, ob sie vorhanden ist. Ob ein Format unterstützt wird, zeigt ImageDecoder.isTypeSupported(type).