如何在 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)
我正在制作一个 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)