折腾:
【已解决】Safari浏览器中页面出错:Origin is not allowed by Access-Control-Allow-Origin
之后,发现点击提交后,返回的代码中,执行到js出错:
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.
点击后发现是:
var audioElt = $(".audio_player audio");
console.log("audioElt=%o", audioElt);
var audioObject = audioElt[0];
console.log("audioObject=%o", audioObject);
var playAudioResult = audioObject.play();
看起来像是:
js中audio的对象,在Safari中play()不支持?
但是Chrome中是支持的,没有问题的:
safari Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context
API: Safari play(true) blocked · Issue #2421 · jwplayer/jwplayer
想办法把:
var promise = document.querySelector(‘video’).play();
if (promise !== undefined) {
promise.catch(error => {
// Auto-play was prevented
// Show a UI element to let the user manually start playback
}).then(() => {
// Auto-play started
});
}
集成进来
但是突然发现,貌似本地的127.0.0.1中去测试,连接本地flask服务器,用Safari,却是好的:
是可以获取到
playAudioResult=
Promise
status: "pending"
“Promise”原型
catch(rejectionHandler)
constructor: function()
finally()
then(resolvedHandler, rejectionHandler)
Symbol(Symbol.toStringTag): "Promise"
“Object”原型
的。。
Safari audio.play() – NotAllowedError (DOM Exception 35) – General Discussion – Vue Forum
OSX Safari play sound on load – Browser & Compatibility – Tumult Forums
Safari 11: audio.play causes "Unhandled Promise… | Apple Developer Forums
“The user gesture is not recognized by the element because of the delay caused by the async load ahead of play method call.”
难道是,没有load,或者没有完全load,就不能播放?
但是此处是已经load的:
if (audioUrl) {
$(".audio_player audio source").attr("src", audioUrl);
audioObject.load();
console.log("has load audioObject=%o", audioObject);
}
输出:
然后才发现,实际上此处load没出错,但是play出错:
safari audio play Unhandled Promise Rejection: NotAllowedError
safari 音频播放 Unhandled Promise Rejection: NotAllowedError
HTMLMediaElement.play() – Web APIs | MDN
看到的是Safari都是支持的啊:
javascript – ios Safari中audio音频播放没有声音 – SegmentFault 思否
“原因是新版本的ios中的safari,不支持自动播放,需要用户交互才会播放
我的只有点击一下才能出声音,,,”
去点击了一下,果然可以播放:
那想办法,去实现捕获这个error,或者是能检测到然后显示一个提示,让用户自己点击播放
然后试了试代码:
var playAudioPromise = undefined;
if ((dataControl === "") && audioUrl) {
playAudioPromise = audioObject.play();
} else if ((dataControl === "next") && (audioUrl)) {
var playAudioResult = audioObject.play();
}
if (playAudioPromise !== undefined) {
playAudioPromise.then(() => {
// Auto-play started
console.log("Auto paly audio started, playAudioPromise=%o", playAudioPromise);
}).catch(error => {
// Auto-play was prevented
// Show a UI element to let the user manually start playback
console.error("play audio promise error=%o", error);
//NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
});
}
结果是:
Safari打开在线的html测试结果是:会error:
play audio promise error=NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
play
success — main.js:123
fire — jquery-1.11.1.js:3119
fireWith — jquery-1.11.1.js:3231
done — jquery-1.11.1.js:9275
callback — jquery-1.11.1.js:9685
Safari打开本地html测试结果是:
不会出错:
Auto paly audio started, playAudioPromise=
Promise
result: undefined
status: "resolved"
“Promise”原型
catch(rejectionHandler)
constructor: function()
finally()
then(resolvedHandler, rejectionHandler)
Symbol(Symbol.toStringTag): "Promise"
“Object”原型
有点奇怪
但是不管了,总之在线网页中是会error的。
看到:
https://forums.developer.apple.com/thread/94522
中提示说的是:
“ It is likely it will work if you change the per-site auto-play preferences to always allow playing media with sound. ”
然后去看看设置,果然还真有:
去改为允许自动播放:
然后再去测试看看效果
果然允许自动播放带声音的媒体了:
那剩下的就是:
给html中添加合适的提示
【已解决】用Bootstrap给html中添加显示后可以消失掉的提示或警告
【总结】
此处,用audio的play去播放,报错:
Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context
的原因是:
新版的Safari中,提高了限制,不允许代码上直接播放 带声音的音频(或视频)
只能:
办法1.让用户主动点击播放按钮后才能开始播放音频
办法2:让用户去Safari中设置,允许你当前网站,可以直接播放带声音的音频
而此处在代码上,唯一能做的事情是:
用promise的catch,去从代码上,检测到自动播放被屏蔽了的话,给用户显示提示,让用户主动点击播放按钮去播放音频:
相关代码:
var audioElt = $(".audio_player audio");
console.log("audioElt=%o", audioElt);
var audioObject = audioElt[0];
console.log("audioObject=%o", audioObject);
var playAudioPromise = undefined;
playAudioPromise = audioObject.play();
if (playAudioPromise !== undefined) {
playAudioPromise.then(() => {
// Auto-play started
console.log("Auto paly audio started, playAudioPromise=%o", playAudioPromise);
//for debug
showAudioPlayPreventedNotice();
}).catch(error => {
// Auto-play was prevented
// Show a UI element to let the user manually start playback
// showAudioPlayPreventedNotice();
console.error("play audio promise error=%o", error);
//NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
});
}
function showAudioPlayPreventedNotice(){
console.log("showAudioPlayPreventedNotice");
// var prevDisplayValue = $("#audio_play_prevented").css("display");
// console.log("prevDisplayValue=%o", prevDisplayValue);
// $("#audio_play_prevented").css({"display":"block"});
var curAudioPlayPreventedNoticeEltHtml = $("#audio_play_prevented").html();
console.log("curAudioPlayPreventedNoticeEltHtml=%o", curAudioPlayPreventedNoticeEltHtml);
if (curAudioPlayPreventedNoticeEltHtml !== undefined) {
console.log("already exist audio play prevented notice, so not insert again");
} else {
var audioPlayPreventedNoticeHtml = ‘<div id="audio_play_prevented" class="alert alert-warning alert-dismissible col-md-12 col-xs-12"><button type = "button" class="close" data-dismiss = "alert">x</button><strong>Notice:</strong> Auto play prevented, please mannually click above play button to play</div>’;
console.log("audioPlayPreventedNoticeHtml=%o", audioPlayPreventedNoticeHtml);
$(".audio_player").append(audioPlayPreventedNoticeHtml);
}
}
转载请注明:在路上 » 【已解决】Safari中js代码出错:Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context