来源:W3C/SMPTE Joint Workshop on Professional Media Production on the Web 主讲人:Christoph Guttandin and Sacha Guddoy 内容整理:张志宇 Christoph Guttandin 介绍了他对行业发展的一些愿望,Sacha Guddoy 则介绍了直播媒体制作中的 WebRTC。
目录
- 无论能做什么,都会做
- 愿望清单
- 更贴合实现者的愿望
- 总结
- 直播媒体制作中的 WebRTC
- Grabyo 简介
- 流同步化的使用场景
- 流同步化的挑战
- MediaStreamTrack 插入流
无论能做什么,都会做
愿望清单
愿望清单
当我被要求为这次研讨会准备演讲时,我认为这是一个向世界表达我们愿望的绝佳机会。因此,我要求我的同事帮助我准备一份清单,其中包含我们希望在某个时候实施或我们已经实施但如果可能的话真正希望以更好的方式实施的东西。
自定义编解码器
自定义编解码器
清单上的第一个项目是将自定义编解码器与 WebRTC 一起使用。你可以通过对音频数据和视频数据进行编码来做到这一点。然后你可以忽略 WebRTC 的媒体功能,并通过 DataChannel 发送数据。但整个过程非常繁琐,至少对于视频来说,它不是很准确。每个视频帧都需要绘制到画布上,然后需要从那里抓取,将其移交给 WebAssembly。当实时使用时,你很可能会丢失几帧。
幸运的是,我们现在可以使用 WebCodecs 以更有效的方式做到这一点。但到目前为止,WebCodecs 仅在 Chromium 浏览器中可用,Firefox 正在研究它。
部分解码
部分解码
清单中的下一个项目是部分解码,指的是只能解码媒体资产的特定范围或者某个特定帧的能力。对于音频来说,有一种非常黑客的方法,它通过使用 decodeAudioData() 方法工作,此方法在 AudioContext 上可用。但它会自动将音频重新采样到 AudioContext 的采样率,这意味着在进行实际解码之前,需要手动解析文件,以了解正确的采样率。decodeAudioData() 仅适用于完整文件,这是在解码前需要解析文件的另一个原因。我们需要弄清楚在哪里可以切片,虽然这并不容易弄清楚,但对于大多数文件类型来说这是可能的。如果操作正确,decodeAudioData() 会很乐意解码文件的一部分,因为它认为它正在解码整个文件。但是,decodeAudioData() 在最新版本的 Safari 浏览器中坏了。该错误已经在代码库中修复,但是不知道该修复程序何时可供 Safari 用户使用。
要解码单个视频帧,可以使用媒体元素加载视频,然后使用 seekToNextFrame() 逐个获取帧。但这只适用于 Firefox。
但是,既然在 Chromium 和 Firefox 中都支持 WebCodecs,所以这些都不再必要了。
下放工作
下放工作
另一件至关重要的事情是尽可能多地将工作下放到其他线程。最后,主线程应该只是用于触发工作,而不是用于操作。
有一些 API 已经遵循了这种模式。其中之一是 AudioWorklet 和 Web Audio API。对于视频内容,有 OffscreenCanvas,可以在 Web Worker 中使用。最后但并非最不重要的是,可以将 TransformStream 插入 MediaStream,并将其传输给 Web Worker。
媒体同步
媒体同步
另一件通常棘手的事情是保持媒体的同步。特别是如果涉及一些音频或视频处理,这通常会延迟其中之一,需要确保当情况变得非常棘手时,音频和视频可以再次实现同步。
AudioContext 上有两个属性,让我们知道用户何时可以真正听到该 AudioContext 上安排的声音。这使我们能够确保当时显示的视频帧与音频匹配。但遗憾的是,到目前为止,这些属性仅在 Firefox 中完全有效。
输出选择
输出选择
对我们来说,另一个热门话题是可以选择特定的输出设备,而不是使用默认的输出设备。
有一种方法可以调用来更改媒体元素的输出设备,但到目前为止,它只适用于 Chromium 浏览器,它被称为 setSinkId()。据我所知,Firefox 目前正在实施 selectAudioOutput() 方法,这是一种同意访问音频输出设备的新方法。
Chromium 浏览器已经公开了音频输出设备。因此,使用 setSinkId() 并不真正需要实现 selectAudioOutput()。
更贴合实现者的愿望
无论如何,我想出了一些不再真正与规格相关的愿望,更适合实现者。
发布应该无聊
该清单上的第一个项目是,我希望发布尽可能无聊。我认为 Chromium 浏览器和 Firefox 确实有一个很好的流程来确保这一点。
nightly 版本
两个浏览器都发布 nightly 版本。现在,这是 Chromium 的 97 版本和 Firefox 的 95 版本。
beta 版本
nightly 版本的状态每 4 周就会升级到下一阶段。无论当时的 nightly 版本是什么,都会成为 beta 版。同样,nightly 版本也会增加。因此,今天这些浏览器的 nightly 版本中的任何内容都将在至少 4 周内进入 beta 版。
stable 版本
再过 4 周后,beta 版成为 stable 版本,nightly 版本成为新的 beta 版。这就像源源不断的更新,当一项功能到达 beta 版频道时,您可以计算它向所有普通用户开放的日期。整个过程非常可预测,也超级无聊。
regrssions 应该被尽快修复
我希望 regrssions 尽快得到修复。想象一下,构建一个媒体专业人士每天依靠的网络应用程序来完成他们的工作。突然,浏览器更新导致该应用程序失败。我知道即使是 Safari 浏览器也可以非常及时地获得安全更新。我也希望补丁能修复 regrssions,这种情况也会发生。
给用户更多权限
我知道一些强大的功能可能会被恶意页面滥用。我绝对同意,默认情况下,每个页面都不应该启用某些功能。然而,我认为浏览器的用户应该可以选择允许某些网站访问文件系统,录制整个屏幕,捕获系统音频,接收MIDI消息,运行高优先级线程等。我认为这在每种情况下都不需要是明确的权限提示。它也可以是一条小小的吐司式消息,弹出来通知用户特定API或完全不同的东西的使用情况。重点是,我认为应该授权用户自行决定他们想要启用哪些功能,以及他们现在最好不想使用哪些功能。
给开发人员更多权限
同样,作为一名开发人员,我真的很想拥有同样的权限。正如我之前所说,我喜欢对每个浏览器的当前和即将发布的版本运行自动测试。我在本地这样做,我也通过 BrowserStack 和 Sauce Labs 等服务在云中这样做。测试媒体API是一个真正的挑战,因为它们通常需要用户交互才能工作。但显然在运行自动测试时没有用户。可以为 Chromium 浏览器和 Firefox 设置标志。但它们并没有很好地记录在案,它们总是落后于浏览器的功能,可悲的是,它们有不时断裂的倾向。至少据我所知,在以编程方式启动浏览器时,甚至无法在 Safari 浏览器中禁用自动播放策略。这意味着在 Safari 浏览器中测试更困难。这反过来意味着错误的捕获更少。这当然是一个真正的问题,因为正如我之前所说,一个典型的错误会在 Safari 浏览器中停留至少 6 个月。
总结
最后,我想再次重复这次演讲的标题:技术的基本规则是,无论能做什么,都会做。我认为为网络构建专业媒体应用程序是今天可以做到的。我知道很多人都在做这件事,我希望并相信,这成为新常态只是时间问题。
附上演讲视频:http://mpvideo.qpic.cn/0bc3jmaboaaatqaps2s35jrfas6dc5fqafya.f10002.mp4?dis_k=dc30a941fc154e61f17ec7413f9f896f&dis_t=1653387775&vid=wxv_2358873498481426432&format_id=10002&support_redirect=0&mmversion=false
直播媒体制作中的 WebRTC
Grabyo 简介
Grabyo 简介
Grabyo 是一个 SaaS 平台,为商业广播公司提供直播制作工具。一些产品包括直播制作、视频编辑、从直播中剪切以及发布到各种端点。
在 Grabyo,我们在现场制作产品中使用 WebRTC。这是工作方式,用户将看到,在他们的网络浏览器中,他们将有多个直播,他们将能够监控这些直播,并选择哪些直播被输出到他们的广播端点。我们还拥有多个边车应用程序和多窗口工作流程。例如,弹出一个播放器。
流同步化的使用场景
流同步化的使用场景
我们面临的挑战之一是流的同步化问题。我们想做的是让来自不同相机的多个直播馈送进来,并能够在它们之间切换。但是,如果我们的直播没有完全同步,如果这两个相机没有完全同步,那么当你在它们之间切换时,它们之间会非常明显,它们之间有一些延迟,这对观众来说很刺耳。
当您的页面上有多个 WebRTC 流时,保持所有这些流的同步不一定是最直截了当的事情。浏览器会尽力而为,但它们没有绑定在一起。因此,例如,如果您在不同的相机之间切割,您希望这些相机完全同时显示。如果您正在进行多方聊天,也不会想要延迟。
流同步化的挑战
流同步化的挑战
同步方面相当困难。网络条件可能是不可预测的,您实际上没有办法纠正这一点,也没有办法与客户端的流同步相协调。如果流上有嵌入式时间戳,那么您可能会这样做,使用较低级别的东西,例如 Web 传输。
在上下文之间共享连接
我们最近使用的一种模式是将工作流程划分为不同的浏览器上下文。能够创建一个弹出窗口,允许您在一个窗口中监控特定视频,并能够在另一个窗口中监控其他所有内容。
或者能够在一个窗口中编辑音频,并在另一个窗口中监控您的视频。在最后一个场景中,您将在浏览器中有两个相同 WebRTC 连接的实例。如果我想将实时流的视频放在一个窗口中,因为这是我的视频控制套件,并且我想在另一个窗口中拥有相同的实时流,因为这是我的音频控制套件,那么我必须有两个 WebRTC 连接。这是头顶性能的两倍,带宽的两倍,等等。
我们考虑了 Shared WebWorkers 的工作方式,即 SharedWorker 界面,该界面允许多个上下文共享该 Worker 中发生的事情。如果我们能对 WebRTC 做同样的事情,这将大大减少我们的性能开销。
对于专业的桌面应用程序来说,这些类型的工作流程非常强大。如果您是使用某种 NLE 的视频编辑器,您可能想要尽可能多的屏幕空间用于时间线、显示器、资产箱等。能够将我们界面的不同部分拆分到不同的窗口中,以便用户可以按照他们认为合适的方式定位它们,这真的很有帮助。
这样做有什么好处?资源消耗显然更少,因为你只有一个连接。上下文之间存在固有的同步,因为数据来自同一连接。现在,使用共享工人和网络传输可能是可能的。但浏览器对此的支持不是特别好。Accuracy 在这项技术中也很重要。更准确的时间戳可能有助于我们同步这些流。此外,它还有助于同步其他内容。例如,在 DOM 中同步覆盖层,或者 DOM 中的通知。
MediaStreamTrack 插入流
MediaStreamTrack 插入流
从WebRTC连接中编码和解码数据的能力也非常有用。目前,WebRTC 连接的 API 表面非常小,它不会向我们公开太多有用的信息。能够将我们自己的代码放入该管道将允许我们做所有这些有趣的事情。
例如,当我们想展示一个特定的框架时,它就会出现。例如,从不同的浏览器窗口同步音频和视频。在它们渲染到 DOM 之前,我们可以确切地知道正在呈现哪个帧,这样我们就可以准备与之同步的 DOM 元素。我们可能会发送专有的错误更正数据,以优先处理任何链接故障,并优先考虑图像质量。
许多问题都可以使用 MediaStreamTrack 插入流功能来解决。这仍在规范草案中,我真的很想看到更多的浏览器支持。
附上演讲视频:
http://mpvideo.qpic.cn/0bc3tmaboaaaliaonas35nrfbg6dc6nqafya.f10002.mp4?dis_k=c1116abfdfaedb3141d6243562d84429&dis_t=1653387775&vid=wxv_2358886009133957121&format_id=10002&support_redirect=0&mmversion=false