El contenido de un MediaStreamTrack
se expone como una transmisión que se puede manipular o usar para generar contenido nuevo.
Fondo
En el contexto de la API de Media Capture and Streams, la interfaz MediaStreamTrack
representa una sola pista de medios dentro de una transmisión. Por lo general, se trata de pistas de audio o video, pero pueden existir otros tipos de pistas.
Los objetos MediaStream
constan de cero o más objetos MediaStreamTrack
, que representan varias pistas de audio o video. Cada MediaStreamTrack
puede tener uno o más canales. El canal representa la unidad más pequeña de una transmisión de medios, como una señal de audio asociada a un altavoz determinado, como el izquierdo o el derecho en una pista de audio estéreo.
¿Qué son los streams insertables para MediaStreamTrack
?
La idea principal detrás de los flujos insertables para MediaStreamTrack
es exponer el contenido de un MediaStreamTrack
como una colección de flujos (según lo define la API de Streams de WHATWG). Estos flujos se pueden manipular para introducir componentes nuevos.
Otorgar a los desarrolladores acceso directo a la transmisión de video (o audio) les permite aplicar modificaciones directamente a la transmisión. En cambio, realizar la misma tarea de manipulación de video con métodos tradicionales requiere que los desarrolladores usen intermediarios, como elementos <canvas>
. (Para obtener detalles sobre este tipo de proceso, consulta, por ejemplo, video + lienzo = magia).
Navegadores compatibles
Los streams insertables para MediaStreamTrack
son compatibles a partir de Chrome 94.
Casos de uso
Los casos de uso de los flujos insertables para MediaStreamTrack
incluyen, sin limitaciones, los siguientes:
- Gadgets para videoconferencias, como "sombreros divertidos" o fondos virtuales
- Procesamiento de voz, como vocoders de software
Cómo usar transmisiones insertables para MediaStreamTrack
Detección de características
Puedes detectar la compatibilidad con transmisiones insertables de MediaStreamTrack
de la siguiente manera.
if ('MediaStreamTrackProcessor' in window && 'MediaStreamTrackGenerator' in window) {
// Insertable streams for `MediaStreamTrack` is supported.
}
Conceptos básicos
Los flujos insertables para MediaStreamTrack
se basan en conceptos propuestos anteriormente por WebCodecs y dividen conceptualmente el MediaStreamTrack
en dos componentes:
- El
MediaStreamTrackProcessor
, que consume la fuente de un objetoMediaStreamTrack
y genera un flujo de fotogramas de medios, específicamente objetosVideoFrame
oAudioFrame
. Puedes pensar en esto como un receptor de pista que puede exponer los fotogramas sin codificar de la pista como unReadableStream
. - El
MediaStreamTrackGenerator
, que consume un flujo de fotogramas multimedia y expone una interfazMediaStreamTrack
. Se puede proporcionar a cualquier receptor, al igual que una pista degetUserMedia()
. Toma fotogramas de medios como entrada.
MediaStreamTrackProcessor
Un objeto MediaStreamTrackProcessor
expone una propiedad, readable
. Permite leer los fotogramas de MediaStreamTrack
. Si el segmento es un segmento de video, los fragmentos leídos de readable
serán objetos VideoFrame
. Si la pista es de audio, los fragmentos leídos de readable
serán objetos AudioFrame
.
MediaStreamTrackGenerator
Del mismo modo, un objeto MediaStreamTrackGenerator
expone una propiedad, writable
, que es un WritableStream
que permite escribir fotogramas de medios en el MediaStreamTrackGenerator
, que a su vez es un MediaStreamTrack
. Si el atributo kind
es "audio"
, el flujo acepta objetos AudioFrame
y falla con cualquier otro tipo. Si el tipo es "video"
, el flujo acepta objetos VideoFrame
y falla con cualquier otro tipo. Cuando se escribe un fotograma en writable
, se invoca automáticamente el método close()
del fotograma, de modo que ya no se puede acceder a sus recursos multimedia desde JavaScript.
Un objeto MediaStreamTrackGenerator
es un segmento para el que se puede implementar una fuente personalizada escribiendo fotogramas de medios en su campo writable
.
reunir todo en un solo lugar
La idea principal es crear una cadena de procesamiento de la siguiente manera:
Pista de la plataforma → Procesador → Transformación → Generador → Receptores de la plataforma
En el siguiente ejemplo, se ilustra esta cadena para una aplicación de escáner de códigos de barras que destaca el código de barras detectado en una transmisión de video en 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;
Demostración
Puedes ver la demostración del escáner de códigos QR de la sección anterior en acción en un navegador para computadoras o dispositivos móviles. Sostén un código QR frente a la cámara y la app lo detectará y destacará. Puedes ver el código fuente de la aplicación en GitHub.
Consideraciones de seguridad y privacidad
La seguridad de esta API se basa en los mecanismos existentes en la plataforma web. A medida que los datos se exponen con las interfaces VideoFrame
y AudioFrame
, se aplican las reglas de esas interfaces para tratar los datos contaminados por el origen. Por ejemplo, no se puede acceder a los datos de los recursos de origen cruzado debido a las restricciones existentes para acceder a dichos recursos (p.ej., no es posible acceder a los píxeles de un elemento de imagen o video de origen cruzado). Además, el acceso a los datos multimedia de cámaras, micrófonos o pantallas está sujeto a la autorización del usuario. Los datos de medios que expone esta API ya están disponibles a través de otras APIs.
Comentarios
El equipo de Chromium quiere conocer tu experiencia con los streams insertables para MediaStreamTrack
.
Cuéntanos sobre el diseño de la API
¿Hay algo sobre la API que no funciona como esperabas? ¿O faltan métodos o propiedades que necesitas para implementar tu idea? ¿Tienes alguna pregunta o comentario sobre el modelo de seguridad? Informa un problema de especificación en el repositorio de GitHub correspondiente o agrega tus ideas a un problema existente.
Informa un problema con la implementación
¿Encontraste un error en la implementación de Chromium? ¿O la implementación es diferente de la especificación?
Presenta un error en new.crbug.com. Asegúrate de incluir tantos detalles como sea posible, instrucciones sencillas para reproducir el error y, luego, ingresa Blink>MediaStream
en el cuadro Components.
Cómo mostrar compatibilidad con la API
¿Planeas usar transmisiones insertables para MediaStreamTrack
? Tu apoyo público ayuda al equipo de Chromium a priorizar funciones y muestra a otros proveedores de navegadores lo importante que es admitirlas.
Envía un tuit a @ChromiumDev con el hashtag #InsertableStreams
y cuéntanos dónde y cómo lo usas.
Vínculos útiles
- Borrador de especificaciones
- Explicación
- ChromeStatus
- Error de Chromium
- Revisión del TAG
- Repositorio de GitHub
Agradecimientos
La especificación de los flujos insertables para MediaStreamTrack
fue escrita por Harald Alvestrand y Guido Urdaneta.
Este artículo fue revisado por Harald Alvestrand, Joe Medley, Ben Wagner, Huib Kleinhout y François Beaufort. Imagen hero de Chris Montgomery en Unsplash.