Signatur
Beschreibung
ImageTrackList gehört zur WebCodecs API. Man erzeugt die Liste nicht selbst, sondern bekommt sie über die Eigenschaft ImageDecoder.tracks. Manche Bildformate enthalten mehrere Spuren, zum Beispiel ein Standbild und eine Animation in AVIF. Jede dieser Spuren steht in der Liste als ImageTrack-Objekt.
Die Liste funktioniert wie ein Array: tracks[0] liefert die erste Spur, length die Anzahl der Spuren. Dazu kommen diese Eigenschaften:
ready: einPromise<undefined>. Es wird erfüllt, sobald die Liste mit Spuren gefüllt ist.length: die Anzahl der Spuren.selectedIndex: der Index der ausgewählten Spur, oder-1, wenn keine ausgewählt ist.selectedTrack: die ausgewählteImageTrack, odernull.
Die Liste braucht man vor allem, um vor dem Dekodieren herauszufinden, ob ein Bild animiert ist (ImageTrack.animated), wie viele Einzelbilder es hat (frameCount) und wie oft die Animation wiederholt wird (repetitionCount). Setzt man ImageTrack.selected = true, wählt man eine andere Spur zum Dekodieren aus. Die bisher ausgewählte Spur wird dabei automatisch abgewählt.
Rückgabewert
ImageDecoder.tracks. Einträge liest man per Index aus (list[i] → ImageTrack).Beispiele
Spuren eines animierten GIFs auslesen
const response = await fetch('/bilder/animation.gif');
const decoder = new ImageDecoder({
data: response.body,
type: 'image/gif'
});
// Warten, bis die Spurliste gefüllt ist
await decoder.tracks.ready;
const tracks = decoder.tracks;
console.log('Anzahl Spuren:', tracks.length);
console.log('Ausgewählter Index:', tracks.selectedIndex);
const track = tracks.selectedTrack;
console.log('Animiert:', track.animated);
console.log('Frames:', track.frameCount);
console.log('Wiederholungen:', track.repetitionCount);
Über alle Spuren iterieren
const logTracks = async (decoder) => {
await decoder.tracks.ready;
const { tracks } = decoder;
for (let i = 0; i < tracks.length; i++) {
const t = tracks[i];
console.log(`#${i}: animiert=${t.animated}, frames=${t.frameCount}, ausgewählt=${t.selected}`);
}
};
const res = await fetch('/bilder/foto.avif');
const decoder = new ImageDecoder({ data: res.body, type: 'image/avif' });
await logTracks(decoder);
Animierte Spur auswählen und ersten Frame zeichnen
const res = await fetch('/bilder/foto.avif');
const decoder = new ImageDecoder({ data: res.body, type: 'image/avif' });
await decoder.tracks.ready;
const tracks = Array.from({ length: decoder.tracks.length }, (_, i) => decoder.tracks[i]);
const animatedTrack = tracks.find((t) => t.animated);
if (animatedTrack) {
animatedTrack.selected = true; // wählt die bisherige Spur automatisch ab
}
console.log('Neuer Index:', decoder.tracks.selectedIndex);
const { image } = await decoder.decode({ frameIndex: 0 });
const ctx = document.querySelector('canvas').getContext('2d');
ctx.drawImage(image, 0, 0);
image.close(); // VideoFrame freigeben
// Wichtig · Fallstricke
- Browserunterstützung:
ImageDecoderund damitImageTrackListgibt es in Chromium-Browsern (Chrome, Edge, Opera) ab Version 94 und in Firefox ab Version 133. Safari unterstützt die API nicht. Vor der Nutzung sollte man prüfen, ob sie vorhanden ist:'ImageDecoder' in globalThis. - Die API steht nur in einem sicheren Kontext (HTTPS) zur Verfügung. Sie funktioniert auch in Web Workern.
- Vor
await tracks.readyist die Liste unter Umständen noch leer:lengthist dann0undselectedTrackistnull. - Die Liste ist kein echtes Array. Es gibt kein
mapoderforEach. Man verwendet eine Zählschleife oder baut vorher mitArray.from({ length })ein Array daraus. - Wenn man eine andere Spur auswählt, werden laufende
decode()-Aufrufe unter Umständen abgebrochen.frameIndexbezieht sich danach immer auf die neu ausgewählte Spur. - Bei Datenströmen (
ReadableStream) kannframeCountanfangs zu niedrig sein. Der endgültige Wert steht erst fest, wennImageDecoder.completederfüllt ist.