· 6 min read

Jak zbudowaliśmy Browser- Native MP4 Export - Nie wymaga serwera

PinePaper eksportuje wideo MP4 całkowicie w przeglądarce za pomocą WebCodecs. Oto jak działa rurociąg H.264 od ram płótna do odtwarzalnego pliku wideo, bez wrzucania niczego.

Problem

Tradycyjne narzędzia do animacji webowej eksportują wideo wysyłając ramki na serwer, kodując je ffmpeg i zwracając wynik. Ma to trzy koszty: przesyłanie przepustowości (wysyłanie megabajtów danych ramek), obliczanie serwerów (czas procesora / GPU dla kodowania) oraz prywatność (praca twórcza przechodzi infrastrukturę osoby trzeciej).

PinePaper nic z tego nie robi. MP4 jest tworzony w całości w przeglądarce. Żadne ramy nie opuszczą twojego urządzenia. Kodowanie odbywa się na sprzętowym koderze wideo maszyny. Ten artykuł wyjaśnia jak.

WebCodecs: Kodowanie wideo w przeglądarce

    • WebCodecs API * * [W3C, 2021] zapewnia niski poziom dostępu do budynku przeglądarki - w koderze wideo i dekoderze. Został wysłany w Chrome 94 (wrzesień 2021) i jest teraz dostępny w Chrome, Edge i Opera. Safari i Firefox mają częściowe lub eksperymentalne wsparcie [Czy mogę używać, 2026].

WebCodecs ujawnia dwa kluczowe interfejsy:

  • VideoEncoder - pobiera surowe ramki wideo, wyjścia zakodowane H.264 (lub VP8 / VP9 / AV1)
  • VideoDecoder - bierze zakodowane kawałki, wyjścia surowe ramy (używane do odtwarzania, a nie eksportu)

Dla eksportu MP4 używamy VideoEncoder. Przepływ pracy:

  1. Utwórz VideoEncoder skonfigurowany dla H.264 w pożądanej rozdzielczości i bitrate
  2. Dla każdej ramy animacji: uchwycić płótno jako VideoFrame, karmić go do kodera
  3. Zbierz zakodowane kawałki (surowe jednostki H.264 NAL)
  4. Wrzuć kawałki do pojemnika MP4
  5. Oferujemy plik MP4 do pobrania

Krok 1: Konfiguracja enkodera

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
});

Łańcuch kodekowy avc1.42E01E określa profil podstawowy H.264. Jest to najbardziej kompatybilny profil H.264 - gra na każdym telefonie, przeglądarce i platformie mediów społecznościowych. Wyższe profile (Main, High) oferują lepszą kompresję, ale mniej kompatybilności [Richardson, 2010].

Bitrate kontroluje jakość a rozmiar pliku. Przy 5 Mbps za 3-sekundowy klip: 5,000,000 bits/s × 3s = 15,000,000 bits = ~1.8 MB. Rzeczywista wielkość zależy od złożoności treści - sceny statyczne kompresują lepiej niż szybki ruch.

Krok 2: Uchwyt i kodowanie ramki

Dla każdej ramki w linii czasu animacji:

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
}

Krytyczny szczegół: po przyspieszeniu animacji i renderowaniu płótna, należy poczekać na requestAnimationFrame przed przechwyceniem. Dzięki temu GPU ukończyło kompostowanie pikseli. Bez tej synchronizacji, można uchwycić nieświeży bufor i produkować ramki, które są puste lub duplikowane.

Krok 3: MP4 Muxing

VideoEncoder wyjmuje surowe części H.264 (jednostki NAL). Nie są to odtwarzalne pliki - muszą być zawinięte w pojemnik MP4, który przechowuje czas, metadane i konfigurację kodeka.

PinePaper używa * * mp4- muxer * * biblioteki [Vani, mp4- muxer] dla tego kroku. Muxer otrzymuje zakodowane kawałki ze znacznikami czasu i produkuje ważny plik MP4 z:

  • Pole ftyp: deklaracja typu pliku (isom, iso2, mp41)
  • moov box: metadane filmowe, opisy utworów, tabele czasowe
  • mdat box: rzeczywiste zakodowane dane wideo

Rezultatem jest zgodny ze standardami MP4, który gra w każdym odtwarzaczu wideo, przeglądarce i platformie mediów społecznościowych.

Krok 4: Pobierz

Ukończony MP4 jest montowany jako Blob, konwertowany na URL przez URL.createObjectURL() i uruchamiany jako pobieranie:

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);

Cały rurociąg.. wychwytywanie ramki, kodowanie H.264, muxowanie MP4 i pobieranie - dzieje się w przeglądarce. Nie ma serwera. Nie wysyłaj. Nie ma trzeciej partii.

Wydajność

Na MacBook Pro (M2) 2023 kodowanie animacji 1080 × 1080 przy 30 FPS:

Czas trwania Ramy Czas kodowania Rozmiar pliku
3 sekundy 90 ~ 2 sekundy ~1.8 MB
10 sekund 300 6 sekund ~ 5 MB
30 sekund 900 18 sekund 14 MB

Kodowanie jest szybsze niż w czasie rzeczywistym, ponieważ sprzęt H.264 encoders (Intel Quick Sync, Apple VideoToolbox, NVIDIA NVENC) obsługuje ciężkie obliczenia. WebCodecs API w przeglądarce przekazuje te akceleratory sprzętowe w przejrzysty sposób [McIlroy, 2021].

Wybierz długość. Oba paski dzielą jedną skalę, więc pasek kodowy siedzi wewnątrz clip bar * jest * roszczenie - i przełączanie między trzema pokazuje, że praca rośnie proporcjonalnie do ramek, które są częścią, której pojedynczy wiersz nie może pokazać.

Interactive demo — open in editor pp:PinePaper

Obsługa przeglądarki

Przeglądarka WebCodecs H.264 Kod Status
Chrome 94 + Tak Tak Pełne wsparcie
Krawędź 94 + Tak Tak Pełne wsparcie (chrom)
Opera 80 + Tak Tak Pełne wsparcie (chrom)
Safari 16,4 + Częściowo Tylko dekodowanie Kod niedostępny
Firefox Za flagą Nie Eksperymentalne

Dla przeglądarek bez WebCodecs PinePaper wraca do eksportu GIF, który używa czystego kodera JavaScript (gif.js) i działa wszędzie.

Odniesienia

  • Czy mogę użyć (2026). Tabela obsługi przeglądarki WebCodecs API. caniuse.com / webcodecs.
  • McIlroy. (2021). WebCodecs Explorainer. W3C WICG. github.com / nicerobot / nicerobot.github.io / blob / master / nicerobot- explainer- webcodecs.md.
  • Richardson, I.E.G. (2010). * H.264 Advanced Video Compression Standard * (2nd ed.). Wiley.
  • Vani, A. mp4- muxer - JavaScript MP4 muxer dla WebCodecs. github.com / nicerobot / nicerobot.github.io.
  • W3C (2021). WebCodecs API Specyfikacja. w3c.github.io / webcodecs /.

Eksportuj filmy MP4 za darmo - bez serwera, bez rejestracji, bez znaku wodnego. Otwórz [pinepaper.studio / editor] (/editor) i spróbuj.

Ready to create?

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

Open PinePaper Editor