我做了一个网站,如果用户点击,它会播放声音。为了防止声音重叠,我不得不添加以下代码:
n.pause();
n.currentTime = 0;
n.play();
但这会导致错误:
播放请求被暂停调用中断
每次声音事件在另一个触发器之后立即触发时,都会出现这种情况。声音仍然可以正常播放,但我想防止不断弹出此错误消息。有什么建议吗?
我做了一个网站,如果用户点击,它会播放声音。为了防止声音重叠,我不得不添加以下代码:
n.pause();
n.currentTime = 0;
n.play();
但这会导致错误:
播放请求被暂停调用中断
每次声音事件在另一个触发器之后立即触发时,都会出现这种情况。声音仍然可以正常播放,但我想防止不断弹出此错误消息。有什么建议吗?
最近我也遇到了这个问题——这可能是play()
和pause()
之间的竞争条件。看起来有一个与此问题相关的参考或相关内容在这里。
正如@Patrick所指出的那样,pause
不会返回任何承诺(或其他任何东西),因此上述解决方案将不起作用。虽然MDN没有关于pause()
的文档,但在WC3媒体元素草案中,它说:
media.pause()
如果必要的话,将paused属性设置为true,加载媒体资源。
因此,在超时回调中,一个人还可以检查paused
属性。
根据这个很棒的SO答案,这里是一种你可以检查视频是否真正播放(或没有播放)的方法,这样你就可以安全地触发play()
而不会出现错误。
var isPlaying = video.currentTime > 0 && !video.paused && !video.ended
&& video.readyState > video.HAVE_CURRENT_DATA;
if (!isPlaying) {
video.play();
}
否则,@Patrick 的 答案 应该可行。经过几个小时的搜索和努力,我找到了完美的解决方案。
// Initializing values
var isPlaying = true;
// On video playing toggle values
video.onplaying = function() {
isPlaying = true;
};
// On video pause toggle values
video.onpause = function() {
isPlaying = false;
};
// Play video function
async function playVid() {
if (video.paused && !isPlaying) {
return video.play();
}
}
// Pause video function
function pauseVid() {
if (!video.paused && isPlaying) {
video.pause();
}
}
之后,你可以尝试快速切换 播放/暂停,它会正常工作。
playVid()
然后立即调用 pauseVid()
,会发生什么?看起来 isPlaying
仍然是 false,所以 video.pause()
没有被调用。因此视频将继续播放,即使我最后调用的是 pauseVid()
。这正确吗? - teedyay我遇到了这个问题,并且有一种情况需要先使用pause()然后使用play(),但是当使用pause().then()时,我得到了undefined的结果。
我发现如果在暂停后150毫秒开始播放,就可以解决这个问题。(希望Google尽快修复)
playerMP3.volume = 0;
playerMP3.pause();
//Avoid the Promise Error
setTimeout(function () {
playerMP3.play();
}, 150);
我刚刚在https://developers.google.com/web/updates/2017/06/play-request-was-interrupted上发布了一篇关于这个问题的文章,它会告诉你发生了什么以及如何解决它。
试一下
n.pause();
n.currentTime = 0;
var nopromise = {
catch : new Function()
};
(n.play() || nopromise).catch(function(){}); ;
n.cloneNode(true).play();
对于这种情况有太多的答案,所以我只会参考最好的文档:
https://developers.google.com/web/updates/2017/06/play-request-was-interrupted
在这种情况下,当标签页未聚焦时,浏览器可能通过调用pause
来中断play
,以便为活动标签页节省资源。
因此,您可以在调用播放之前等待标签页被聚焦:
async function waitForTabFocus() {
return new Promise((resolve, reject) => {
const onFocus = () => { resolve(); window.removeEventListener('focus', onFocus) };
window.addEventListener('focus', onFocus)
})
}
if (!document.hasFocus()) await this.waitForTabFocus();
videoEl.play();
根据您解决问题的复杂程度,这可能会有所帮助:
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 场景时非常有帮助。
这里提出的解决方案对我不起作用或太大了,所以我正在寻找其他东西,并在bountysource.com/issues/上找到了由@dighan提出的解决方案。
这是解决我的问题的代码:
var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
playPromise.catch(() => { media.play(); })
}
它仍然会在控制台中抛出一个错误,但至少视频正在播放 :)
我有一个类似的问题,我认为做这样的事情是最容易的:
video.play().then(() => {
video.pause();
video.currentTime = 0;
video.play();
})
play()
也可以正常工作,它会像预期的那样返回一个promise。
onCanPlay()
。所有这些答案都是肮脏的黑客行为。 - Martin Dawsonn.play()
然后再 执行n.pause()
。对此,这篇Web基础知识文章描述了解决方案。简而言之:n.play().then(() => { n.pause()})
- totymedli