· 5 min read

Як ми побудували браузер-нативний MP4 Експорт — не потрібно сервера

PinePaper експортує відео MP4 повністю в браузері за допомогою WebCodecs. Ось як працює трубопровід H.264 — від полотна рамок до відтворюваного відеофайлу, без завантаження нічого.

Проблема

Традиційні інструменти веб-на основі анімації експортують відео шляхом відправки кадрів на сервер, кодування їх фfmpeg та повернення результату. Це має три витрати: завантажити пропускну здатність (закінчення мегабайтів даних кадрів), серверний комп’ютер (час CPU/GPU для кодування), а також конфіденційність (при творчій роботі транзитує інфраструктуру третьої сторони).

PinePaper не робить цього. Файл MP4 створений повністю у вашому браузері. Без рамок залиште пристрій. Кодування відбувається на апаратному відео енкодері машини. У статті описано як.

WebCodecs: Апаратне відео кодування в браузері

WebCodecs API [W3C, 2021] забезпечує низький рівень доступу до вбудованого відеокодера браузера та декодера. Він був відправлений в Chrome 94 (вересень 2021) і тепер доступний в Chrome, Edge і Opera. Safari і Firefox мають часткову або експериментальну підтримку [Чи можу я використовувати, 2026].

WebCodecs визначає два основні інтерфейси:

  • VideoEncoder — займає сирі відеорамки, виходи, зашифровані H.264 (або VP8/VP9/AV1) бітстрім штани
  • VideoDecoder — закодовані шматки, виходи сирої рами (використовуються для відтворення, не експортуються)

Для експорту MP4 ми використовуємо VideoEncoder. Робочий потік:

  1. Створіть VideoEncoder налаштовуваний для H.264 на бажаному дозволі та бітрейт
  2. Для кожної анімаційної рами: захоплення полотна як VideoFrame, годувати його до енкодера
  3. Збір закодованих штанів (raw H.264 NAL одиниці)
  4. Мукс куртки в контейнер MP4
  5. Пропозиція файлу MP4 для завантаження

Крок 1: Конфігурація Encoder

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

Кодc string avc1.42E01E визначає H.264 Базовий профіль. Це найбільш широко сумісний профіль H.264 — він грає на кожному телефоні, браузері та соціальні медіаплатформі. Більш високі профілі (Main, High) пропонують краще стиснення, але менше сумісності [Richardson, 2010].

Якість бітрейт контролює як і розмір файлу. На 5 Мбіт/с за 3-секундний кліп: 5,000,000 bits/s × 3s = 15,000,000 bits = ~1.8 MB. Фактичний розмір варіюється в залежності від складності контенту — статичних сцен компресів краще, ніж швидкий рух.

Крок 2: Захоплення каркасу і кодування

Для кожного кадру в часі анімації:

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
}

Критична деталь: після оголошення анімації та рендерингу полотна, необхідно чекати requestAnimationFrame перед захопленням. Це забезпечує графічний процесор. Без цієї синхронізації ви захоплюєте буфер і випускає кадри, які є порожніми або дублікованими.

Крок 3: MP4 Муксинг

Виходи відеоEncoder сирі H.264 штани (NAL юніти). Це не відтворюваний файл — потрібно загорнути в контейнері MP4, який зберігає терміни, метадані та налаштування коду.

Русский EnglishРусскийУкраїнськаPolskiItalianoEspañol汉语Bahasa Indonesiaहिन्दीPortuguês日本語DeutschFrançaisภาษาไทยελληνικά اللغة العربية Муксер отримує зашифровані шматки з таймерами і виробляє дійсний файл MP4 з:

  • ftyp: декларація типу файлу (ізо, iso2, mp41)
  • moov: метадані фільму, опис треків, таблиці термінів
  • mdat: фактичні закодовані відеодані

В результаті є стандарти-компліант MP4, які грає в кожному відеоплеєрі, браузері та соціальні медіаплатформі.

Крок 4: Завантажити

Завершено MP4 зібрано як Blob, перетворений на URL через URL.createObjectURL(), і запускається як завантаження:

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

Весь трубопровід — захоплення кадру, кодування H.264, обшивка MP4 і завантаження — відбувається в браузері. Немає сервера. Немає завантаження. Немає сторонніх обробки.

Продуктивність

2023 MacBook Pro (M2), кодування анімації 1080 × 1080 на 30 FPS:

Тривалість Кошик Час кодування Розмір файлу
3 хв 90 ~2 хв ~1.8 MB
10 хв 300 ~6 хв ~5 МБ
30 хв 900 до18 секунд ~14 МБ

Конкодування швидше, ніж в режимі реального часу, оскільки апаратні засоби H.264 (Intel Quick Sync, Apple VideoToolbox, NVIDIA NVENC) керують важким обчисленням. WebCodecs API делегує ці апаратні акселератори прозоро [McIlroy, 2021].

Підтримка браузера

Веб-сайт Сайти H.264 коди Статус на сервери
Хром 94+ Я Я Повна підтримка
Край 94+ Я Я Повна підтримка (Хром)
Опера 80+ Я Я Повна підтримка (Хром)
Сафарі 16.4+ Часті За замовчуванням Код не доступний
Українська За прапором Немає Експериментальні

Для браузерів без WebCodecs, PinePaper повертається на експорт GIF, який використовує чистий JavaScript-кодер (gif.js) і працює всюди.

Посилання

  • Чи можу я використовувати (2026). Статус на сервери JavaScript licenses API Веб-сайт Go1.13.8.
  • МакІльрой, Д. (2021 р.). WebCodecs Explainer. W3C WICG. github.com/nicerobot/nicerobot/nicerobot.github.io/blob/master/nicerobot-explainer-webcodecs.md.
  • Річардсон, І.Є.Г. (2010). * H.264 Advanced Video Compression Standard* (2-й ред.). Вілі.
  • Вані, А. mp4-muxer — JavaScript MP4 muxer для WebCodecs. github.com/nicerobot/nicerobot/nicerobot.github.io.
  • W3C (2021). Специфікація WebCodecs API. JavaScript licenses API Веб-сайт Go1.13.8.

Експорт відео MP4 безкоштовно — без сервера, без реєстрації, без водяного знака. Відкрийте paper.studio/editor і спробуйте його.

Ready to create?

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

Open PinePaper Editor