最近在使用audio時遇到一个问题,那就是在Chrome DevTools 老是报错:git
Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
orgithub
Uncaught (in promise) DOMException: The play() request was interrupted by a new load request.
报错:web
除了google浏览器,其余浏览都没有报错。 并且虽然报错,其实仍是能正常播放声音,原本想就这样了,可是看到有报错。总有一点膈应。ajax
后来google了一下 发现是由于调用play()的时候,音频文件尚未加载完成的问题。promise
以前代码:浏览器
知道了是这个问题,那么如何修复呢?app
<video id="video" preload="none" src="https://example.com/file.mp4"></video> <script> // Show loading animation. var playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(_ => { // Automatic playback started! // Show playing UI. }) .catch(error => { // Auto-play was prevented // Show paused UI. }); } </script>
经过这个例子已经可以解决问题, dom
可是新的问题来了,promise在低版本的浏览器不支持。异步
Chrome 50才有 video和audio才在play()上面返回了一个promise;ide
而后我又看到了这个例子。
<video id="video"></video> <button id="button"></button> <script> button.addEventListener('click', onButtonClick); function onButtonClick() { // This will allow us to play video later... video.load(); fetchVideoAndPlay(); } function fetchVideoAndPlay() { fetch('https://example.com/file.mp4') .then(response => response.blob()) .then(blob => { video.srcObject = blob; return video.play(); }) .then(_ => { // Video playback started ;) }) .catch(e => { // Video playback failed ;( }) } </script>
经过这两个例子,我在想 用Fetch低版本仍是不兼容。因而乎我就想用$.ajax, 由于他的本意不就是一个异步么。先用阿贾克斯请求音频文件,而后在回调里面调用play方法不就能够了么。
然而却被现实啪啪的打脸。仍是不行 报一样的错。说明此路不通啊。
没办法我就只能再请教google, 而后我在GitHub上面看到有人这样说;
发现这也能够。因而我就把个人代码改了一下:
// 播放声音 function playVoice(src, domId) { var $dom = $('#' + domId) if ($.browser.msie) { // IE用bgsound标签处理声音 if ($dom.length) { $dom[0].src = src; } else { $('<bgsound>', {src: src, id: domId}).appendTo('body'); } } else { // IE之外的其它浏览器用HTML5处理声音 if ($dom.length) { $dom[0].load(); setTimeout(function() { $dom[0].play(); }, 200); } else { $('<audio src='+src+' id='+domId +' controls autoplay preload="auto">').appendTo('body')[0].load(); playVoice(src, domId); } } }
你们一看也就明白了,就是先load,而后异步去调用play,可是我用0,在我刷新快,频繁的时候仍是会报错、因而我就改为200ms,至于延时器里面的200ms,我也是本身大概写了一个数字.
以上问题暂时解决。