· 5 min read

Wie wir Browser-nativen MP4-Export aufgebaut haben - kein Server erforderlich

PinePaper exportiert MP4-Videos vollständig im Browser mit WebCodecs. So funktioniert die H.264-Pipeline - von Canvas-Frames bis hin zu abspielbaren Videodateien, ohne etwas hochzuladen.

Das Problem

Traditionelle webbasierte Animationstools exportieren Videos, indem sie Frames an einen Server senden, sie mit ffmpeg codieren und das Ergebnis zurückgeben. Dies hat drei Kosten: Upload-Bandbreite (Versenden von Megabyte Frame-Daten), Server-Compute (CPU/GPU-Zeit für die Kodierung) und Datenschutz (Ihre kreative Arbeit durchläuft die Infrastruktur eines Drittanbieters).

PinePaper tut nichts davon. Die MP4-Datei wird vollständig in Ihrem Browser erstellt. Keine Frames verlassen Ihr Gerät. Die Kodierung erfolgt auf dem Hardware-Video-Encoder Ihres Computers. Dieser Artikel erklärt, wie.

WebCodecs: Hardware Video Encoding im Browser

Der WebCodecs API [W3C, 2021] bietet Low-Level-Zugriff auf den eingebauten Video- und Decoder des Browsers. Es wurde in Chrome 94 (September 2021) ausgeliefert und ist jetzt in Chrome, Edge und Opera verfügbar. Safari und Firefox haben teilweise oder experimentelle Unterstützung [Can I Use, 2026].

WebCodecs zeigt zwei wichtige Schnittstellen:

  • VideoEncoder — nimmt rohe Video-Frames, Ausgänge codiert H.264 (oder VP8/VP9/AV1) Bitstream-Stücke
  • VideoDecoder — nimmt kodierte Brocken auf, gibt rohe Frames aus (für die Wiedergabe, nicht für den Export)

Für den Export von MP4 verwenden wir VideoEncoder. Der Workflow:

  1. Erstellen eines für H.264 konfigurierten VideoEncoder mit der gewünschten Auflösung und Bitrate
  2. Für jeden Animationsrahmen: Erfassen Sie die Canvas als VideoFrame, füttern Sie sie an den Geber
  3. Sammeln Sie die codierten Stücke (rohe H.264 NAL-Einheiten)
  4. Mux die Stücke in einen MP4 Container
  5. Angebot der MP4-Datei zum Download

Schritt 1: Encoderkonfiguration

const encoder = new VideoEncoder({
  output: (chunk, metadata) => {
    // chunk.data contains encoded H.264 bytes
    // metadata.decoderConfig contains SPS/PPS on first chunk
    muxer.addVideoChunk(chunk, metadata);
  },
  error: (e) => console.error('Encoder error:', e)
});

encoder.configure({
  codec: 'avc1.42E01E',  // H.264 Baseline Profile Level 3.0
  width: 1080,
  height: 1080,
  bitrate: 5_000_000,    // 5 Mbps
  framerate: 30
});

Die Codec-Zeichenfolge avc1.42E01E spezifiziert H.264 Baseline Profile. Dies ist das am weitesten kompatible H.264-Profil - es wird auf jedem Telefon, Browser und jeder Social-Media-Plattform abgespielt. Höhere Profile (Main, High) bieten eine bessere Kompression, aber weniger Kompatibilität [Richardson, 2010].

Die Bitrate steuert die Qualität vs Dateigröße. Bei 5 Mbps für einen 3-Sekunden-Clip: 5,000,000 bits/s × 3s = 15,000,000 bits = ~1.8 MB. Die tatsächliche Größe variiert je nach Inhaltskomplexität - statische Szenen komprimieren sich besser als schnelle Bewegungen.

Schritt 2: Frame Capture und Encoding

Für jeden Frame in der Animationszeitleiste:

for (let frameNum = 0; frameNum < totalFrames; frameNum++) {
  const frameTime = frameNum / fps;

  // Advance animation to this time
  app.setPlaybackTime(frameTime);
  paper.view.draw();  // Full render (not view.update!)
  await new Promise(r => requestAnimationFrame(r));  // Wait for paint

  // Create VideoFrame from canvas
  const frame = new VideoFrame(canvas, {
    timestamp: frameNum * (1_000_000 / fps)  // microseconds
  });

  // Encode (keyframe every 2 seconds)
  encoder.encode(frame, {
    keyFrame: frameNum % (fps * 2) === 0
  });
  frame.close();  // Release GPU memory
}

