最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Safari中js代码出错:Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context

JS crifan 22573浏览 0评论

折腾:

【已解决】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

Recent issue with Safari : running an audio without an user action · Issue #2410 · mediaelement/mediaelement

detect `Unhandled Promise Rejection: NotAllowedError` when calling `.play()` · Issue #178 · scottschiller/SoundManager2

API: Safari play(true) blocked · Issue #2421 · jwplayer/jwplayer

Safari 11 has a major change to Web Audio API: requires each Audio() object to be triggered manually:webdev

safari 禁止视频自动播放的错误捕捉 | 石头匠人

想办法把:

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,就不能播放?

音乐无法播放_实战问答

Vue.js 升级踩坑小记 – 掘金

但是此处是已经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,或者是能检测到然后显示一个提示,让用户自己点击播放

Topic: Video Autoplay : Unhandled Promise Rejection: [object DOMError] in Safari 11 « WordPress.org Forums

javascript – MediaStream Unhandled Promise Rejection: [object DOMError] (in Safari 11) – Stack Overflow

然后试了试代码:

    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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.166 seconds, using 22.11MB memory