首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebRTC从WKWebView AVAudioSession开发路障运行

WebRTC从WKWebView AVAudioSession开发路障运行
EN

Stack Overflow用户
提问于 2022-03-15 14:12:35
回答 1查看 739关注 0票数 2

在过去的几年中,我稳步地开发了一个完整的基于WebRTC的浏览器电话,使用的是SIP协议。主要的SIP工具箱是SIPJS (https://sipjs.com/),它提供了进行和接收对基于SIP的PBX的调用所需的所有工具。

Browser Phone项目:https://github.com/InnovateAsterisk/Browser-Phone/为SIPJS提供了完整的功能和UI。您可以在浏览器中导航到电话并开始使用它。一切都会完美无缺。

On Mobile

苹果终于允许WebRTC (getUserMedia())在WKWebView上运行,所以不久之后人们就开始问它如何在手机上工作。虽然UI非常适合手机和平板电脑,但现在仅仅UI还不足以成为一个完整的解决方案。

主要考虑的是,移动应用通常具有较短的使用寿命,因为你不能或不让它在后台运行,就像在PC上使用浏览器一样。这对真正使浏览器手机更加友好提出了一些挑战。iOS想要尽快关闭应用程序,只要它不是最前面的应用程序--这是正确的。因此,有一些工具可以处理这些问题,比如Callkit & Push通知。这样,应用程序就可以被唤醒,这样它就可以接受呼叫,并通知用户。

请记住,这个应用程序是通过打开UIViewController、添加WKWebView和导航到电话页面来创建的。应用程序和html & Javascript之间有完全的通信,因此事件可以来回传递。

WKWebView & AVAudioSession发行

在阅读了大量未解决的论坛帖子后,很明显,AVAudioSession.sharedInstance()根本没有连接到WKWebView,或者有一些无文档的连接。

结果是,如果调用从应用程序开始,并发送到后台,麦克风就会被禁用。显然,如果你在打电话的话,这不是一种选择。现在,我可以通过将应用程序发送到后台时暂停调用来管理这个限制--尽管这会让用户和用户体验差的感到困惑。

然而,真正的问题是,如果应用程序是从Callkit中唤醒的,因为应用程序从来不进入前台(因为Callkit是),麦克风一开始就不会被激活,即使你对应用程序做了女巫,它也不会在那之后激活。这只是一个不可接受的用户体验

我发现有趣的是,如果您只需在iOS (15.x)上打开Safari浏览器,并导航到电话页面:https://www.innovateasterisk.com/phone/ (无需在xCode中制作应用程序并将其加载到WKWebView中),则当应用程序被发送到后台时,麦克风将继续工作。那么Safari是如何做到这一点的呢?当然,这不能也不能解决CallKit问题,但是仍然感兴趣的是,Safari可以使用后台的麦克风,因为Safari是基于WKWebView构建的。

(我读到有关应享权利的文章,这可能需要特别批准.我不知道这是怎么回事?)

AVAudioSession的下一个问题是,由于无法访问WkWebView的会话,所以不能更改<audio>元素的输出,因此不能从扬声器更改为耳机,也不能让它使用蓝牙设备。

使用过时的WebRTC SDK重新开发整个应用程序是不可行的(谷歌不再维护WebRTC iOS SDK),然后像SIPJS一样构建自己的Swift堆栈,然后使用两组代码进行维护.所以我的主要问题是:

如何访问path/device?

  • How的AVAudioSession,以便设置输出background)?

,当应用程序发送到background?

  • How时,麦克风保持活动,当Callkit激活应用程序时(应用程序在background)?

中),我能激活麦克风吗?

EN

回答 1

Stack Overflow用户

发布于 2022-11-25 14:22:03

对于1)也许有人也在遵循这种方法,并且可以添加一些洞察力/纠正错误的假设: WebRTC站点中的音频被表示为Mediastream。也许可以从没有WKWebView的情况下获得流,并在应用程序中回放它?这个代码应该传递一些缓冲区,但是当它们迅速到达时,它们是空的:

代码语言:javascript
复制
//javascript
...
someRecorder = new MediaRecorder(audioStream);
someRecorder.ondataavailable = async (e) =>
{
    window.webkit.messageHandlers.callBackMethod.postMessage(await e.data.arrayBuffer());
}
mediaRecorder.start(1000);

然后迅速地接受它就像

代码语言:javascript
复制
//swift
import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
...
let config = WKWebViewConfiguration()
config.userContentController = WKUserContentController()
config.userContentController.add(self, name: "callBackMethod")
let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: 10, height: 10), configuration: config)
...
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    addToPlayingAudioBuffer(message.body)
    //print(message.body) gives the output "{}" every 1000ms.
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71483732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档