Как предотвратить ошибку" запрос play() был прерван вызовом pause ()"?
Я сделал веб-сайт, где, если пользователь нажимает, он воспроизводит звук. Чтобы звук не перекрывался, мне пришлось добавить код:
n.pause();
n.currentTime = 0;
n.play();
но это вызывает ошибку:
The play() request was interrupted by a call to pause()
появляться каждый раз, когда звуковое событие запускается сразу после другого триггера. Звуки по-прежнему отлично воспроизводятся, но я хочу, чтобы это сообщение об ошибке постоянно появлялось. Есть идеи?
спасибо заранее!
23 ответов
Я недавно столкнулся с этой проблемой - это может быть условие гонки между play()
и pause()
. Похоже, есть ссылка на эту проблему, или что-то связанное здесь.
As @Patrick указывает pause
не возвращает обещание (или что-то еще), поэтому вышеупомянутое решение не будет работать. Хотя MDN не имеет документов на pause()
, в проект WC3 для медиа-элементов он говорит:
СМИ.pause()
устанавливает атрибут paused в true, при необходимости загружая медиа-ресурс.
таким образом, можно также проверить paused
атрибут в их обратном вызове тайм-аута.
на основе это великий так ответ, вот как вы можете проверить, действительно ли видео (или нет) играет, поэтому вы можете безопасно запустить play() без ошибки.
var isPlaying = video.currentTime > 0 && !video.paused && !video.ended
&& video.readyState > 2;
if (!isPlaying) {
video.play();
}
после нескольких часов работы и работы я нашел идеальный решение.
// 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() затем play (), но при использовании 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(){}); ;
Я только что опубликовал статью об этой точной проблеме в https://developers.google.com/web/updates/2017/06/play-request-was-interrupted это говорит вам точно, что происходит и как исправить это.
в зависимости от того, насколько сложным вы хотите, чтобы ваше решение, это может быть полезно:
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);
}
}
Это немного перебор, но помогает при обработке обещания в уникальных сценариях.
решения, предлагаемые здесь, либо не работали для меня, либо где большой, поэтому я искал что-то еще и нашел решение, предложенное @dighan on bountysource.com/issues/
Итак, вот код, который решил мою проблему:
var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
playPromise.catch(() => { media.play(); })
}
Он по-прежнему выдает ошибку в консоли, но по крайней мере на видео :)
может быть, лучшее решение для этого, как я понял. Spec говорит, как цитируется из @JohnnyCoder:
СМИ.pause()
задает для атрибута paused значение true, при необходимости загружая медиаресурс.
--> загрузки
if (videoEl.readyState !== 4) {
videoEl.load();
}
videoEl.play();
указывает состояние готовности носителя HAVE_ENOUGH_DATA = 4
в основном загружайте видео, только если оно еще не загружено. Упомянутая ошибка для меня, потому что видео было не загружать. Может быть, лучше, чем использовать тайм-аут.
удалены все ошибки: (typescript)
audio.addEventListener('canplay', () => {
audio.play();
audio.pause();
audio.removeEventListener('canplay');
});
С live streaming я столкнулся с той же проблемой. и вот мое решение. Из тега html video убедитесь, что удалить "автозапуск" и используйте этот код ниже, чтобы играть.
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;
}
}
});
}
Chrome возвращает обещание в новейших версиях. В противном случае, просто:
n.pause();
n.currentTime = 0;
setTimeout(function() {n.play()}, 0);
У меня такая же проблема, я, наконец, решить:
video.src = 'xxxxx';
video.load();
setTimeout(function() {
video.play();
}, 0);
этот кусок кода исправлен для меня!
измененный код @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();
}
};
};
}
});
я исправил это с помощью некоторого кода ниже:
когда вы хотите играть, используйте следующую конструкцию:
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');
});
вот еще одно решение, если причина в том, что загрузка видео очень медленная, и видео не буферизовано:
if (videoElement.state.paused) {
videoElement.play();
} else if (!isNaN(videoElement.state.duration)) {
videoElement.pause();
}
похоже, что многие программисты сталкивались с этой проблемой.
решение должно быть довольно простым. media element return Promise
от действий
n.pause().then(function(){
n.currentTime = 0;
n.play();
})
должен делать трюк
вот решение из блога googler:
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)
}
я столкнулся с той же проблемой и решил ее, динамически добавив вместо 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;
и в функции check
if(audio === undefined)
{
audio = new Audio(url);
}
и в функции stop
audio.pause();
audio = undefined;
Итак, следующий вызов audio.play
, аудио будет готово от' 0 ' currentTime
Я
audio.pause();
audio.currentTime =0.0;
но это не сработало. Спасибо.