Die canplay/canplaythrough-Ereignisse für ein HTML5-Video werden bei Firefox nicht aufgerufen. Warum?

Lesezeit: 4 Minuten

Ich baue ein jQuery-Plugin zum Verwalten von HTML5-Videos. Ich versuche, die Canplay- und Canplaythrough-Ereignisse zu erfassen. In Chrome wird das Ereignis problemlos ausgelöst. In Firefox wird es manchmal ausgelöst, manchmal nicht.

Ich vereinfache meinen Code hier ein wenig:

$('#my_video').on('canplay canplaythrough', function(){
    console.log('canplay event fired');
});

Ich habe es auch mit dem nativen Javascript .addEventListener() versucht und es funktioniert nicht.

Irgendeine Idee, warum das Ereignis in Firefox nicht aufgerufen wird und wie man das beheben kann?

HINWEIS: Bitte sagen Sie mir nicht, dass ich eines der bereits verfügbaren Plugins wie jplayer und video-js verwenden soll, ich weiß, dass sie existieren und gut funktionieren, aber ich muss eine interne Lösung bauen.

Die canplaycanplaythrough Ereignisse fur ein HTML5 Video werden bei Firefox nicht aufgerufen
Pierre Spring

Das Problem ist, dass Sie video Element hat ausgelöst canplaythrough event, bevor Sie den Event-Handler registriert haben.

Wie Sie in Ihrer eigenen Antwort betont haben, können Sie Ihre Skripts in die <head>aber das ist schlecht für Ihre Seitenleistung.

Eine bessere Möglichkeit, Ihr Problem zu beheben, besteht darin, die zu überprüfen readystate -Attribut und führen Sie Ihre Funktion in diesem Fall manuell aus:

var $video = $('video'),
    videoElement = $video[0];

$video.on('canplaythrough', callback);

// If the video is in the cache of the browser,
// the 'canplaythrough' event might have been triggered
// before we registered the event handler.
if (videoElement.readyState > 3) {
  callback();
}

  • Beste Antwort! Überprüfen Sie den Bereitschaftsstatus des Videos und fügen Sie den Ereignis-Listener hinzu, wenn readyState dies nicht ist 4 oder höher.

    – peirix

    16. Oktober 2014 um 17:56 Uhr

  • Erstaunliche Antwort! Dies ist die eine. Danke!!!! @Gabriel, Sie sollten dies sicher als Antwort markieren

    – 30 Sekundenstosam

    23. November 2014 um 21:49 Uhr


  • Skripte nicht in den Kopf zu stecken ist schlecht für: Skripte schreiben insgesamt und zeigt einen Mangel an nicht nachvollziehbaren Standards: nutze die defer Attribut, Skripte im Kopf behalten und trotzdem die gleiche Performance haben.

    – John

    23. September 2015 um 21:36 Uhr

  • @John: Ich bin mir ziemlich sicher, dass das Hinzufügen der <script> Etikett zum <head> mit einer defer wird zu demselben Problem führen, das @Gabriel beschrieben hat.

    – Pierre Spring

    24. September 2015 um 12:41 Uhr

  • Nein du immer behalte Skripte im Head-Element und dann das Problem lösen. Verschieben von Skripten in die body -Element ist eine schlechte Praxis und sogar das Verschieben der Skripte zwischen den Elementen body und head Element ist ein klares Verständnis von JavaScript auf Amateurniveau.

    – John

    24. September 2015 um 18:25 Uhr


Der wahrscheinlichste Grund, warum Sie dies sehen, hat wahrscheinlich mit Timing-Problemen zu tun. Sie haben in Ihrer akzeptierten Antwort angegeben, dass das Einfügen von jQuery in den Kopf und nicht in die Fußzeile das Problem löst. Dies sagt mir, dass das Problem die DOM-Analyse und die Ausführungsreihenfolge des Skripts ist. Der wahrscheinlichste Schuldige ist, dass die Ereignisse „canplay“ und „canplaythrough“ ausgelöst wurden, bevor jquery und Ihr Seitenskript analysiert und die Ereignishandler hinzugefügt wurden – aber nur manchmal, abhängig vom Netzwerkverkehr und den Ladezeiten. Indem Sie das Skript in den Kopf gesetzt haben, haben Sie Ihre Ereignisbindung erzwungen, bevor die DOM-Elemente erstellt wurden, und dadurch sichergestellt, dass Sie keine Ereignisse verpassen.

Abgesehen davon sind die Leistungsvorteile der Platzierung von Skriptelementen am Ende der Seite umstritten. Wenn Sie die Seitenleistung wirklich optimieren möchten, verwenden Sie etwas wie LABjs, um das parallele Laden von Skripten zu verwalten.

In meinem Fall wurde dies durch die bestimmt preload Attribut, das für das Element angegeben ist. Ich hatte es überhaupt nicht angegeben, also entschieden sich verschiedene Browser, unterschiedliche Dinge zu tun.

Einmal habe ich angegeben preload="auto"der on("canplay") Event-Handler hat gut/wie erwartet funktioniert.

Auch wenn meine Frage überhaupt keine Aufmerksamkeit erregt hat, denke ich, dass es eine gute Idee ist, eine Erklärung für Leute zu geben, die in Zukunft darüber stolpern könnten …

Das Problem ist wirklich seltsam: Wenn der jQuery-Kern in der Fußzeile enthalten ist, funktionieren einige der Videoereignisse nicht. Wenn der jQuery-Core im Head des Dokuments eingebunden ist, werden alle Events korrekt aufgerufen.

Die Lösung besteht also darin, den jQuery-Kern in den HTML-Kopf aufzunehmen, auch wenn “Best Practices” für die Optimierung empfehlen, das gesamte Skript für schnellere Ladezeiten am Ende des Körpers zu platzieren.

Ich denke auch, dass dies eine Rennbedingung ist. Die Art und Weise, wie ich damit umgegangen bin, ist folgende:

Fügen Sie im HTML des Videoelements das Attribut preload=”metadata” hinzu, um nur die Videometadaten vorab zu laden. Damit:

<video id="myVideo" width="640" height="480" preload="metadata" />

Als nächstes im JS:

var $vid = $("#myVideo");
$vid.bind("canplaythrough", console.log("can play through full video"));
$vid.get(0).load();

Dies hat die Nachricht für mich in Chrome protokolliert – habe es nicht anderswo getestet.

Wenn Sie erwarten, dass Firefox nach dem Auslösen das gesamte Audio lädt load dann würde es das nicht tun. Es wird die feuern loadstart aber nichts herunterladen. Nein progress Ereignisse werden gefeuert. Und es wird tatsächlich keine Anfrage an diese Datei gestellt. Sie können dieses Verhalten im Firebug sehen.

Firefox beginnt erst mit dem Laden der Datei, nachdem Sie „Play“ ausgelöst haben.

Nachweisen. Siehe Konsolenausgabe.

Die canplaycanplaythrough Ereignisse fur ein HTML5 Video werden bei Firefox nicht aufgerufen
Troja Valle

Hinzufügen:

var video = $('video');
video.trigger('load');

Nach dem Das Hinzufügen des Canplaythrough-Ereignis-Listeners hat es für mich in Firefox und Safari behoben.

994380cookie-checkDie canplay/canplaythrough-Ereignisse für ein HTML5-Video werden bei Firefox nicht aufgerufen. Warum?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy