如何尽快检测网络断开(在 RTCPeerConnection 上)或由此产生的冻结视频?
How to detect network disconnects (on an RTCPeerConnection) as soon as possible or the resulting frozen video?
我正在使用 RTCPeerconnections
在基于 web-RTC 的视频信使中提交视频和音频。我能够在大约 7 秒后检测到网络断开连接 - 然而,这是用户盯着冻结视频并开始随机单击应用程序中的按钮的 7 秒。我想通过缩短这个时间跨度来改善用户体验 - 例如如果视频冻结超过 1 秒,则通知用户网络问题。
现状:我目前正在通过侦听RTCPeerConnection
的onconnectionstatechange
事件来检测各自的情况。然而,该事件仅在断开连接后大约 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/s)。
虽然像 requestsSent 这样的实际 ICE 统计数据似乎更有用,但它们发生的频率要低得多,每秒仅一次,您可能会丢失数据包或延迟。
总的来说,这是一个网络故障检测可靠性的问题。如果它过于激进,你最终会得到糟糕的用户体验,并经常显示警告。
与以引入需要维护的复杂性为代价相比,您最终可能不会好得多。
感谢 Philipp 的见解 - 这为我指明了正确的方向。
我现在正在考虑使用 getStats
来识别任何冻结。乍一看,轮询 framesPerSecond
值对我来说似乎最有希望。好处:它在断开连接时立即做出反应 - 并且 - 当基础视频流暂停时它仍然有效(我允许用户暂停视频提交/通过将所有视频轨道设置为启用 = false 来实现它)。 IE。即使在发送方禁用了视频轨道,接收方仍会继续每秒接收约定的帧数。
由于 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
不一定会变为零,即使 webRTCInternals 屏幕提示相同。当断开连接发生时,我看到 undefined
。
可能需要更仔细地研究以高频率/跨更多连接进行轮询的运行时影响。然而,这似乎是朝着正确方向迈出的良好一步,除非经常这样做。
我正在使用 RTCPeerconnections
在基于 web-RTC 的视频信使中提交视频和音频。我能够在大约 7 秒后检测到网络断开连接 - 然而,这是用户盯着冻结视频并开始随机单击应用程序中的按钮的 7 秒。我想通过缩短这个时间跨度来改善用户体验 - 例如如果视频冻结超过 1 秒,则通知用户网络问题。
现状:我目前正在通过侦听RTCPeerConnection
的onconnectionstatechange
事件来检测各自的情况。然而,该事件仅在断开连接后大约 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/s)。
虽然像 requestsSent 这样的实际 ICE 统计数据似乎更有用,但它们发生的频率要低得多,每秒仅一次,您可能会丢失数据包或延迟。
总的来说,这是一个网络故障检测可靠性的问题。如果它过于激进,你最终会得到糟糕的用户体验,并经常显示警告。 与以引入需要维护的复杂性为代价相比,您最终可能不会好得多。
感谢 Philipp 的见解 - 这为我指明了正确的方向。
我现在正在考虑使用 getStats
来识别任何冻结。乍一看,轮询 framesPerSecond
值对我来说似乎最有希望。好处:它在断开连接时立即做出反应 - 并且 - 当基础视频流暂停时它仍然有效(我允许用户暂停视频提交/通过将所有视频轨道设置为启用 = false 来实现它)。 IE。即使在发送方禁用了视频轨道,接收方仍会继续每秒接收约定的帧数。
由于 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
不一定会变为零,即使 webRTCInternals 屏幕提示相同。当断开连接发生时,我看到 undefined
。
可能需要更仔细地研究以高频率/跨更多连接进行轮询的运行时影响。然而,这似乎是朝着正确方向迈出的良好一步,除非经常这样做。