如何尽快检测网络断开连接(在RTCPeerConnection上)或由此产生的冻结视频



我使用RTCPeerconnections在基于web RTC的视频信使中提交视频和音频。我能够在大约7秒钟后检测到网络断开连接——然而,在这7秒钟里,用户正盯着冻结的视频,并开始随机点击应用程序中的按钮。我想通过缩短这个时间跨度来改善用户体验,例如,如果视频冻结超过1秒,就通知用户网络问题。

现状:我目前正在通过监听RTCPeerConnectiononconnectionstatechange事件来检测各自的情况。然而,该事件仅在断开连接约7秒后启动。我通过正常的WiFi连接两台机器,使用其中一台笔记本电脑上的硬件开关关闭无线连接(联想的一些旧型号上有这样的开关/保证立即断开连接(,等待另一台机器检测到事件,从而确定了大约7秒的时间。

考虑:根本原因是底层网络连接中断,最好尽早检测到更改的网络状态(即使只是传输延迟(。也就是说,用户面临的干扰最终源于中断网络时立即冻结的视频。如果之前无法检测到连接问题,可以选择检测冻结的视频。这两件事中的任何一件都可能吗(理想情况下是事件驱动的,这样我就不需要每秒轮询一次(?

下面是一个非常简单的代码片段,描述了我当前的断开检测:

myRTCPeerConnection.onconnectionstatechange = (event: Event) => {
let newCS = myRTCPeerConnection.connectionState;
if (newCS == "disconnected" || newCS == "failed" || newCS == "closed") {
//do something on disconnect - e.g. show messages to user and start reconnect
}
}

(ice(connectionstatechange通常是正确的事件。

如果你想要更多的粒度,你需要轮询getStats并查找像framesReceived这样的统计信息。但无法保证从另一端发送的帧速率(例如,在屏幕共享中,帧速率低于1秒(。

虽然像requestsSent这样的实际ICE统计数据似乎更有用,但它们发生的频率要低得多,每秒只有一次,你可能会丢失数据包或数据包来得晚。

一般来说,这是一个网络故障检测的可靠性问题。如果检测过于激进,你最终会得到糟糕的用户体验,并经常显示警告。你可能不会以引入你需要维护的复杂性为代价,这样做会好得多。

感谢Philipp的真知灼见-这为我指明了正确的方向。

我现在正在研究使用getStats来识别任何冻结。乍一看,轮询framesPerSecond值对我来说似乎是最有希望的。好的一面是:它在断开连接时立即做出反应,而且当底层视频流暂停时它仍然有效(我允许用户暂停视频提交/通过将所有视频轨道设置为enabled=false来实现它(。即,即使发送端禁用了视频轨道,接收端仍然继续每秒接收商定的帧。

由于getStats函数的使用在编写本文时在文档中显得很弱/很少有简单的使用示例,请在下面找到我的代码摘要:

peerRTCPC
.getReceivers()
.forEach(
(
receiver: RTCRtpReceiver,
index: number,
array: RTCRtpReceiver[]
) => {
if (receiver.track.kind == "video") {
receiver.getStats().then((myStatsReport: RTCStatsReport) => {
myStatsReport.forEach(
(statValue: any, key: string, parent: RTCStatsReport) => {
if (statValue.type == "inbound-rtp") {
console.log(
"The PC stats returned the framesPerSecond value " +
statValue["framesPerSecond"] +
" while the full inbound-rtp stats reflect as " +  
JSON.stringify(statValue)
);
}
}
);
});
}
}
);

请注意,断开连接后,framesPerSecond不一定会变为零,即使webRTCInternal屏幕也会提示相同的情况。断开连接时,我看到undefined

可能需要更仔细地研究以高频率/跨大量连接进行轮询的运行时影响。然而,这似乎是朝着正确方向迈出的一大步,除非经常这样做。

最新更新