【问题标题】:How to play audio in WKWebView?如何在 WKWebView 中播放音频?
【发布时间】:2020-06-18 16:55:40
【问题描述】:

我正在制作一个 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 iPhone SE 12.1.1 我也曾在装有 iOS 10 的 iPad 上尝试过,并得到同样的错误。 我也尝试过 context.decodeAudioData() / context.createBufferSource() 并得到同样的错误。

【问题讨论】:

  • 这个现在可能已经过时了,但是你需要在设置web视图的配置之前配置配置对象。 self.myWebView3.configuration.mediaTypesRequiringUserActionForPlayback = [] 将静默失败。只需创建一个新的WKWebViewConfiguration 对象,设置其属性,然后创建 Web 视图:webView = WKWebView(frame: .zero, configuration: webConfiguration)
  • 谢谢它现在有效!我确实让 webConfiguration = WKWebViewConfiguration() if #available(iOS 10.0, *) { webConfiguration.mediaTypesRequiringUserActionForPlayback = [] }
  • 酷,很高兴听到它。我已将其发布为答案,以防其他人遇到同样的问题。

标签: javascript swift wkwebview web-audio-api


【解决方案1】:

Re: 问题 1,您需要在设置 Web 视图的配置之前创建配置对象。线

self.myWebView3.configuration.mediaTypesRequiringUserActionForPlayback = []

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

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

【讨论】:

    【解决方案2】:

    在WKWebView的delegate中,webview加载完成后,执行addEventListener到音频和视频标签的javascript,事件playpause,结束。然后检查播放状态。

    【讨论】:

      猜你喜欢
      • 2019-11-12
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 2012-03-14
      相关资源
      最近更新 更多