[Javascript] Come impedire "La richiesta play () è stata interrotta da un errore call to pause ()"?



Answers

Dopo ore di ricerca e di lavoro, ho trovato la soluzione perfetta.

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

Dopodiché puoi attivare / disattivare la riproduzione il più velocemente possibile, funzionerà correttamente .

Question

Ho creato un sito Web in cui, se l'utente fa clic, riproduce un suono. Per evitare che il suono si sovrapponesse, ho dovuto aggiungere il codice:

https://codebitt.com/snippet/Vi3vq8

Ma questo causa l'errore: The play() request was interrupted by a call to pause()
Per apparire ogni volta che l'evento sonoro viene attivato subito dopo un altro trigger. I suoni continuano a funzionare bene, ma voglio evitare che questo messaggio di errore compaia costantemente. Qualche idea?

Grazie in anticipo!

modificare

Codice dal link codebitt.com, nel caso sia stato rimosso e interrotto il collegamento

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



ecco una soluzione dal blog 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)
}



Forse una soluzione migliore per questo come ho capito. Spec afferma come citato da @JohnnyCoder:

media.pause ()

Imposta l'attributo sospeso su true, caricando la risorsa multimediale se necessario.

-> caricandolo

if (videoEl.readyState !== 4) {
    videoEl.load();
}
videoEl.play();

indica lo stato di preparazione del supporto HAVE_ENOUGH_DATA = 4

In pratica, carica il video solo se non è già caricato. Errore menzionato per me, perché il video non è stato caricato. Forse meglio che usare un timeout.




Con lo streaming live ero di fronte allo stesso problema. e la mia correzione è questa. Da TAG video html, assicurati di rimuovere "autoplay" e utilizzare questo codice sotto per giocare.

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



Quando vedi un errore con Uncaught (in promise) Questo significa solo che devi gestire la promessa con un .catch() In questo caso, .play() restituisce una promessa. Puoi decidere se vuoi registrare un messaggio, eseguire un codice, o non fare nulla, ma finché hai il .catch() l'errore andrà via.

var n = new Audio();
n.pause();
n.currentTime = 0;
n.play().catch(function(e) {
  // console.log('There was an error', e);
});



Cercando di far riprodurre in loop un video a riproduzione automatica chiamando play() quando finisce, la soluzione alternativa di timeout non ha funzionato per me (tuttavia il timeout è lungo).

Ma ho scoperto che clonando / sostituendo il video con jQuery quando è terminato, si accedeva correttamente.

Per esempio:

<div class="container">
  <video autoplay>
    <source src="video.mp4" type="video/mp4">
  </video>
</div>

e

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

Sto usando Chrome 54.0.2840.59 (64-bit) / OS X 10.11.6







A seconda di quanto complessa vuoi la tua soluzione, questo può essere utile:

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

Questo è un po 'eccessivo, ma aiuta quando si gestisce una Promessa in scenari unici.




Provalo

n.pause();
n.currentTime = 0;
var nopromise = {
   catch : new Function()
};
(n.play() || nopromise).catch(function(){}); ;



Ho lo stesso problema, finalmente risolvo con:

video.src = 'xxxxx';
video.load();
setTimeout(function() {
  video.play();
}, 0);



Ecco un'altra soluzione se il motivo è che il download del video è molto lento e il video non è stato memorizzato nel buffer:

if (videoElement.state.paused) { videoElement.play(); } else if (!isNaN(videoElement.state.duration)) { videoElement.pause(); }




Links