我创建了一个网站,如果用户点击,它会发出声音。为防止声音重叠,我不得不添加代码:
n.pause();
n.currentTime = 0;
n.play();
但是这会导致错误:
The play() request was interrupted by a call to pause()
每次触发声音事件后立即启动。声音仍然很好,但我想防止这个错误信息不断弹出。有什么想法吗?
答案 0 :(得分:72)
我最近也遇到过这个问题 - 这可能是play()
和pause()
之间的竞争条件。看起来有一个对此问题的引用,或与here相关的内容。
正如@Patrick指出的那样,pause
不会返回承诺(或任何内容),因此上述解决方案无法正常工作。虽然MDN在pause()
上没有文档,但在WC3 draft for Media Elements中,它说:
media.pause()
将paused属性设置为true,并在必要时加载媒体资源。
因此,人们也可以检查超时回调中的paused
属性。
基于this great SO answer,您可以通过以下方式检查视频是否(或者不是)正在播放,因此您可以安全地触发播放()而不会出现错误。
var isPlaying = video.currentTime > 0 && !video.paused && !video.ended
&& video.readyState > 2;
if (!isPlaying) {
video.play();
}
答案 1 :(得分:60)
经过几个小时的搜索和工作,我找到了完美的 解决方案 。
// 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
function playVid() {
if (video.paused && !isPlaying) {
video.play();
}
}
// Pause video function
function pauseVid() {
if (!video.paused && isPlaying) {
video.pause();
}
}
之后,您可以尽快切换 播放/暂停 , 它将正常运作
答案 2 :(得分:18)
我遇到了这个问题,有一个案例我需要点击pause()然后播放()但是当使用pause()时那么()我得到了未定义。
我发现如果我在暂停后开始播放150毫秒就解决了这个问题。 (希望Google尽快修复)
playerMP3.volume = 0;
playerMP3.pause();
//Avoid the Promise Error
setTimeout(function () {
playerMP3.play();
}, 150);
答案 3 :(得分:5)
试试吧
n.pause();
n.currentTime = 0;
var nopromise = {
catch : new Function()
};
(n.play() || nopromise).catch(function(){}); ;
答案 4 :(得分:4)
我刚刚在https://developers.google.com/web/updates/2017/06/play-request-was-interrupted发布了一篇关于这个确切问题的文章,它可以准确地告诉您发生了什么以及如何解决这个问题。
答案 5 :(得分:3)
这个解决方案帮助了我:
n.cloneNode(true).play();
答案 6 :(得分:2)
根据您希望解决方案的复杂程度,这可能很有用:
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时会有所帮助。
答案 7 :(得分:2)
这里提出的解决方案要么对我不起作用,要么在哪里工作, 所以我正在寻找其他的东西,并找到了@dighan在bountysource.com/issues/
上提出的解决方案所以这是解决我问题的代码:
var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
playPromise.catch(() => { media.play(); })
}
它仍会向控制台抛出错误,但至少视频正在播放:)
答案 8 :(得分:1)
我用一些代码修正了它:
如果您想玩,请使用以下内容:
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');
});
答案 9 :(得分:1)
这段代码为我修好了!
@JohnnyCoder的修改代码
HTML:
<video id="captureVideoId" muted width="1280" height="768"></video>
<video controls id="recordedVideoId" muted width="1280"
style="display:none;" height="768"></video>
JS:
var recordedVideo = document.querySelector('video#recordedVideoId');
var superBuffer = new Blob(recordedBlobs, { type: 'video/webm' });
recordedVideo.src = window.URL.createObjectURL(superBuffer);
// workaround for non-seekable video taken from
// https://bugs.chromium.org/p/chromium/issues/detail?id=642012#c23
recordedVideo.addEventListener('loadedmetadata', function () {
if (recordedVideo.duration === Infinity) {
recordedVideo.currentTime = 1e101;
recordedVideo.ontimeupdate = function () {
recordedVideo.currentTime = 0;
recordedVideo.ontimeupdate = function () {
delete recordedVideo.ontimeupdate;
var isPlaying = recordedVideo.currentTime > 0 &&
!recordedVideo.paused && !recordedVideo.ended &&
recordedVideo.readyState > 2;
if (isPlaying) {
recordedVideo.play();
}
};
};
}
});
答案 10 :(得分:1)
正如我所知,也许是一个更好的解决方案。 规范说@JohnnyCoder引用:
media.pause()
将paused属性设置为true,并在必要时加载媒体资源。
- &GT;加载它
if (videoEl.readyState !== 4) {
videoEl.load();
}
videoEl.play();
表示媒体的准备状态 HAVE_ENOUGH_DATA = 4
基本上只加载视频(如果尚未加载)。我提到错误,因为未加载视频。 也许比使用超时更好。
答案 11 :(得分:1)
我有同样的问题,最后我解决了:
video.src = 'xxxxx';
video.load();
setTimeout(function() {
video.play();
}, 0);
答案 12 :(得分:1)
删除了所有错误:(打字稿)
audio.addEventListener('canplay', () => {
audio.play();
audio.pause();
audio.removeEventListener('canplay');
});
答案 13 :(得分:1)
通过直播,我遇到了同样的问题。我的解决方法就是这个。 从html视频TAG确保删除&#34;自动播放&#34; 并使用下面的代码来播放。
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;
}
}
});
}
答案 14 :(得分:1)
Chrome会在最新版本中返回Promise。 否则,只需:
n.pause();
n.currentTime = 0;
setTimeout(function() {n.play()}, 0);
答案 15 :(得分:0)
在这种情况下,答案太多,因此,我将仅参考针对该问题的最佳文档:
https://developers.google.com/web/updates/2017/06/play-request-was-interrupted
在这种情况下,浏览器可以中断process.on('unhandledRejection', error => {
if (error.code === "ENOTFOUND") { console.log ("No internet connection")}
if (error.code === "ECONNREFUSED") { console.log ("Connection refused")}
//console.log('Unhandled promise rejection:', error.code);
});
通过调用play
当凸片不聚焦。为了节省活动标签的资源。
因此,您可以在调用play之前等待标签集中显示
pause
async function waitForTabFocus() {
return new Promise((resolve, reject) => {
const onFocus = () => { resolve(); window.removeEventListener('focus', onFocus) };
window.addEventListener('focus', onFocus)
})
}
答案 16 :(得分:0)
最干净的和最简单的解决方案:
var p = video.play();
if (p !== undefined) p.catch(function(){});
答案 17 :(得分:0)
所有新的浏览器支持的视频都只能在静音的情况下自动播放,因此请放置类似这样的内容
<video autoplay muted="muted" loop id="myVideo">
<source src="https://w.r.glob.net/Coastline-3581.mp4" type="video/mp4">
</video>
如果您的网站使用https运行,则视频URL应与SSL状态匹配,然后视频URL也应为https且与HTTP相同
答案 18 :(得分:0)
我有类似的问题,我认为做这样的事情最简单:
started
无论视频是否正在播放,视频最后都会无一例外地暂停,然后归零重新播放。
即使视频已经在播放,调用 play() 也能正常工作,它会按预期返回承诺。
答案 19 :(得分:0)
这是来自googler blog的解决方案:
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)
}
答案 20 :(得分:0)
看起来很多程序员都遇到过这个问题。
解决方案应该非常简单。媒体元素从操作返回Promise
n.pause().then(function(){
n.currentTime = 0;
n.play();
})
应该做的伎俩
答案 21 :(得分:0)
如果原因是您的视频下载速度非常慢并且视频没有缓冲,那么这是另一种解决方案:
if (videoElement.state.paused) {
videoElement.play();
} else if (!isNaN(videoElement.state.duration)) {
videoElement.pause();
}
答案 22 :(得分:-1)
当您看到Uncaught (in promise)
出现错误时这意味着您需要使用.catch()
来处理承诺。在这种情况下,.play()
会返回一个承诺。您可以决定是否要记录消息,运行某些代码或不执行任何操作,但只要您拥有.catch()
,错误就会消失。
var n = new Audio();
n.pause();
n.currentTime = 0;
n.play().catch(function(e) {
// console.log('There was an error', e);
});
答案 23 :(得分:-1)
我认为他们更新了html5视频并弃用了一些编解码器。 删除编解码器后,它对我有用。
在下面的示例中:
<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>
答案 24 :(得分:-1)
尝试通过在play()
结束时调用自动播放视频来循环,超时解决方法对我来说不起作用(无论多长时间都是如此)。
但我发现通过jQuery在结束时克隆/替换视频,它会正常循环。
例如:
<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
答案 25 :(得分:-1)
我遇到了同样的问题并通过动态添加autoplay
属性而非使用play()
来解决此问题。这样浏览器可以在没有遇到竞争条件的情况下发挥作用。
答案 26 :(得分:-5)
我用了一个技巧来解决这个问题。 定义全局变量var audio;
并在功能检查中
if(audio === undefined)
{
audio = new Audio(url);
}
和停止功能
audio.pause();
audio = undefined;
所以下一次调用audio.play
,音频将从'0'urrentTime
我用过
audio.pause();
audio.currentTime =0.0;
但它不起作用。 感谢。