Как мы создали нативный браузерный MP4-экспорт — не требуется сервер
PinePaper экспортирует видео MP4 полностью в браузере с помощью WebCodecs. Вот как работает конвейер H.264 — от холстовых кадров до воспроизводимого видеофайла, не загружая ничего.
Проблема
Традиционные веб-инструменты анимации экспортируют видео, отправляя кадры на сервер, кодируя их с помощью ffmpeg и возвращая результат. Это требует трех затрат: загрузка пропускной способности (отправка мегабайт данных кадра), вычисление сервера (время CPU / GPU для кодирования) и конфиденциальность (ваша творческая работа проходит через инфраструктуру третьей стороны).
PinePaper этого не делает. Файл MP4 полностью создан в вашем браузере. Никакие кадры не покидают ваше устройство. Кодирование происходит на аппаратном видеокодере вашей машины. Эта статья объясняет, как.
WebCodecs: аппаратное кодирование видео в браузере
WebCodecs API [W3C, 2021] обеспечивает низкоуровневый доступ к встроенному видеокодеру и декодеру браузера. Он был отправлен в Chrome 94 (сентябрь 2021 года) и теперь доступен в Chrome, Edge и Opera. Safari и Firefox имеют частичную или экспериментальную поддержку [Can I Use, 2026].
WebCodecs предлагает два ключевых интерфейса:
VideoEncoder— берет необработанные видеокадры, выводит закодированный H.264 (или VP8/VP9/AV1) битовый потокVideoDecoder— берет закодированные фрагменты, выводит необработанные кадры (используется для воспроизведения, а не экспорта)
Для экспорта MP4 мы используем VideoEncoder. Рабочий процесс:
- Создайте
VideoEncoder, сконфигурированный для H.264 с требуемым разрешением и битрейтом - Для каждого кадра анимации: захват холста в виде
VideoFrame, подача его к кодеру - Соберите закодированные фрагменты (сырые единицы Н.264 NAL)
- Смешайте куски в контейнер MP4
- Предложите файл MP4 для загрузки
Шаг 1: Конфигурация кодера
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
});
Строка кодека 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 перед захватом. Это гарантирует, что GPU закончил композицию пикселей. Без этой синхронизации вы захватываете несвежий буфер и создаете пустые или дублированные кадры.
Шаг 3: MP4 Muxing
VideoEncoder выводит необработанные фрагменты H.264 (единицы NAL). Это не воспроизводимый файл — он должен быть завернут в контейнер MP4, который хранит время, метаданные и конфигурацию кодека.
PinePaper использует библиотеку mp4-muxer [Vani, mp4-muxer] для этого шага. Муксер получает закодированные фрагменты с метками времени и производит действительный файл MP4 с:
ftypbox: декларация типа файла (isom, iso2, mp41)moovbox: метаданные фильма, описания треков, таблицы времениmdatbox: фактические закодированные видеоданные
Результатом является стандартный 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) обрабатывают тяжелые вычисления. Веб-кодеки браузера API делегируют эти аппаратные ускорители прозрачно [McIlroy, 2021].
Поддержка браузера
| Браузер | WebCodecs | H.264 Код | Статус |
|---|---|---|---|
| Chrome 94+ | Да | Да | Полная поддержка |
| Edge 94+ | Да | Да | Полная поддержка (хром) |
| Опера 80+ | Да | Да | Полная поддержка (хром) |
| Сафари 16.4+ | Частичный | Только декодировать | Код недоступен |
| Firefox | За флагом | Нет | Экспериментальный |
Для браузеров без WebCodecs PinePaper возвращается к экспорту GIF, который использует чистый кодер JavaScript (gif.js) и работает везде.
Ссылки
- Можно ли использовать (2026) WebCodecs API таблица поддержки браузера. caniuse.com/webcodecs.
- Макилрой, Д. (2021). W3C WICG. github.com/nicerobot/nicerobot.github.io/blob/master/nicerobot-explainer-webcodecs.md.
- Ричардсон, I.E.G. (2010). H.264 Advanced Video Compression Standard (2-е изд.). Уайли.
- Vani, A. mp4-muxer — JavaScript MP4 muxer для WebCodecs. github.com/nicerobot/nicerobot.github.io.
- W3C (2021). Спецификация WebCodecs API. w3c.github.io/webcodecs/.
Экспорт MP4 видео бесплатно — без сервера, без регистрации, без водяного знака. Откройте [pinepaper.studio/editor] (/editor) и попробуйте.
Ready to create?
Start making animated GIFs, videos, and graphics — free, no signup.
Open PinePaper Editor