Вставляемые потоки для MediaStreamTrack

Содержимое MediaStreamTrack представляется как поток, которым можно манипулировать или использовать для создания нового контента.

Фон

В контексте API захвата и потоков мультимедиа интерфейс MediaStreamTrack представляет собой одну дорожку мультимедиа в потоке; обычно это аудио- или видеодорожки, но могут существовать и другие типы дорожек. Объекты MediaStream состоят из нуля или более объектов MediaStreamTrack , представляющих различные аудио- или видеодорожки. Каждый MediaStreamTrack может иметь один или несколько каналов. Канал представляет собой наименьшую единицу медиапотока, например аудиосигнал, связанный с данным динамиком, например, левым или правым на стереофонической звуковой дорожке.

Что такое вставляемые потоки для MediaStreamTrack ?

Основная идея вставляемых потоков для MediaStreamTrack — представить содержимое MediaStreamTrack как коллекцию потоков (как определено API WHATWG Streams ). Этими потоками можно манипулировать для введения новых компонентов.

Предоставление разработчикам доступа к видео (или аудио) потоку напрямую позволяет им вносить изменения непосредственно в поток. Напротив, реализация той же задачи манипулирования видео традиционными методами требует от разработчиков использования посредников, таких как элементы <canvas> . (Подробнее об этом типе процесса см., например, видео + холст = магия .)

Поддержка браузера

Вставляемые потоки для MediaStreamTrack поддерживаются начиная с Chrome 94.

Случаи использования

Варианты использования вставляемых потоков для MediaStreamTrack включают, помимо прочего:

  • Гаджеты для видеоконференций, такие как «забавные шляпы» или виртуальные фоны.
  • Обработка голоса, подобная программным вокодерам .

Как использовать вставляемые потоки для MediaStreamTrack

Обнаружение функций

Вы можете обнаружить вставляемые потоки для поддержки MediaStreamTrack следующим образом.

if ('MediaStreamTrackProcessor' in window && 'MediaStreamTrackGenerator' in window) {
  // Insertable streams for `MediaStreamTrack` is supported.
}

Основные понятия

Вставляемые потоки для MediaStreamTrack основаны на концепциях, ранее предложенных WebCodecs , и концептуально разделяют MediaStreamTrack на два компонента:

  • MediaStreamTrackProcessor , который использует источник объекта MediaStreamTrack и генерирует поток медиакадров, в частности объектов VideoFrame или AudioFrame ). Вы можете думать об этом как о приемнике дорожек, который способен отображать незакодированные кадры дорожки как ReadableStream .
  • MediaStreamTrackGenerator , который принимает поток медиакадров и предоставляет интерфейс MediaStreamTrack . Его можно передать любому приемнику, как и трек из getUserMedia() . В качестве входных данных он принимает медиакадры.

MediaStreamTrackProcessor

Объект MediaStreamTrackProcessor предоставляет одно свойство — readable . Это позволяет читать кадры из MediaStreamTrack . Если дорожка является видеодорожкой, фрагменты, считанные из readable , будут объектами VideoFrame . Если дорожка является звуковой дорожкой, фрагменты, считываемые из readable будут объектами AudioFrame .

MediaStreamTrackGenerator

Объект MediaStreamTrackGenerator также предоставляет одно свойство, writable , которое представляет собой WritableStream , позволяющее записывать медиакадры в MediaStreamTrackGenerator , который сам по себе является MediaStreamTrack . Если атрибут kind имеет значение "audio" , поток принимает объекты AudioFrame и не работает с любым другим типом. Если kind — "video" , поток принимает объекты VideoFrame и не работает с любым другим типом. Когда фрейм записывается в writable , автоматически вызывается метод close() фрейма, так что его медиа-ресурсы больше не доступны из JavaScript.

MediaStreamTrackGenerator — это дорожка, для которой можно реализовать собственный источник путем записи медиакадров в его writable поле.

Собираем все это вместе

Основная идея состоит в том, чтобы создать цепочку обработки следующим образом:

Платформа Трек → Процессор → Преобразование → Генератор → Приемники платформы

Пример ниже иллюстрирует эту цепочку для приложения сканера штрих-кода, которое выделяет обнаруженный штрих-код в реальном видеопотоке.

const stream = await getUserMedia({ video: true });
const videoTrack = stream.getVideoTracks()[0];

const trackProcessor = new MediaStreamTrackProcessor({ track: videoTrack });
const trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });

const transformer = new TransformStream({
  async transform(videoFrame, controller) {
    const barcodes = await detectBarcodes(videoFrame);
    const newFrame = highlightBarcodes(videoFrame, barcodes);
    videoFrame.close();
    controller.enqueue(newFrame);
  },
});

trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable);

const videoBefore = document.getElementById('video-before');
const videoAfter = document.getElementById('video-after');
videoBefore.srcObject = stream;
const streamAfter = new MediaStream([trackGenerator]);
videoAfter.srcObject = streamAfter;

Демо

Вы можете увидеть демонстрацию сканера QR-кода из раздела выше в действии на настольном компьютере или в мобильном браузере. Поднесите QR-код к камере, и приложение обнаружит его и выделит. Посмотреть исходный код приложения можно на Glitch .

Сканер QR-кода, работающий на вкладке браузера настольного компьютера, показывает обнаруженный и выделенный QR-код на телефоне, который пользователь держит перед камерой ноутбука.

Соображения безопасности и конфиденциальности

Безопасность этого API зависит от существующих механизмов веб-платформы. Поскольку данные предоставляются с помощью интерфейсов VideoFrame и AudioFrame , применяются правила этих интерфейсов для работы с данными, испорченными источником. Например, к данным из ресурсов перекрестного происхождения нельзя получить доступ из-за существующих ограничений на доступ к таким ресурсам (например, невозможно получить доступ к пикселям изображения или видеоэлемента перекрестного происхождения). Кроме того, доступ к медиаданным с камер, микрофонов или экранов требует авторизации пользователя. Медиаданные, предоставляемые этим API, уже доступны через другие API.

Обратная связь

Команда Chromium хочет услышать о вашем опыте использования вставляемых потоков для MediaStreamTrack .

Расскажите нам о дизайне API

Что-то в API работает не так, как вы ожидали? Или вам не хватает методов или свойств, необходимых для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности? Сообщите о проблеме спецификации в соответствующем репозитории GitHub или добавьте свои мысли к существующей проблеме.

Сообщить о проблеме с реализацией

Вы нашли ошибку в реализации Chromium? Или реализация отличается от спецификации? Сообщите об ошибке на сайте new.crbug.com . Обязательно укажите как можно больше подробностей, простые инструкции по воспроизведению и введите Blink>MediaStream в поле «Компоненты» . Glitch отлично подходит для быстрого и простого обмена репродукциями.

Показать поддержку API

Планируете ли вы использовать вставляемые потоки для MediaStreamTrack ? Ваша публичная поддержка помогает команде Chromium расставлять приоритеты в функциях и показывает другим поставщикам браузеров, насколько важно их поддерживать.

Отправьте твит @ChromiumDev , используя хэштег #InsertableStreams , и сообщите нам, где и как вы его используете.

Благодарности

Вставляемые потоки для спецификации MediaStreamTrack написали Харальд Альвестранд и Гвидо Урданета . Эту статью рецензировали Харальд Альвестранд, Джо Медли , Бен Вагнер , Хьюб Кляйнхаут и Франсуа Бофорт . Изображение героя Криса Монтгомери на Unsplash .