如何防止“play()请求被暂停()”的错误调用中断?

我做了一个网站,如果用户点击,它会发出声音。 为了防止声音重叠,我不得不添加代码:

https://codebitt.com/snippet/Vi3vq8

但是,这会导致错误: The play() request was interrupted by a call to pause()
每当声音事件被触发后立即触发。 声音仍然播放良好,但我想防止这个错误信息不断popup。 有任何想法吗?

提前致谢!

编辑

代码从codebitt.com链接,以防万一它被删除并断开链接

 n.pause(); n.currentTime = 0; n.play(); 

我最近遇到了这个问题 – 这可能是play()pause()之间的竞争条件。 它看起来像是对这个问题的引用,或者是与这里相关的东西 。

正如@Regency Software指出的那样, pause不会返回一个承诺(或任何东西),所以上述解决scheme将无法工作。 虽然MDN在pause()上没有文档,但在WC3的媒体元素草案中 ,它表示:

media.pause()

将paused属性设置为true,根据需要加载媒体资源。

所以也可以在超时callback中检查paused属性。

基于这个伟大的答案 ,这里有一个方法可以检查video是否真的在播放,所以你可以安全地触发一个播放()而不出错。

 var isPlaying = video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2; if (!isPlaying) { video.play(); } 

否则, @Regency软件的答案应该工作。

经过几个小时的搜寻和工作,我find了完美的解决scheme

 // Initializing values var onplaying = true; var onpause = false; // On video playing toggle values video.onplaying = function() { onplaying = true; onpause = false; }; // On video pause toggle values video.onpause = function() { onplaying = false; onpause = true; }; // Play video function function playVid() { if (video.paused && !onplaying) { video.play(); } } // Pause video function function pauseVid() { if (!video.paused && !onpause) { video.pause(); } } 

之后,您可以尽可能快地切换播放/暂停它将正常工作

我碰到这个问题,有一个情况,我需要暂停(),然后播放(),但是当使用pause()。然后()我得到未定义。

我发现如果我在暂停后150ms开始播放,就解决了这个问题。 (希望Google很快修复)

 playerMP3.volume = 0; playerMP3.pause(); //Avoid the Promise Error setTimeout(function () { playerMP3.play(); }, 150); 

尝试一下

 n.pause(); n.currentTime = 0; var nopromise = { catch : new Function() }; (n.play() || nopromise).catch(function(){}); ; 

这个解决scheme帮助我:

 n.cloneNode(true).play(); 

根据你想要的解决scheme的复杂程度,这可能是有用的:

 var currentPromise=false; //Keeps track of active Promise function playAudio(n){ if(!currentPromise){ //normal behavior n.pause(); n.currentTime = 0; currentPromise = n.play(); //Calls play. Will store a Promise object in newer versions of chrome; //stores undefined in other browsers if(currentPromise){ //Promise exists currentPromise.then(function(){ //handle Promise completion promiseComplete(n); }); } }else{ //Wait for promise to complete //Store additional information to be called currentPromise.calledAgain = true; } } function promiseComplete(n){ var callAgain = currentPromise.calledAgain; //get stored information currentPromise = false; //reset currentPromise variable if(callAgain){ playAudio(n); } } 

这有点矫枉过正,但在独特场景下处理Promise时有帮助。

也许这是一个更好的解决scheme,我想通了。 规范说,从@JohnnyCoder引用:

media.pause()

将paused属性设置为true,根据需要加载媒体资源。

– >加载它

 if (videoEl.readyState !== 4) { videoEl.load(); } videoEl.play(); 

表示媒体HAVE_ENOUGH_DATA = 4的准备就绪状态

基本上只加载video,如果它尚未加载。 提到我的错误,因为video没有加载。 也许比使用超时更好。

