Опубликовано: 4 мая 2021 г.
В контексте API захвата и потоковой передачи мультимедиа интерфейс MediaStreamTrack представляет собой отдельную дорожку мультимедиа в потоке. Как правило, это аудио- или видеодорожки, но могут существовать и другие типы дорожек.
Объекты MediaStream состоят из нуля или более объектов MediaStreamTrack , представляющих различные аудио- или видеодорожки. Каждый объект MediaStreamTrack может иметь один или несколько каналов. Канал представляет собой наименьшую единицу медиапотока, например, аудиосигнал, связанный с определенным динамиком, таким как левый или правый в стереофонической аудиодорожке.
Что представляют собой вставляемые потоки для MediaStreamTrack ?
Основная идея вставляемых потоков для MediaStreamTrack заключается в том, чтобы представить содержимое MediaStreamTrack в виде набора потоков (как определено в API потоков WHATWG). Эти потоки можно изменять для добавления новых компонентов.
Предоставление разработчикам прямого доступа к видео (или аудио) потоку позволяет им вносить изменения непосредственно в поток. В отличие от этого, реализация той же задачи манипулирования видео традиционными методами требует от разработчиков использования промежуточных элементов, таких как элементы <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-код к камере, и приложение распознает его и выделит. Исходный код приложения можно посмотреть на GitHub .

Вопросы безопасности и конфиденциальности
Безопасность этого API основана на существующих механизмах веб-платформы. Поскольку данные предоставляются через интерфейсы VideoFrame и AudioFrame , применяются правила этих интерфейсов для обработки данных, содержащих информацию из разных источников. Например, доступ к данным из ресурсов, находящихся в разных источниках, невозможен из-за существующих ограничений на доступ к таким ресурсам (например, невозможно получить доступ к пикселям изображения или видеоэлемента, находящегося в другом источнике). Кроме того, доступ к медиаданным с камер, микрофонов или экранов осуществляется только после авторизации пользователя. Медиаданные, предоставляемые этим API, уже доступны через другие API.
Обратная связь
Команда Chromium хочет узнать о вашем опыте использования вставляемых потоков в MediaStreamTrack .
Расскажите о проектировании API.
Есть ли что-то в API, что работает не так, как вы ожидали? Или отсутствуют методы или свойства, необходимые для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности? Создайте заявку в соответствующем репозитории GitHub или добавьте свои мысли в существующую заявку.
Сообщить о проблеме с реализацией
Вы обнаружили ошибку в реализации Chromium? Или реализация отличается от спецификации? Сообщите об ошибке на new.crbug.com . Обязательно укажите как можно больше подробностей, инструкции по воспроизведению и введите Blink>MediaStream в поле «Компоненты» .
Поддержка API
Вы планируете использовать вставляемые потоки для MediaStreamTrack ? Ваша публичная поддержка помогает команде Chromium расставлять приоритеты в разработке функций и показывает другим разработчикам браузеров, насколько важно их поддерживать.
Отправьте твит @ChromiumDev , используя хэштег #InsertableStreams , и расскажите, где и как вы его используете.
Полезные ссылки
Благодарности
Спецификация MediaStreamTrack для вставляемых потоков была написана Харальдом Альвестрандом и Гвидо Урданетой . Ее рецензировали Харальд Альвестранд, Джо Медли , Бен Вагнер , Хуиб Кляйнхаут и Франсуа Бофор .