Das entscheidende Detail: Nach dem Vorantreiben der Animation und dem Rendern der Canvas müssen Sie auf requestAnimationFrame warten, bevor Sie aufnehmen. Dies stellt sicher, dass die GPU das Komponieren von Pixeln abgeschlossen hat. Ohne diese Synchronisation erfassen Sie einen veralteten Puffer und erzeugen Frames, die leer oder dupliziert sind.

Schritt 3: MP4 Muxing

Der VideoEncoder gibt rohe H.264 Chunks (NAL-Einheiten) aus. Diese sind keine spielbare Datei - sie müssen in einen MP4-Container gewickelt werden, der Timing, Metadaten und die Codec-Konfiguration speichert.

PinePaper verwendet für diesen Schritt die mp4-muxer-Bibliothek [Vani, mp4-muxer]. Der muxer erhält kodierte Stücke mit Zeitstempeln und erzeugt eine gültige MP4-Datei mit:

  • Feld ftyp: Dateitypdeklaration (isom, iso2, mp41)
  • moov-Box: Film-Metadaten, Track-Beschreibungen, Timing-Tabellen
  • mdat-Box: die tatsächlichen codierten Videodaten

Das Ergebnis ist ein standardkonformes MP4, das in jedem Videoplayer, Browser und jeder Social-Media-Plattform abgespielt wird.

Schritt 4: Download

Das fertige MP4 wird als Blob zusammengebaut, über URL.createObjectURL() in ein URL umgewandelt und als Download ausgelöst:

await encoder.flush();  // Wait for all frames to encode
const mp4Blob = muxer.finalize();
const url = URL.createObjectURL(new Blob([mp4Blob], { type: 'video/mp4' }));

const a = document.createElement('a');
a.href = url;
a.download = 'animation.mp4';
a.click();
URL.revokeObjectURL(url);

Die gesamte Pipeline - Frame Capture, H.264 Codierung, MP4 Muxing und Download - findet im Browser statt. Kein Server. Kein Upload. Keine Verarbeitung durch Dritte.

Leistung

Auf einem 2023 MacBook Pro (M2), Kodierung einer 1080 × 1080 Animation bei 30 FPS:

Dauer Rahmen Kodierungszeit Dateigröße
3 sekunden 90 ~2 sekunden ~1.8 MB
10 sekunden 300 ~6 sekunden ~5 MB
30 sekunden 900 ~18 sekunden ~14 MB

Die Kodierung ist schneller als in Echtzeit, da Hardware-H.264-Encoder (Intel Quick Sync, Apple VideoToolbox, NVIDIA NVENC) die umfangreichen Berechnungen durchführen. Der WebCodecs API des Browsers delegiert diese Hardware-Beschleuniger transparent [McIlroy, 2021].

Browser-Unterstützung

Browser WebCodecs H.264 Code Status
Chrome 94+ Ja Ja Volle Unterstützung
Rand 94+ Ja Ja Volle Unterstützung (Chromium)
Oper 80+ Ja Ja Volle Unterstützung (Chromium)
Safari 16.4+ Teilweise Nur Dekodierung Code nicht verfügbar
Firefox Hinter der Flagge Nein Experimentell

Für Browser ohne WebCodecs greift PinePaper auf den GIF-Export zurück, der einen reinen JavaScript-Encoder (gif.js) verwendet und überall funktioniert.

Referenzen

  • Kann ich verwenden (2026). WebCodecs API Browser-Unterstützungstabelle. caniuse.com/webcodecs.
  • McIlroy, D. (2021). WebCodecs Explainer W3C WICG. github.com/nicerobot/nicerobot.github.io/blob/master/nicerobot-explainer-webcodecs.md.
  • Richardson, I.E.G. (2010). Der H.264 Advanced Video Compression Standard (2. Aufl.). Wiley.
  • Vani, A. mp4-muxer — JavaScript MP4 muxer für WebCodecs. github.com/nicerobot/nicerobot.github.io.
  • W3C (2021): WebCodecs API Specification. w3c.github.io/webcodecs/.

Exportieren Sie MP4-Video kostenlos - kein Server, keine Anmeldung, kein Wasserzeichen. Öffnen Sie pinepaper.studio/editor und versuchen Sie es.

Ready to create?

Start making animated GIFs, videos, and graphics — free, no signup.

Open PinePaper Editor