如何在 WKWebView 中播放音频?

How to play audio in WKWebView?

我正在制作一个 iOS 应用来包装我的 javascript 游戏。在移动 safari 上它工作正常,因为在 ontouchstart 中播放声音后,我可以随时播放任何音频,我也可以设置它们的音量。

问题 1:在 WKWebView 中,我只能播放我在 ontouchstart 中播放的特定声音,而不能播放其他声音。所以我会在第一次点击时播放我游戏中的每一个音频。听起来真的很糟糕。否则在 audio.play() 上的 javascript 我得到 Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

问题 2:我也无法降低 WKWebView 中的音量。如果我设置 myAudio.volume=.5 它立即又是 1。这意味着用户必须真正听到它们,以便它们到达 readyState=4

有什么好的解决方案或技巧吗?现在我在第一次点击时播放每一个声音,而且一切都是全音量。

<html>
    <body style='bakcground:#DDD;height:333px'>
        <div id=debug style='font-size:20px' onclick="playSound(myAudio)">
            Debug<br />
            Tap here to play the sound.<br />
        </div>
        <script>
            var context = new webkitAudioContext()
            var myAudio = new Audio("sound/upgrade.wav")
            myAudio.addEventListener('canplaythrough', function(){log('canplaythrough1')}, false)
            var myAudio2 = new Audio("sound/dragon.wav")
            myAudio2.addEventListener('canplaythrough', function(){log('canplaythrough2')}, false)

            function playSound(sound)
            {
                log("playSound() readyState="+sound.readyState)
                try{
                    sound.play()
                    context.resume().then(() => {
                                          log("Context resumed")
                                          sound.play()
                                          })
                    }
                catch(e)
                {
                    log(e)
                }
            }

            function log(m)
            {
                console.log(m)
                debug.innerHTML += m+"<br />"
            }

            window.ontouchstart = function()
            {
                log("ontouchstart()")
                playSound(myAudio)
                setTimeout(function() {
                           playSound(myAudio2, 1111)
                           })
            }
        </script>
    </body>
</html>

和ViewController.swift

import UIKit
import WebKit

class ViewController: UIViewController {
    private var myWebView3 : WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()

        self.myWebView3 = WKWebView(frame: .zero)

        self.myWebView3.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
        self.myWebView3.configuration.mediaTypesRequiringUserActionForPlayback = []
        self.myWebView3.configuration.allowsInlineMediaPlayback = true

        let url = Bundle.main.url(forResource: "index6", withExtension: "html", subdirectory: "/")!
        self.myWebView3.loadFileURL(url, allowingReadAccessTo: url)
        let request = URLRequest(url: url)
        self.myWebView3.load(request)

        self.view.addSubview(self.myWebView3)
    }

    override func viewDidLayoutSubviews() {
        self.myWebView3.frame = self.view.bounds
    }

}

我正在使用 Xcode 10.1 iPhoneSE 12.1.1 我也尝试过 iPad 和 iOS 10 并得到同样的错误。 我也试过 context.decodeAudioData() / context.createBufferSource() 并得到同样的错误。

在WKWebView的delegate中,webview加载完成后,执行javascript那个addEventListener到带有事件play[=16=的音频和视频标签], 暂停, 结束。然后有目的的查看播放状态。

回复:问题 1,您需要在设置 Web 视图的配置之前创建配置对象。该行

self.myWebView3.configuration.mediaTypesRequiringUserActionForPlayback = []

将无声地失败。只需创建一个新的 WKWebViewConfiguration 对象,设置其属性,然后创建 Web 视图:

webView = WKWebView(frame: .zero, configuration: webConfiguration)