如何防止“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; } } }); }
我刚刚在https://developers.google.com/web/updates/2017/06/play-request-was-interrupted上发表了一篇关于这个确切问题的文章,告诉你到底发生了什么以及;如何解决这个问题 。
我已经修复了一些代码下面的代码:
当你想玩:
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;
但它没有工作。 谢谢。