webRTC如何判断是否有音频

webRTC how to tell if there is audio

我将 WebRTC 与 Asterisk 一起使用,并且在大约 5% 的时间内出现错误,其中由于信号错误而没有音频。简单的解决方法是,如果没有音频通过,则停止连接并重试。当我解决真正的问题时,我知道这是创可贴。不过现在,我会修改我的代码。

要获取音频,我正在执行以下操作:

var remoteStream = new MediaStream();
peerConnection.getReceivers().forEach((receiver) => {
  remoteStream.addTrack(receiver.track);
});
callaudio.srcObject = remoteStream;
callaudio.play();

这里的问题是远程流总是添加一个音轨,即使没有音频从扬声器中传出。

如果您检查 chrome://webrtc-internals,您可以看到没有音频被发送,但仍然有一个接收器。您可以查看媒体流,发现确实有音轨。一切都支持我应该听到一些东西的事实,但有 5% 的时间我什么也没听到。

我的解决方案是从接收器轨道获取数据并检查那里是否有任何东西经过,但我不知道如何读取该数据。我有 web audio API working but it only works if there is some sound currently being played. Sometimes the person on the other end does not talk for 10 seconds. I need a way to read the raw data and see that something is going across that. I just want to know is there ANY data on a MediaStream!

如果你这样做 remoteStream.getAudioTracks() 你会得到一个音轨,因为有一个音轨,只是没有音频穿过那个音轨。

简单的技巧是:

在第一秒播放回服务器 1hz 音调。

如果服务器在第一秒得到它,服务器播放2hz,如果没有,播放1hz。

如果客户端没有从服务器返回 2hz,它会重新启动。

请注意,执行此操作时您应该被静音。

在最新的 API 中,receiver.track 在建立连接之前就存在,即使它未被使用,所以您不应该从它的存在中推断出任何东西。

至少有 5 种方法可以检查何时协商了音频接收:

  1. 追溯:检查receiver.track.muted。远程轨道诞生 muted,并收到一个 unmute 事件 if/once 数据到达:

    audioReceiver.track.onunmute = () => console.log("Audio data arriving!");
    
  2. 主动:使用pc.ontracktrack 事件作为协商的结果被触发,但仅针对将接收数据的轨道。 trackEvent.track.kind == "audio" 的事件意味着会有音频。
  3. 自动:使用trackEvent.streams[0]中提供的远程流而不是你自己的(假设对方在addTrack中添加了一个)。 RTCPeerConnection 仅根据协商的内容填充此连接(除非收到音频,否则不存在音轨)。
  4. 统一计划:检查transceiver.direction"sendrecv""recvonly"表示您正在接收一些东西; "sendonly""inactive" 表示您不是。
  5. 超越协商:使用 getStats() 检查 "inbound-rtp" 统计数据中 .kind == "audio".packetsReceived 以查看数据包是否在流动。

前四个是对协商内容的确定性检查。第五个是只有当其他一切都检查完毕,但由于某种原因您仍然收不到音频时。

所有这些工作,无论音频是否静音,如您所要求(您的问题实际上是关于协商的内容,而不是关于可听见的内容)。

有关这方面的更多信息,请查看 my blog 以及 Chrome 和 Firefox 中的工作示例。