我创建了一个网站,如果用户单击该网站,它将播放声音。为了防止声音重叠,我必须添加代码:
n.pause();
n.currentTime = 0;
n.play();
但是,这会导致错误:
The play() request was interrupted by a call to pause()
每次声音事件在另一个触发器之后立即触发时都会出现。声音仍然可以正常播放,但我想防止此错误消息不断弹出。有任何想法吗?
onCanPlay()
。所有这些答案都是肮脏的骇客。
我创建了一个网站,如果用户单击该网站,它将播放声音。为了防止声音重叠,我必须添加代码:
n.pause();
n.currentTime = 0;
n.play();
但是,这会导致错误:
The play() request was interrupted by a call to pause()
每次声音事件在另一个触发器之后立即触发时都会出现。声音仍然可以正常播放,但我想防止此错误消息不断弹出。有任何想法吗?
onCanPlay()
。所有这些答案都是肮脏的骇客。
Answers:
我最近也遇到了这个问题-这可能是play()
和之间的竞争条件pause()
。看来这里有对此问题的参考,或与之相关的东西。
正如@Patrick指出的那样,pause
它不会返回诺言(或其他任何东西),因此上述解决方案将行不通。尽管MDN pause()
在的Media Elements的WC3草案中没有上的文档,但它说:
media.pause()
将暂停的属性设置为true,必要时加载媒体资源。
因此,还可以paused
在其超时回调中检查属性。
基于这个很好的SO答案,您可以通过以下方法检查视频是否正在播放(或没有在播放),因此可以安全地触发play()而不出错。
var isPlaying = video.currentTime > 0 && !video.paused && !video.ended
&& video.readyState > 2;
if (!isPlaying) {
video.play();
}
经过数小时的搜索和工作,我找到了完美的解决方案。
// 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();
}
}
之后,您可以尽快切换播放/暂停,它将正常工作。
我遇到了这个问题,并且遇到一种情况,我需要先打pause()然后再打play(),但是当使用pause()。then()时,我不确定。
我发现,如果我在暂停后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.cloneNode(true).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);
}
}
这有点矫kill过正,但是在特殊情况下处理Promise时会有所帮助。
解决方案这里提出要么没有工作或我在哪里大,所以我一直在寻找别的东西,发现通过@dighan提出的解决方案bountysource.com/issues/
所以这是解决我的问题的代码:
var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
playPromise.catch(() => { media.play(); })
}
它仍然会向控制台抛出错误,但是至少正在播放视频:)
对于实时流媒体,我面临着同样的问题。而我的解决方法是 确保从html video TAG中删除“自动播放”, 然后使用以下代码播放。
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;
}
}
});
}
这段代码为我修复了!
@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();
}
};
};
}
});
所有新的浏览器支持的视频都只能在静音的情况下自动播放,因此请输入以下内容
<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相同
对于这种情况,答案太多了,因此,我将仅参考针对该问题的最佳文档:
https://developers.google.com/web/updates/2017/06/play-request-was-interrupted
在这种情况下,浏览器可能会play
通过调用来中断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();
尝试通过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
我认为他们更新了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>
当您看到错误时,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);
});
我使用了一个技巧来解决这个问题。定义一个全局变量var audio;
并在功能检查中
if(audio === undefined)
{
audio = new Audio(url);
}
并在停止功能中
audio.pause();
audio = undefined;
所以下一个电话 audio.play
,音频将从当前时间“ 0”开始就绪
我用了
audio.pause();
audio.currentTime =0.0;
但这没用。谢谢。