此令人沮丧的iOS Safari MediaStream错误(和修复)

我最近刚在一家提供带语音聊天功能的可嵌入网络聊天系统的公司工作。 当我刚加入团队时,由于iOS Safari的许多问题(包括一个本机错误),该产品在iOS上损坏。 这是我固定的方法。

我们的应用程序的设计方式是使用window.open()创建一个新窗口(弹出); 并在子窗口中启动基本的WebRTC调用。 这是持久性所必需的。 使访问者(用户A)继续浏览网站而不会中断呼叫。 这既是用户体验的增强,也是第三方SIP提供程序的要求。

第一个问题是,我们正在使用autoplay属性动态创建一个视频/音频元素-在iOS上不起作用-仅在页面加载时才尊重autoplay属性。 足够简单的解决方案-我们只需要运行.play() ,流就可以播放。 太好了,那很容易。 现在我们的整个解决方案都在起作用!…等等。

由于某种原因,这仅适用于一个呼叫。 任何后续呼叫都将导致座席(用户B)听不到访客(用户A)的声音。 唯一的解决方案是完全重置浏览器。

这很奇怪,因为一切看起来都很好。 我在调试时找不到任何特别之处。

在多个不同的环境中进行测试后,我推断出问题出在关闭弹出窗口(包含WebRTC调用)上。 出于某种原因,似乎Safari无法正确拆除本地MediaStream,这导致输入流无法正常工作。 唯一的解决方法是硬重置浏览器。

值得庆幸的是,我找到了一种方法,使浏览器能够正常关闭弹出窗口,而不会增加调用次数。

我最终偶然发现了一个修复程序-如果刷新或更改了子窗口的位置(如前所述终止了我们的调用),则MediaStream将正确拆除,然后可以关闭该窗口。

有多种方法可以执行此操作,但是这是我的最小方法,您可以在CodeSandbox.io上进行演示

ios-safari-mediastream错误和修复– CodeSandbox

iOS Safari漏洞的最小演示,我对此的修正

codesandbox.io

这将导致WebRTC连接的干净断开,并且座席(用户B)将能够在任何后续呼叫中听到访问者(用户A)。 需要注意的是,如果访问者(用户A)要在执行我们的小小的变通办法之前手动关闭弹出窗口,则将导致相同的错误,并且他们将需要重新启动浏览器。

希望Apple在以后的更新中修复此问题。 从iOS 12开始,这仍然是一个问题。