Streams inseríveis para MediaStreamTrack

O conteúdo de uma MediaStreamTrack é exposto como um stream que pode ser manipulado ou usado para gerar novo conteúdo.

Contexto

No contexto da API Media Capture e Streams, a interface MediaStreamTrack representa uma única faixa de mídia em um stream. Normalmente, são faixas de áudio ou vídeo, mas podem existir outros tipos de faixa. Objetos MediaStream consistem em zero ou mais objetos MediaStreamTrack, representando várias faixas de áudio ou vídeo. Cada MediaStreamTrack pode ter um ou mais canais. O canal representa a menor unidade de um stream de mídia, por exemplo, um sinal de áudio associado a um determinado alto-falante, como esquerda ou direita em uma faixa de áudio estéreo.

O que são streams inseríveis no MediaStreamTrack?

A ideia principal por trás de streams inseríveis para MediaStreamTrack é expor o conteúdo de um MediaStreamTrack como uma coleção de streams, conforme definido pela API Streams do WhatWG. Esses streams podem ser manipulados para introduzir novos componentes.

Conceder aos desenvolvedores acesso direto ao stream de vídeo (ou áudio) permite que eles apliquem modificações diretamente ao stream. Por outro lado, para realizar a mesma tarefa de manipulação de vídeo com métodos tradicionais, os desenvolvedores precisam usar intermediários, como elementos <canvas>. Para saber mais sobre esse tipo de processo, consulte, por exemplo, video + canvas = magic.

Suporte ao navegador

O Chrome 94 já tem suporte para as transmissões inseríveis de MediaStreamTrack.

Casos de uso

Os casos de uso de streams inseríveis para MediaStreamTrack incluem, entre outros:

  • Dispositivos de videoconferência, como "chapéus engraçados" ou planos de fundo virtuais.
  • Processamento de voz, como vocoders de software.

Como usar streams inseríveis no MediaStreamTrack.

Detecção de recursos

Confira a seguir como detectar streams inseríveis com detecção de recursos para oferecer suporte a MediaStreamTrack.

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

Principais conceitos

Streams inseríveis para MediaStreamTrack se baseiam em conceitos propostos anteriormente pelo WebCodecs e dividem conceitualmente o MediaStreamTrack em dois componentes:

  • O MediaStreamTrackProcessor, que consome a origem de um objeto MediaStreamTrack e gera um fluxo de frames de mídia, mais especificamente objetos VideoFrame ou AudioFrame. Pense nisso como um coletor de faixa capaz de expor os frames não codificados da faixa como um ReadableStream.
  • O MediaStreamTrackGenerator, que consome um stream de frames de mídia e expõe uma interface MediaStreamTrack. Pode ser fornecido a qualquer coletor, como uma faixa de getUserMedia(). Ele usa frames de mídia como entrada.

O MediaStreamTrackProcessor

Um objeto MediaStreamTrackProcessor expõe uma propriedade, readable. Ela permite a leitura dos frames do MediaStreamTrack. Se a faixa for uma faixa de vídeo, os blocos lidos de readable serão objetos VideoFrame. Se a faixa for uma faixa de áudio, os blocos lidos de readable serão objetos AudioFrame.

O MediaStreamTrackGenerator

Um objeto MediaStreamTrackGenerator também expõe uma propriedade, writable, que é uma WritableStream que permite gravar frames de mídia no MediaStreamTrackGenerator, que é uma MediaStreamTrack. Se o atributo kind for "audio", o stream aceitará objetos AudioFrame e falhará com qualquer outro tipo. Se o tipo for "video", o stream aceitará objetos VideoFrame e falhará com qualquer outro tipo. Quando um frame é gravado em writable, o método close() do frame é invocado automaticamente para que os recursos de mídia não possam mais ser acessados no JavaScript.

Um MediaStreamTrackGenerator é uma faixa em que uma origem personalizada pode ser implementada gravando frames de mídia no campo writable.

Resumo geral

A ideia central é criar uma cadeia de processamento desta forma:

Plataforma de rastreamento → Processador → Transformação → Gerador → Coletores de plataforma

O exemplo abaixo ilustra essa cadeia para um aplicativo de leitura de código de barras que destaca o código de barras detectado em um stream de vídeo ao vivo.

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;

Demonstração

Confira a demonstração do leitor de QR code da seção acima em ação em um navegador para computador ou dispositivo móvel. Segure o QR code na frente da câmera para que ele o detecte e destaque. Você pode ver o código-fonte do aplicativo no Glitch.

Leitor de QR code executado na guia do navegador do computador que mostra um QR code detectado e destacado no smartphone que o usuário segura em frente à câmera do laptop.

Considerações sobre segurança e privacidade

A segurança dessa API depende dos mecanismos existentes na plataforma da Web. Como os dados são expostos usando as interfaces VideoFrame e AudioFrame, são aplicadas as regras delas para lidar com dados com taint de origem. Por exemplo, não é possível acessar dados de recursos de origem cruzada devido a restrições atuais de acesso a esses recursos (por exemplo, não é possível acessar os pixels de um elemento de imagem ou vídeo de origem cruzada). Além disso, o acesso a dados de mídia de câmeras, microfones ou telas está sujeito à autorização do usuário. Os dados de mídia que essa API expõe já estão disponíveis em outras APIs.

Feedback

A equipe do Chromium quer saber mais sobre suas experiências com streams inseríveis para MediaStreamTrack.

Fale sobre o design da API

Há algo na API que não funciona como você esperava? Ou há métodos ou propriedades ausentes que você precisa para implementar sua ideia? Você tem alguma dúvida ou comentário sobre o modelo de segurança? Registre um problema de especificação no repositório do GitHub correspondente ou adicione suas ideias a um problema atual.

Informar um problema com a implementação

Você encontrou um bug na implementação do Chromium? Ou a implementação é diferente da especificação? Registre um bug em new.crbug.com. Inclua o máximo de detalhes possível, instruções simples para reprodução e insira Blink>MediaStream na caixa Componentes. O Glitch funciona muito bem para compartilhar repetições rápidas e fáceis.

Mostrar suporte à API

Você planeja usar transmissões inseríveis para MediaStreamTrack? Seu apoio público ajuda a equipe do Chromium a priorizar recursos e mostra a outros fornecedores de navegadores como é fundamental oferecer suporte a eles.

Envie um tweet para @ChromiumDev usando a hashtag #InsertableStreams e conte para nós onde e como você está usando a hashtag.

Agradecimentos

Os streams inseríveis para a especificação MediaStreamTrack foram escritos por Harald Alvestrand e Guido Urdaneta. Este artigo foi revisado por Harald Alvestrand, Joe Medley, Ben Wagner, Huib Kleinhout e François Beaufort. Imagem principal de Chris Montgomery no Unsplash (links em inglês).