Flux insérables pour MediaStreamTrack

Le contenu d'un MediaStreamTrack est exposé sous forme de flux pouvant être manipulé ou utilisé pour générer de nouveaux contenus.

Contexte

Dans le contexte de l'API Media Capture and Streams, l'interface MediaStreamTrack représente une seule piste multimédia dans un flux. Il s'agit généralement de pistes audio ou vidéo, mais d'autres types de pistes peuvent exister. Les objets MediaStream sont constitués de zéro, un ou plusieurs objets MediaStreamTrack, représentant différentes pistes audio ou vidéo. Chaque MediaStreamTrack peut avoir un ou plusieurs canaux. Le canal représente la plus petite unité d'un flux multimédia, tel qu'un signal audio associé à un locuteur donné, par exemple gauche ou droit dans une piste audio stéréo.

Qu'est-ce que les flux insérables pour MediaStreamTrack ?

L'idée de base derrière les flux insérables pour MediaStreamTrack est d'exposer le contenu d'un MediaStreamTrack en tant que collection de flux (tel que défini par l'API Streams WHATWG). Ces flux peuvent être manipulés pour introduire de nouveaux composants.

Accorder aux développeurs l'accès direct au flux vidéo (ou audio) leur permet d'y appliquer directement des modifications. En revanche, pour effectuer la même tâche de manipulation vidéo avec des méthodes traditionnelles, les développeurs doivent utiliser des intermédiaires tels que des éléments <canvas>. (Pour en savoir plus sur ce type de processus, consultez, par exemple, vidéo + canevas = magie.)

Prise en charge des navigateurs

Les flux insérables pour MediaStreamTrack sont compatibles à partir de Chrome 94.

Cas d'utilisation

Voici quelques exemples de cas d'utilisation des flux insérables pour MediaStreamTrack:

  • Gadgets de visioconférence tels que des "chapeaux rigolos" ou des arrière-plans virtuels
  • Traitement de la voix, comme les vocoders logiciels.

Utiliser des flux insérables pour MediaStreamTrack

Détection de caractéristiques

Vous pouvez détecter les flux insérables pour la prise en charge de MediaStreamTrack comme suit.

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

Concepts fondamentaux

Les flux insérables pour MediaStreamTrack s'appuient sur des concepts précédemment proposés par WebCodecs et divisent conceptuellement le MediaStreamTrack en deux composants:

  • MediaStreamTrackProcessor, qui consomme la source d'un objet MediaStreamTrack et génère un flux de frames multimédias, en particulier des objets VideoFrame ou AudioFrame. Vous pouvez le considérer comme un récepteur de piste capable d'exposer les frames non encodés de la piste en tant que ReadableStream.
  • MediaStreamTrackGenerator, qui consomme un flux de frames multimédias et expose une interface MediaStreamTrack. Elle peut être fournie à n'importe quel récepteur, tout comme une piste de getUserMedia(). Il utilise des frames multimédias en entrée.

MediaStreamTrackProcessor

Un objet MediaStreamTrackProcessor expose une propriété, readable. Elle permet de lire les frames à partir de MediaStreamTrack. Si le canal est un canal vidéo, les segments lus à partir de readable seront des objets VideoFrame. Si la piste est une piste audio, les fragments lus à partir de readable seront des objets AudioFrame.

MediaStreamTrackGenerator

Un objet MediaStreamTrackGenerator expose également une propriété, writable, qui est un WritableStream qui permet d'écrire des frames multimédias dans le MediaStreamTrackGenerator, qui est lui-même un MediaStreamTrack. Si l'attribut kind est "audio", le flux accepte les objets AudioFrame et échoue avec tout autre type. Si le genre est "video", le flux accepte les objets VideoFrame et échoue avec tout autre type. Lorsqu'un frame est écrit dans writable, la méthode close() du frame est automatiquement appelée, de sorte que ses ressources multimédias ne soient plus accessibles depuis JavaScript.

Un MediaStreamTrackGenerator est une piste pour laquelle une source personnalisée peut être implémentée en écrivant des frames multimédias dans son champ writable.

Conclusion

L'idée centrale est de créer une chaîne de traitement comme suit:

Canal de la plate-forme → Processeur → Transformation → Générateur → Émetteurs de la plate-forme

L'exemple ci-dessous illustre cette chaîne pour une application de lecteur de code-barres qui met en surbrillance le code-barres détecté dans un flux vidéo en direct.

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;

Démo

Vous pouvez voir la démo du lecteur de code QR de la section ci-dessus en action dans un navigateur pour ordinateur ou mobile. Pointez un code QR devant l'appareil photo. L'application le détectera et le surlignera. Vous pouvez consulter le code source de l'application sur Glitch.

Lecteur de code QR exécuté dans l&#39;onglet du navigateur pour ordinateur, affichant un code QR détecté et mis en surbrillance sur le téléphone que l&#39;utilisateur tient devant la caméra de l&#39;ordinateur portable.

Considérations sur la sécurité et la confidentialité

La sécurité de cette API repose sur les mécanismes existants de la plate-forme Web. Comme les données sont exposées à l'aide des interfaces VideoFrame et AudioFrame, les règles de ces interfaces pour gérer les données contaminées par l'origine s'appliquent. Par exemple, les données des ressources multi-origines ne sont pas accessibles en raison des restrictions existantes sur l'accès à ces ressources (par exemple, il n'est pas possible d'accéder aux pixels d'un élément image ou vidéo multi-origine). De plus, l'accès aux données multimédias provenant des caméras, des micros ou des écrans est soumis à l'autorisation de l'utilisateur. Les données multimédias exposées par cette API sont déjà disponibles via d'autres API.

Commentaires

L'équipe Chromium souhaite en savoir plus sur votre expérience avec les flux insérables pour MediaStreamTrack.

Parlez-nous de la conception de l'API

L'API ne fonctionne-t-elle pas comme prévu ? Ou manque-t-il des méthodes ou des propriétés dont vous avez besoin pour implémenter votre idée ? Avez-vous une question ou un commentaire sur le modèle de sécurité ? Signalez un problème de spécification dans le dépôt GitHub correspondant ou ajoutez vos commentaires à un problème existant.

Signaler un problème d'implémentation

Avez-vous trouvé un bug dans l'implémentation de Chromium ? Ou l'implémentation est-elle différente des spécifications ? Signalez un bug sur new.crbug.com. Veillez à inclure autant de détails que possible, des instructions simples pour reproduire le problème et saisissez Blink>MediaStream dans le champ Composants. Glitch est idéal pour partager des reproductions rapidement et facilement.

Apportez votre soutien à l'API

Prévoyez-vous d'utiliser des flux insérables pour MediaStreamTrack ? Votre soutien public aide l'équipe Chromium à hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge.

Envoyez un tweet à @ChromiumDev avec le hashtag #InsertableStreams et indiquez-nous où et comment vous l'utilisez.

Remerciements

Les flux insérables de la spécification MediaStreamTrack ont été écrits par Harald Alvestrand et Guido Urdaneta. Cet article a été relu par Harald Alvestrand, Joe Medley, Ben Wagner, Huib Kleinhout et François Beaufort. Image héros de Chris Montgomery sur Unsplash.