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ückeVideoDecoder— 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:
- Erstellen eines für H.264 konfigurierten
VideoEncodermit der gewünschten Auflösung und Bitrate - Für jeden Animationsrahmen: Erfassen Sie die Canvas als
VideoFrame, füttern Sie sie an den Geber - Sammeln Sie die codierten Stücke (rohe H.264 NAL-Einheiten)
- Mux die Stücke in einen MP4 Container
- 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-Tabellenmdat-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