Как предотвратить ошибку" запрос play() был прерван вызовом pause ()"?
Я сделал сайт, где, если пользователь нажимает, он воспроизводит звук. Чтобы звук не перекрывался, мне пришлось добавить код:
n.pause();
n.currentTime = 0;
n.play();
но это вызывает ошибку:
The play() request was interrupted by a call to pause()
чтобы подходить каждый раз, когда звуковое событие запускается сразу после другого триггера. Звуки по-прежнему воспроизводятся нормально, но я хочу, чтобы это сообщение об ошибке постоянно выскакивало. Есть идеи?
спасибо заранее!
23 ответа:
Я недавно столкнулся с этой проблемой - это может быть состояние гонки между
play()
иpause()
. Похоже, есть ссылка на эту проблему, или что-то связанное здесь.как @Patrick указывает
pause
не возвращает обещание (или что-нибудь), так что выше решение не будет работать. В то время как MDN не имеет документов наpause()
, в проект WC3 для элементов мультимедиа он говорит:СМИ.пауза()
устанавливает для атрибута paused значение true, при необходимости загружая медиаресурс.
так что можно также проверить
paused
атрибут в их тайм-аут обратного вызова.на основе это великий так ответ, вот способ, которым вы можете проверить, действительно ли видео играет (или нет), поэтому вы можете безопасно запускать воспроизведение() без ошибки.
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().затем () я получаю неопределенный.
Я обнаружил, что если я начал играть 150 мс после паузы это решенный вопрос. (Надеюсь, 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:
СМИ.пауза()
задает для атрибута 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(); }
похоже, что многие программисты сталкивались с этой проблемой. решение должно быть достаточно простым. медиа-элемент возврата
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) }
я столкнулся с той же проблемой и решил ее путем динамического добавления
autoplay
атрибут, а не с помощью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); }
и в функции остановки
audio.pause(); audio = undefined;
так что следующий вызов
audio.play
, аудио будет готово с' 0 ' currentTimeЯ
audio.pause(); audio.currentTime =0.0;
но это не сработало. Спасибо.