Оптимизация рабочих процессов видео и аудио для ваших пользователей

Меня всегда привлекала возможность скомпилировать приложение в веб-сборку. Это означает, что мы можем использовать проверенные инструменты в Интернете. Теперь, когда даже мобильные устройства более мощные, чем большинство серверов, и мы можем использовать эту возможность бесплатно, нет причин не делать этого.

Итак, давайте изменим его на 11 с обработкой аудио/видео в браузере.



Лучшим инструментом с открытым исходным кодом для этого, несомненно, является FFmpeg. Его интерфейс командной строки функционален, но прост. И уже есть проект под названием ffmpeg.wasm, который делает упаковку и предоставляет готовые бинарники в виде ffmpeg.wasm-core.

Однако есть 2 проблемы:

  1. Производительность. Не ожидайте обработки видео в формате Full HD.
  2. Размер. Окончательный бинарный файл wasm весит 24,5 мб. Даже с gzip его 8,5 Мб, что может занять некоторое время для загрузки и увеличить стоимость хостинга.

Вероятно, нецелесообразно загружать такой двоичный файл только для сжатия, например. например, mp3 перед загрузкой.

Итак, как мы можем улучшить это?

Скомпилируйте свой собственный ffmpeg.wasm

Инструкции в ридми на самом деле неплохие.

  • Оформить заказ ffmpeg.wasm-core
  • инициализировать подмодули git
  • Но вместо запуска скрипта build-with-docker.sh мы немного изменим проект.

В wasm/build-scripts/configure-ffmpeg.sh вы найдете некоторые параметры, с которыми компилируется FFmpeg. По умолчанию это выглядит примерно так:

#!/bin/bash

set -euo pipefail
source $(dirname $0)/var.sh

FLAGS=(
  "${FFMPEG_CONFIG_FLAGS_BASE[@]}"
  --enable-gpl            # required by x264
  --enable-nonfree        # required by fdk-aac
  --enable-zlib           # enable zlib
  --enable-libx264        # enable x264
  --enable-libx265        # enable x265
  --enable-libvpx         # enable libvpx / webm
  --enable-libwavpack     # enable libwavpack
  --enable-libmp3lame     # enable libmp3lame
  --enable-libfdk-aac     # enable libfdk-aac
  --enable-libtheora      # enable libtheora
  --enable-libvorbis      # enable libvorbis
  --enable-libfreetype    # enable freetype
  --enable-libopus        # enable opus
  --enable-libwebp        # enable libwebp
  --enable-libass         # enable libass
  --enable-libfribidi     # enable libfribidi
  # --enable-libaom         # enable libaom
)
echo "FFMPEG_CONFIG_FLAGS=${FLAGS[@]}"
emconfigure ./configure "${FLAGS[@]}"

Как видите, конфигурация по умолчанию просто включает внешние библиотеки, но не более того.

Запустите ./configure --help в проекте, чтобы получить список параметров, которые вы можете использовать. Вас больше всего интересует Individual component options:

  --disable-everything     disable all components listed below
  --enable-encoder=NAME    enable encoder NAME
  --enable-decoder=NAME    enable decoder NAME
  --enable-muxer=NAME      enable muxer NAME
  --enable-demuxer=NAME    enable demuxer NAME
  --enable-parser=NAME     enable parser NAME
  --enable-filter=NAME     enable filter NAME

Итак, что вы хотите сделать сейчас, это выяснить, какие компоненты вам действительно нужны, поэтому давайте сначала посмотрим, что они из себя представляют:

  • Кодировщики и декодеры. Эти компоненты выполняют тяжелую работу по чтению и записи видео- и аудиоинформации. Всего в FFmpeg доступно 224 кодировщика и 535 декодеров. Некоторые из наиболее часто используемых кодировщиков включают libx264 (для видео H.264) и libfdk_aac (для аудио AAC), а популярные декодеры включают h264 (для видео H.264) и aac (для аудио AAC).
  • Мультиплексоры и демультиплексоры: эти компоненты отвечают за упаковку и распаковку форматов контейнеров, таких как MP4, MKV и AVI. Всего в FFmpeg доступно 165 мультиплексоров и 310 демультиплексоров.
  • Парсеры: эти компоненты считывают выходные данные кодировщиков, чтобы правильно разделить их на форматы контейнеров. Например, если вы используете кодировщик libx264 для создания видео H.264, вам необходимо включить парсер h264 в свою сборку. Всего в FFmpeg доступно 47 парсеров.
  • Фильтры: эти компоненты позволяют редактировать видео- или аудиопоток различными способами. Некоторые распространенные фильтры включают scale (для изменения размера видео- или аудиопотока) и fps (для изменения частоты кадров). Всего в FFmpeg доступен 461 фильтр. Это могут быть фильтры для деинтерлейсинга видео, добавления текста и векторной графики или создания цветовой палитры для GIF-файлов.

