it-swarm.com.de

So verhindern Sie den Fehler "Die play () - Anforderung wurde durch einen Aufruf an pause () unterbrochen"?

Ich habe eine Website erstellt, auf der der Benutzer einen Sound abspielt, wenn er klickt. Um zu verhindern, dass sich der Ton überlappt, musste ich den Code hinzufügen: 

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

Aber das verursacht den Fehler: The play() request was interrupted by a call to pause()
Jedes Mal, wenn das Soundereignis direkt nach einem anderen Auslöser ausgelöst wird, erscheint es. Die Sounds klingen immer noch gut, aber ich möchte verhindern, dass diese Fehlermeldung ständig angezeigt wird. Irgendwelche Ideen?

Danke im Voraus!

95
Owen M

Ich habe dieses Problem auch kürzlich erlebt - dies könnte eine Racebedingung zwischen play() und pause() sein. Anscheinend gibt es einen Hinweis auf dieses Problem oder etwas, das mit hier zusammenhängt.

Wie @Patrick weist darauf hin, dass pause kein Versprechen (oder irgendetwas) zurückgibt, so dass die obige Lösung nicht funktioniert. Während MDN keine Dokumente zu pause() enthält, heißt es im WC3-Entwurf für Media Elements :

media.pause () 

Setzt das angehaltene Attribut auf "true" und lädt die Medienressource bei Bedarf.

Man könnte also auch das paused-Attribut in ihrem Timeout-Callback prüfen.

Basierend auf dieser großartigen SO Antwort können Sie überprüfen, ob das Video wirklich abgespielt wird (oder nicht), sodass Sie ohne Fehler sicher ein play () starten können.

var isPlaying = video.currentTime > 0 && !video.paused && !video.ended 
    && video.readyState > 2;

if (!isPlaying) {
  video.play();
}

Ansonsten sollte @Patrick 's answer funktionieren.

71
JohnnyCoder

Nach stundenlangem Suchen und Arbeiten habe ich eine perfekteLösunggefunden.

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

Danach können Sieplay/pauseso schnell wie möglich umschalten,es funktioniert einwandfrei.

60
Nebojsa Sapic

Ich habe dieses Problem getroffen und habe einen Fall, bei dem ich pause () und play () drücken musste, aber bei Verwendung von pause (). Then () bekomme ich undefined.

Ich habe festgestellt, dass das Problem behoben wurde, wenn ich 150ms nach einer Pause mit dem Spielen begonnen habe. (Hoffentlich korrigiert Google bald)

playerMP3.volume = 0;
playerMP3.pause();

//Avoid the Promise Error
setTimeout(function () {      
   playerMP3.play();
}, 150);
17
Patrick

versuch es

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

Ich habe soeben unter https://developers.google.com/web/updates/2017/06/play-request-was-interrupted einen Artikel zu diesem genauen Problem veröffentlicht, der Ihnen genau sagt, was ist passiert und wie man es repariert .

4

Diese Lösung hat mir geholfen:

n.cloneNode(true).play();
3
Dmitry Kovganov

Die hier vorgeschlagenen Lösungen funktionierten entweder nicht für mich oder für zu groß, Also suchte ich nach etwas anderem und fand die von @dighan vorgeschlagene Lösung unter bountysource.com/issues/

Hier ist der Code, der mein Problem gelöst hat:

var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
    playPromise.catch(() => { media.play(); })
}

Es wird immer noch ein Fehler in die Konsole geworfen, aber zumindest wird das Video abgespielt :)

2
Sharpey

Je nachdem, wie komplex Sie Ihre Lösung haben möchten, kann dies nützlich sein:

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

Dies ist ein wenig übertrieben, hilft jedoch bei der Handhabung eines Versprechens in einzigartigen Szenarien.

2
The Blue Crayon

Dieses Stück Code für mich behoben!

Modifizierter Code von @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();
                }
            };
        };
       }
      });
1
Eliotjse

Chrome gibt ein Versprechen in den neuesten Versionen zurück. Ansonsten einfach:

        n.pause();
        n.currentTime = 0;
        setTimeout(function() {n.play()}, 0);
1
David

Beim Live-Streaming stand ich vor demselben Problem. und mein Update ist dies . Stellen Sie sicher, dass Sie in HTML-Video-TAG entfernen Sie "Autoplay" und verwenden Sie den folgenden Code, um abzuspielen.

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

Vielleicht eine bessere Lösung dafür, als ich herausgefunden habe . Spec sagt, wie von @JohnnyCoder zitiert:

media.pause ()

Setzt das angehaltene Attribut auf "true" und lädt die Medienressource bei Bedarf.

-> laden

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

gibt den Bereitschaftszustand des Mediums an HAVE_ENOUGH_DATA = 4

Laden Sie das Video grundsätzlich nur, wenn es noch nicht geladen ist. Der erwähnte Fehler ist bei mir aufgetreten, da das Video nicht geladen wurde. Vielleicht besser als ein Timeout.

1
Christoph Eberl

alle Fehler wurden entfernt: (TypeScript) 

audio.addEventListener('canplay', () => {
    audio.play();
    audio.pause();
    audio.removeEventListener('canplay');
}); 
1
ryanrain

Ich habe es mit einem Code unten behoben:

Wenn Sie spielen möchten, verwenden Sie Folgendes:

var video_play = $('#video-play');
video_play.on('canplay', function() {
 video_play.trigger('play');
});

Wenn Sie eine Pause machen möchten:

var video_play = $('#video-play');
video_play.trigger('pause');

video_play.on('canplay', function() {
  video_play.trigger('pause');
});
1
Duc Nguyen

Ich habe das gleiche Problem, endlich löse ich durch:

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

Es scheint, als hätten viele Programmierer dieses Problem festgestellt. Eine Lösung sollte ziemlich einfach sein. Medienelement gibt Promise von Aktionen zurück 

n.pause().then(function(){
    n.currentTime = 0;
    n.play();
})

sollte den Trick tun

0
pery mimon

hier ist eine Lösung aus dem googler Blog:

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)
}
0
stackFish

Alle neuen Browser unterstützen Videos, die automatisch abgespielt werden und nur stummgeschaltet sind

<video autoplay muted="muted" loop id="myVideo">
  <source src="https://w.r.glob.net/Coastline-3581.mp4" type="video/mp4">
</video>

Die URL des Videos sollte mit dem SSL-Status übereinstimmen, wenn Ihre Site mit https ausgeführt wird. Die Video-URL sollte ebenfalls in https und für HTTP identisch sein

0
Shobhit Verma

Hier eine andere Lösung, wenn der Download von Videos extrem langsam ist und das Video nicht gepuffert ist:

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

0
Taysky