DOMException-The-play-request-was-interrupted

105次阅读

共计 1945 个字符,预计需要花费 5 分钟才能阅读完成。

最近在使用 audio 時遇到一个问题,那就是在 Chrome DevTools 总是报错:

Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().

or

Uncaught (in promise) DOMException: The play() request was interrupted by a new load request.

报错:

除了 google 浏览器,其他浏览都没有报错。而且虽然报错,其实还是能正常播放声音,本来想就这样了,但是看到有报错。总有一点膈应。

后来 google 了一下 发现是因为调用 play() 的时候,音频文件还没有加载完成的问题。

之前代码:

知道了是这个问题,那么如何修复呢?

例子:Autoplay

<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>

通过这个例子已经能够解决问题,

但是新的问题来了,promise 在低版本的浏览器不支持。


Chrome 50 才有 video 和 audio 才在 play() 上面返回了一个 promise;

然后我又看到了这个例子。

例子 2:Fetch & Play

<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,我也是自己大概写了一个数字.

以上问题暂时解决。

参考文章:
(https://developers.google.com…

(https://github.com/sampotts/p…

正文完
 0