【问题标题】:Send MediaStream object with Web Audio effects over PeerConnection通过 PeerConnection 发送带有 Web 音频效果的 MediaStream 对象
【发布时间】:2014-10-17 18:35:46
【问题描述】:

我正在尝试通过来自 WebRTC 的 PeerConnection 发送由getUserMedia() 获得并使用 Web 音频 API 进行更改的音频。 Web Audio API 和 WebRTC 似乎有能力做到这一点,但我无法理解如何做到这一点。在 Web Audio API 中,AudioContext 对象包含一个方法createMediaStreamSource(),它提供了一种连接由 getUserMedia() 获得的 MediaStream 的方法。此外,还有一个createMediaStreamDestination() 方法,它似乎返回一个带有流属性的对象。

我从 getUserMedia() 方法获取音频和视频。我遇到的问题是如何将此流对象(包括音频和视频)传递给这些方法(例如:createMediaStreamSource())?我是否首先需要以某种方式从流中提取音频(getAudioTracks)并找到一种方法将其与视频结合起来?还是我按原样传递它并且它不影响视频?音频只能更改一次(在添加到 PeerConnection 之前)吗?

【问题讨论】:

  • 根据 W3C 的工作草案,createMediaStreamSource() 获取一个 MediaStream 对象,该对象的第一个 AudioMediaStreamTrack 将用作音频源。但是,createMediaStreamDestination() 方法表示一个只有一个 AudioMediaStreamTrack 的 MediaStream 对象。我会做更多的研究,希望能提供答案。

标签: javascript html webrtc web-audio-api


【解决方案1】:

createMediaStreamSource() 方法将MediaStream 对象作为其参数,然后从该对象中获取第一个AudioMediaStreamTrack 作为音频源。这可以与从getUserMedia() 方法接收的 MediaStream 对象一起使用,即使该对象同时包含音频和视频。例如:

var source = context.createMediaStreamSource(localStream);

在上面的代码中,“context”是一个AudioContext 对象,“localStream”是一个从 getUserMedia() 获得的 MediaStream 对象。 createMediaStreamDestination() 方法创建一个目标节点对象,该对象在其“流”属性中具有一个 MediaStream 对象。此 MediaStream 对象仅包含一个 AudioMediaStreamTrack(即使源的输入流包含音频和视频或许多音轨):从源中的流中获得的轨道的更改版本。例如:

var destination = context.createMediaStreamDestination();

现在,在您可以访问新创建的目标变量的流属性之前,您必须通过将所有节点链接在一起来创建音频图。对于此示例,假设我们有一个名为 filter 的 BiquadFilter 节点:

source.connect(filter);
filter.connect(destination);

然后,我们可以从目标变量中获取流属性。这可以用来添加到PeerConnection 对象以发送到远程对等点:

peerConnection.addStream(destination.stream);

注意:stream 属性包含一个 MediaStream 对象,该对象仅具有更改后的 AudioMediaStreamTrack。因此,没有视频。如果您还想发送视频,则必须将此轨道添加到包含视频轨道的流对象中:

var audioTracks = destination.stream.getAudioTracks();
var track = audioTracks[0]; //stream only contains one audio track
localStream.addTrack(track);
peerConnection.addStream(localStream);

请记住,如果 MediaStream 对象中已有具有相同 id 的轨道,addTrack 方法将不会添加轨道。因此,您可能必须先删除在源节点中获取的轨道。

声音应该可以随时通过调整中间节点(源和目标之间)的值来改变。这是因为流在发送到其他对等方之前会通过节点。 Check out this example 动态改变录制声音的效果(对于流应该是相同的)。注意:我还没有测试过这段代码。虽然理论上可行,但可能存在一些跨浏览器问题,因为 Web Audio API 和 WebRTC 都处于工作草案阶段,尚未标准化。我假设它可以在 Mozilla Firefox 和 Google Chrome 中运行。

参考

【讨论】:

    【解决方案2】:

    @Android Student 的反应很好,根据当前的规范 - 但是,Firefox 和 Chrome 在规范的实施中都存在问题。

    上次我在 Chrome 中检查,它无法通过 WebAudio 处理 WebRTC 的输出,而 Firefox 可以。

    但是,有两个错误阻止 Firefox 在 PeerConnection 中获取 WebAudio 生成的源流,其中一个现已在 Nightly & Aurora 中修复,另一个应该很快就会修复。然而,Firefox 还没有实现 stream.addTrack,这是另一个复杂的问题。 Chrome 显然可以在 PeerConnection 中处理来自 WebAudio 的流。

    【讨论】:

    • 我提供的代码似乎可以在 Chrome 中运行,但是,您对 Firefox 尚未实现 stream.addTrack 是正确的。我正在尝试找到解决方法,但似乎不太可能。希望很快在 Firefox 中可以实现更多 MediaStream API 方法。
    猜你喜欢
    • 2014-10-24
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多