Start · Sprachen · JavaScript · Referenz · VideoFrame.timestamp

VideoFrame.timestamp

Eigenschaft

Nur-Lese-Eigenschaft, die den Präsentationszeitstempel eines <code>VideoFrame</code> als ganze Zahl in Mikrosekunden liefert.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Safari 16.4+, Fir Kategorie: webapi

Signatur

VideoFrame.timestamp

Beschreibung

Die schreibgeschützte Eigenschaft timestamp eines VideoFrame gibt an, wann das Einzelbild innerhalb des Medienstroms angezeigt werden soll. Die Angabe erfolgt als ganze Zahl in Mikrosekunden (1 s = 1 000 000 µs). Sie ist Teil der WebCodecs API.

Den Wert legt man beim Erzeugen eines Frames über die Option timestamp im Konstruktor new VideoFrame(source, { timestamp }) fest. Bei Frames aus einem VideoDecoder übernimmt der Decoder den Zeitstempel aus dem zugehörigen EncodedVideoChunk. Kommen die Frames von einem MediaStreamTrackProcessor (etwa einer Kamera), setzt der Browser den Wert.

Gebraucht wird der Zeitstempel vor allem, um Audio und Video zu synchronisieren, Frames im richtigen Takt auf ein Canvas zu zeichnen, beim Kodieren die Reihenfolge und die Keyframe-Abstände zu steuern und beim Muxen in Container wie MP4 oder WebM die richtige Zeitbasis zu setzen. Zusammen mit VideoFrame.duration ergibt sich das Zeitfenster, in dem der Frame sichtbar ist.

Rückgabewert

Typ
number
Beschreibung
Ganze Zahl (Integer) mit dem Präsentationszeitstempel in Mikrosekunden. Der Wert darf auch negativ sein. Nach close() ist der Frame nicht mehr nutzbar, der Wert ist dann nicht mehr aussagekräftig.

Beispiele

Zeitstempel beim Erzeugen setzen und auslesen

const canvas = new OffscreenCanvas(640, 360);
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'tomato';
ctx.fillRect(0, 0, 640, 360);

// Frame bei 2,5 Sekunden, 1/30 s lang
const frame = new VideoFrame(canvas, {
  timestamp: 2_500_000,
  duration: Math.round(1_000_000 / 30)
});

console.log(frame.timestamp);            // Mikrosekunden
console.log(frame.timestamp / 1e6, 's'); // Sekunden
frame.close();
2500000 2.5 's'

Frames für einen Encoder mit fester Bildrate erzeugen

const fps = 30;
const canvas = new OffscreenCanvas(320, 240);
const ctx = canvas.getContext('2d');

const encoder = new VideoEncoder({
  output: (chunk) => console.log('Chunk', chunk.timestamp, chunk.type),
  error: (e) => console.error(e)
});
encoder.configure({ codec: 'vp8', width: 320, height: 240, bitrate: 1_000_000, framerate: fps });

for (let i = 0; i < 3; i++) {
  ctx.fillStyle = `hsl(${i * 120}, 80%, 50%)`;
  ctx.fillRect(0, 0, 320, 240);
  const frame = new VideoFrame(canvas, {
    timestamp: Math.round((i * 1_000_000) / fps)
  });
  encoder.encode(frame, { keyFrame: i === 0 });
  frame.close(); // Speicher sofort freigeben
}
await encoder.flush();
Chunk 0 key Chunk 33333 delta Chunk 66667 delta

Kamera-Frames auswerten (Abstand zwischen Frames)

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();
const processor = new MediaStreamTrackProcessor({ track });
const reader = processor.readable.getReader();

let last = null;
for (let n = 0; n < 5; n++) {
  const { value: frame, done } = await reader.read();
  if (done) break;
  if (last !== null) {
    const deltaMs = (frame.timestamp - last) / 1000;
    console.log(`Abstand: ${deltaMs.toFixed(1)} ms`);
  }
  last = frame.timestamp;
  frame.close();
}
track.stop();
Abstand: 33.3 ms Abstand: 33.4 ms …

// Wichtig · Fallstricke

  • Einheit: Der Wert ist in Mikrosekunden angegeben, nicht in Millisekunden wie performance.now() und nicht in Sekunden wie HTMLMediaElement.currentTime. Wer das verwechselt, bekommt schnell Synchronisationsfehler um den Faktor 1000.
  • Pflichtangabe: Wird ein VideoFrame aus einem BufferSource (Rohpixeldaten) erzeugt, muss timestamp angegeben werden, sonst wirft der Konstruktor einen TypeError. Bei Bildquellen wie Canvas oder ImageBitmap ist der Wert optional. Ohne Angabe übernimmt der Browser den Zeitstempel der Quelle, falls es einen gibt, sonst 0.
  • Kein fester Nullpunkt: Bei Kamera-Frames beginnt der Zeitstempel oft nicht bei 0. Für Aufnahmen sollte man ihn auf den ersten Frame beziehen (frame.timestamp - startTimestamp).
  • Rundung: Bei Bildraten wie 30 oder 29,97 fps die Werte mit Math.round() berechnen, damit sich keine Rundungsfehler aufsummieren.
  • Frames immer mit close() freigeben, sonst läuft der Grafikspeicher voll.
  • Kompatibilität: WebCodecs gibt es nur in sicheren Kontexten (HTTPS). Die Unterstützung ist gut in Chromium-Browsern, in Safari ab 16.4 und in Firefox ab 130. MediaStreamTrackProcessor gibt es derzeit nur in Chromium-Browsern.