Как предотвратить ошибку" запрос play() был прерван вызовом pause ()"?


Я сделал сайт, где, если пользователь нажимает, он воспроизводит звук. Чтобы звук не перекрывался, мне пришлось добавить код:

n.pause();
n.currentTime = 0;
n.play();

но это вызывает ошибку: The play() request was interrupted by a call to pause()
чтобы подходить каждый раз, когда звуковое событие запускается сразу после другого триггера. Звуки по-прежнему воспроизводятся нормально, но я хочу, чтобы это сообщение об ошибке постоянно выскакивало. Есть идеи?

спасибо заранее!

23 89

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();
}

иначе @Patrick ' s ответ должны работать.

после нескольких часов промывки и работы, я нашел идеальный решение.

// 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(){}); ;

Это решение помогло мне:

n.cloneNode(true).play();

Я только что опубликовал статью об этом точном вопросе в 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; 

но это не сработало. Спасибо.