适用于 MediaStreamTrack 的可插入流

MediaStreamTrack 的内容以数据流的形式公开,可被操纵或用于生成新内容

背景

Media Capture API 和 Streams API MediaStreamTrack 代表音频流中的单个媒体轨道的界面;通常是音频或视频 但也可能存在其他轨道类型。 MediaStream 对象包含 零个或多个 MediaStreamTrack 对象,表示各种音频轨道或视频轨道。每个 MediaStreamTrack 可以有一个或多个频道。渠道是指 媒体流,如与给定讲话人相关联的音频信号,如 立体声音轨。

什么是 MediaStreamTrack 的可插入流?

可插入 MediaStreamTrack 的流的核心思路是:公开 MediaStreamTrack 作为数据流的集合(由 WHATWG 定义) Streams API)。可以对这些信息流进行操纵,以引入新的 组件。

向开发者直接授予对视频(或音频)流的访问权限后,开发者就可以申请 直接对流进行修改。相比之下,使用 传统方法需要开发者使用 <canvas> 元素等中介。( 此类流程的详细信息,请参阅 视频 + 画布 = 魔法。)

浏览器支持

Chrome 94 及以上版本支持 MediaStreamTrack 的可插入视频流。

使用场景

MediaStreamTrack 的可插入信息流的用例包括但不限于:

  • 视频会议小工具,例如“搞笑帽子”或虚拟背景
  • 像软件声码器一样的语音处理。

如何使用适用于 MediaStreamTrack 的可插入信息流

功能检测

您可以对 MediaStreamTrack 支持进行功能检测,如下所示。

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

核心概念

适用于 MediaStreamTrack 的可插入流基于 WebCodecs,并从概念上将 MediaStreamTrack 一分为二 组件:

  • MediaStreamTrackProcessor,它使用 MediaStreamTrack 对象的源并生成 媒体帧流,特别是 VideoFrameAudioFrame) 对象。您可以把 它就像一个轨道接收器,能够将轨道中的未编码帧公开为 ReadableStream
  • MediaStreamTrackGenerator,它负责接收媒体帧流并公开 MediaStreamTrack 接口。它可以提供给任何接收器,就像 getUserMedia()。它接受媒体帧作为输入。

MediaStreamTrackProcessor

MediaStreamTrackProcessor 对象公开了一个属性,即 readable。它支持读取 来自 MediaStreamTrack 的帧。如果此轨道是视频轨道 从 readable 读取的区块将是 VideoFrame 对象。如果曲目为音轨,则分块 从 readable 读取的将是 AudioFrame 对象。

MediaStreamTrackGenerator

MediaStreamTrackGenerator 对象同样会公开一个属性 writable,该属性是 WritableStream,允许将媒体帧写入 MediaStreamTrackGenerator,它本身就是一个 MediaStreamTrack。如果 kind 属性为 "audio" 时,流接受 AudioFrame 对象,但会因任何其他类型而失败。如果种类为 "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;

演示

您可以参阅上文中的二维码扫描器演示 在桌面浏览器或移动浏览器中的实际应用。将二维码置于摄像头前,应用就会 检测并突出显示。您可以看到应用的源代码

在桌面浏览器标签页中运行的二维码扫描器,显示用户在手机上检测到的二维码并突出显示在笔记本电脑摄像头前。

安全与隐私注意事项

此 API 的安全性取决于网络平台中的现有机制。由于数据是使用 VideoFrameAudioFrame 接口,要处理这些接口的规则 受来源污点的数据适用。例如,由于以下原因,跨域资源无法访问 对访问此类资源的现有限制(例如,无法访问 跨源图片或视频元素)。此外,还可以通过摄像头、麦克风、 或屏幕需要经过用户授权。此 API 公开的媒体数据已经可用 通过其他 API 实现

反馈

Chromium 团队希望了解您在使用面向 MediaStreamTrack

向我们介绍 API 设计

API 是否有什么无法按预期运行?或者是否缺少方法 需要哪些资源或属性来实现您的想法?如果您对 安全模型?在相应的 GitHub 代码库中提交规范问题,或添加您的想法 现有问题。

报告实现存在的问题

您是否发现了 Chromium 实现方面的错误?或者,实现是否与规范不同? 在 new.crbug.com 上提交 bug。请务必提供尽可能多的细节信息 简单的重现说明,并在组件框中输入 Blink>MediaStreamGlitch 非常适用于分享轻松快速的重现问题。

表示对 API 的支持

您打算为“MediaStreamTrack”使用可插入的视频流吗?你的公开支持将帮助 Chromium 团队会优先处理各项功能,并向其他浏览器供应商展示提供支持的重要性 。

使用 # 标签向 @ChromiumDev 发送推文 #InsertableStreams 并告诉我们您使用它的地点和方式。

致谢

MediaStreamTrack 规范的可插入流由以下文档编写: Harald AlvestrandGuido Urdaneta。 本文由 Harald Alvestrand、Joe MedleyBen WagnerHuib KleinhoutFrançois Beaufort。主打图片提供方 Chris Montgomery,来自: 不启动