在wkwebview中播放html音频将报告错误:缺少必需的客户端权限



在wkwebview中播放h5音频或视频元素时报告错误:获取断言时出错:<错误域=RBSAssertionErrorDomain代码=3";缺少所需的客户端权限";UserInfo={RBSAssertionAttribute=<RBSDomainAttribute|domain:"com.apple.webkit"名称:"MediaPlayback&quot的源环境:"(null(>,NSLocalizedFailureReason=缺少所需的客户端权限}>然后web视图的性能将变得非常差,对任何元素点击都没有响应。这个问题已经影响了我们数以万计的用户。当前的解决方案是调用客户端方法来播放音频。如何从根本上解决问题?

1.在我的HTML文件中有一个音频元素和一个按钮。单击按钮播放音频。

<body>
<button onclick="handleClick()">PLAY</button>
<audio id="audio" src="https://ac-dev.oss-cn-hangzhou.aliyuncs.com/test-2022-music.mp3"></audio>
<script>

function handleClick() {
document.getElementById("audio").play();
}
</script>
</body>

2.创建一个wkwebview来加载我的演示应用程序中的html文件。

class ViewController: UIViewController , WKUIDelegate{
var webView: WKWebView!
override func loadView() {
let config = WKWebViewConfiguration()
config.preferences.javaScriptEnabled = true
config.allowsInlineMediaPlayback = true
webView = WKWebView(frame: .zero, configuration: config)  //.zero
webView.uiDelegate = self

view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: "https://ac-dev.oss-cn-hangzhou.aliyuncs.com/test-2022-py.html")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
}

3.点击HTML中的按钮播放音频,您可以在xcode上看到错误报告。

iPadN[2133:855729] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=3 "Required client entitlement is missing" UserInfo={RBSAssertionAttribute=<RBSDomainAttribute| domain:"com.apple.webkit" name:"MediaPlayback" sourceEnvironment:"(null)">, NSLocalizedFailureReason=Required client entitlement is missing}>

4.综上所述,在HTML中播放音频或视频时会出现此错误。然后应用程序的性能会下降很多,交互响应会非常慢。

我也遇到了类似的问题。我的计划是将new Audio(...)与作为对象url存储在存储器中的资产或blob一起使用。它对资产有效,但对存储为字符串的blob无效。。。但只在设备上,就像你提到的那样。

我用以下策略解决了这个问题(对于不起作用的部分,在我的情况下,它都是类型脚本,但可以直接在java脚本中完成(:

  • 创建``AudioContext```
  • 使用``FileReader从我的blob/string创建ArrayBuffer```
  • 解码音频数据(await context.decodeAudioData(arrayBuffer, (buffer) => {...})(
  • 在音频上下文的目的地播放声音:
const source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0)
  • 如果需要,请立即清理东西
source.onended = async(): Promise<void> => {
source.disconnect();
await context.close();
}

最新更新