Итак, допустим, вы перекодируете только видео h264 и аудио в формате aac, как это будет выглядеть?:

FLAGS=(
  "${FFMPEG_CONFIG_FLAGS_BASE[@]}"

  # make sure all components are enabled explicitly
  --disable-all

  # external libaries
  --enable-gpl            # required by x264
  --enable-nonfree        # required by fdk-aac
  --enable-zlib           # enable zlib
  --enable-libx264        # enable x264
  --enable-libfdk-aac     # enable libfdk-aac

  # basic requirements to process video
  --enable-protocol=file
  --enable-avcodec
  --enable-avformat
  --enable-avfilter
  --enable-swresample
  --enable-swscale

  # all components we explicitly need
  --enable-demuxer=mov # also mp4,m4a,3gp,3g2,mj2
  --enable-decoder=h264,libfdk_aac
  --enable-encoder=libx264,libfdk_aac
  --enable-parser=h264,aac
  --enable-muxer=mp4

  # filters, that ffmpeg might add automatically
  # insert_trim https://github.com/FFmpeg/FFmpeg/blob/45ab5307a6e8c04b4ea91b1e1ccf71ba38195f7c/fftools/ffmpeg_filter.c#L355
  --enable-filter=trim,atrim
  # configure_output_video_filter https://github.com/FFmpeg/FFmpeg/blob/45ab5307a6e8c04b4ea91b1e1ccf71ba38195f7c/fftools/ffmpeg_filter.c#L428
  --enable-filter=buffersink,scale,format,fps
  # configure_output_audio_filter https://github.com/FFmpeg/FFmpeg/blob/45ab5307a6e8c04b4ea91b1e1ccf71ba38195f7c/fftools/ffmpeg_filter.c#L522
  --enable-filter=abuffersink,aformat
  # configure_input_video_filter https://github.com/FFmpeg/FFmpeg/blob/45ab5307a6e8c04b4ea91b1e1ccf71ba38195f7c/fftools/ffmpeg_filter.c#L710
  --enable-filter=transpose,hflip,vflip
  # configure_input_audio_filter https://github.com/FFmpeg/FFmpeg/blob/45ab5307a6e8c04b4ea91b1e1ccf71ba38195f7c/fftools/ffmpeg_filter.c#L835
  --enable-filter=abuffer
  # negotiate_audio https://github.com/FFmpeg/FFmpeg/blob/41a558fea06cc0a23b8d2d0dfb03ef6a25cf5100/libavfilter/formats.c#L336
  --enable-filter=amix,aresample
)
echo "FFMPEG_CONFIG_FLAGS=${FLAGS[@]}"
emconfigure ./configure "${FLAGS[@]}"

Важной частью являются операторы --enable-filter внизу, мне потребовалось немного исследований, чтобы найти все фильтры, которые FFmpeg может использовать неявно, чтобы у вас их тоже не было. Есть также фильтры null и anull, которые вам понадобятся, если вы не перекодируете, а просто пересобираете файлы.

Если вы сейчас запустите ./build-with-docker.sh (что займет некоторое время), вы получите файл wasm, который может делать только то, что вы указали.

Я создал несколько примеров (все не проверял):

Как видите, отказ от большинства кодировщиков и фильтров резко уменьшит размер конечного пакета. Версия, которую я использую для загрузки клипов в 1/4 от исходного времени.

Как использовать новые файлы?

После того, как вы скомпилируете ffmpeg, вы получите 3 файла в wasm/packages/core/dist:

ffmpeg-core.js
ffmpeg-core.wasm
ffmpeg-core.worker.js

Вам нужно будет сохранить эти файлы в своем проекте, а затем указать расположение файла js в createFFmpeg.

createFFmpeg({
  corePath: new URL(`ffmpeg/custom/ffmpeg-core.js`, document.location as any).href,
});

Есть ли еще причины для пользовательской сборки?

С libfdk_aac могут быть проблемы с патентами, поэтому вы также можете выбрать компиляцию FFmpeg без него и без --enable-nonfree. FFmpeg имеет бесплатный кодировщик aac, который просто называется aac, который вы можете использовать вместо него, что в основном нормально, но не поддерживает некоторые из более продвинутых профилей.

Надеюсь, я помог вам разобраться, как создать собственный файл ffmpeg.wasm.

Не стесняйтесь делиться проектами в комментариях, если хотите. Я хотел бы знать, если эта информация полезна для кого-то.

Также проверьте https://clip.marco.zone/, это инструмент, который я сделал для быстрого вырезания и сжатия видео в браузере. Я горжусь этим.

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord.

Повысьте узнаваемость и признание вашего технического стартапа с помощью Circuit.