随着直播,我面临着同样的问题。 我的解决方法是这样的。 从HTMLvideo标签确保删除“自动播放”,并使用下面的代码播放。

 if (Hls.isSupported()) { var video = document.getElementById('pgVideo'); var hls = new Hls(); hls.detachMedia(); hls.loadSource('http://wpc.1445X.deltacdn.net/801885C/lft/apple/TSONY.m3u8'); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play(); }); hls.on(Hls.Events.ERROR, function (event, data) { if (data.fatal) { switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: // when try to recover network error console.log("fatal network error encountered, try to recover"); hls.startLoad(); break; case Hls.ErrorTypes.MEDIA_ERROR: console.log("fatal media error encountered, try to recover"); hls.recoverMediaError(); break; default: // when cannot recover hls.destroy(); break; } } }); } 

我已经修复了一些代码下面的代码:

当你想玩:

 var video_play = $('#video-play'); video_play.on('canplay', function() { video_play.trigger('play'); ); 

当你想暂停时:

 var video_play = $('#video-play'); video_play.trigger('pause'); video_play.on('canplay', function() { video_play.trigger('pause'); }); 

这里提出的解决scheme要么不适合我,要么在哪里大,所以我正在寻找其他的东西,并find@dighan提出的解决schemebountysource.com/issues/

所以这里是解决我的问题的代码:

 var media = document.getElementById("YourVideo"); const playPromise = media.play(); if (playPromise !== null){ playPromise.catch(() => { media.play(); }) } 

它仍然抛出一个错误到控制台,但至lessvideo播放:)

这是另一种解决scheme,如果原因是您的video下载速度超慢,并且video没有缓冲:

if (videoElement.state.paused) { videoElement.play(); } else if (!isNaN(videoElement.state.duration)) { videoElement.pause(); }

删除了所有的错误:(打字稿)

 audio.addEventListener('canplay', () => { audio.play(); audio.pause(); audio.removeEventListener('canplay'); }); 

看起来像很多程序员遇到了这个问题。 解决scheme应该很简单。 媒体元素从操作返回Promise

 n.pause().then(function(){ n.currentTime = 0; n.play(); }) 

应该做的伎俩

这里是一个来自Google员工博客的解决scheme:

 var video = document.getElementById('#video') var promise = video.play() //chrome version 53+ if(promise){ promise.then(_=>{ video.pause() }) }else{ video.addEventListener('canplaythrough', _=>{ video.pause() }, false) } 

Chrome在最新版本中返回Promise。 否则,简单地说:

  n.pause(); n.currentTime = 0; setTimeout(function() {n.play()}, 0); 

我有同样的问题,最后我解决:

 video.src = 'xxxxx'; video.load(); setTimeout(function() { video.play(); }, 0); 

我遇到了同样的问题,并通过dynamic添加autoplay属性而不是使用play()来解决它。 这样,浏览器就可以在没有竞争的情况下玩弄游戏了。

尝试让自动播放video在play()结束时通过调用play()来循环play() ,超时解决方法对我来说不起作用(不pipe超时是多长时间)。

但是我发现通过在jQuery结束时克隆/replacevideo,它会正确地循环。

例如:

 <div class="container"> <video autoplay> <source src="video.mp4" type="video/mp4"> </video> </div> 

 $(document).ready(function(){ function bindReplay($video) { $video.on('ended', function(e){ $video.remove(); $video = $video.clone(); bindReplay($video); $('.container').append($video); }); } var $video = $('.container video'); bindReplay($video); }); 

我正在使用Chrome 54.0.2840.59(64位)/ OS X 10.11.6

我认为他们更新了html5video,并弃用了一些编解码器。 它删除编解码器后为我工作。

在下面的例子中:

 <video> <source src="sample-clip.mp4" type="video/mp4; codecs='avc1.42E01E, mp4a.40.2'"> <source src="sample-clip.webm" type="video/webm; codecs='vp8, vorbis'"> </video> must be changed to <video> <source src="sample-clip.mp4" type="video/mp4"> <source src="sample-clip.webm" type="video/webm"> </video> 

当你看到Uncaught (in promise)错误Uncaught (in promise)这只是意味着你需要用.catch()来处理promise。在这种情况下, .play()返回一个promise。 您可以决定是否要logging消息,运行一些代码或什么都不做,但只要您有.catch() ,错误就会消失。

 var n = new Audio(); n.pause(); n.currentTime = 0; n.play().catch(function(e) { // console.log('There was an error', e); }); 

我用了一个技巧来解决这个问题。 定义一个全局variablesvar audio;

并在function检查

 if(audio === undefined) { audio = new Audio(url); } 

并在停止function

 audio.pause(); audio = undefined; 

所以audio.play ,audio的下一个调用将从' audio.play准备就绪

我用了

 audio.pause(); audio.currentTime =0.0; 

但它没有工作。 谢谢。