2012-06-28 13 views
8
suchen

Sehr seltsamer Fehler, den ich nicht herausfinden kann.HTML5-Video auf IPad abspielen und

Ich versuche, ein HTML5-Video von einer bestimmten Position aus zu spielen, wenn ein Benutzer auf Play klickt. Ich versuche, es richtig zu suchen, wenn das Video zu spielen beginnt.

Auf meinem Spiel Veranstaltung mache ich this.currentTime = X

auf dem Browser-Fein es funktioniert. Aber auf dem IPad, wenn ich das Video abspiele, sucht das Video nicht nach der richtigen Position (es beginnt bei Null).

Noch seltsamer, wenn ich den this.currentTime = X Anruf in einem SetTimeout von sagen wir 1 Sekunde mache, funktioniert es auf dem IPad (manchmal).

Antwort

-2

Schätzen Sie die folgenden Antworten. Leider musste man nur mal innerhalb von timeupdate nachsehen, ob die currenttime> 0 und < 1 war, wenn es dann zu diesem Teil des Videos ging und den Listener zum timeupdate löschte.

-2

bereit X-1 dezimal

X.toFixed(1); 

zu begrenzen Wie Sie erwähnten es manchmal nach einer Zeit von 1 Sekunde arbeitet. Haben Sie versucht, die Position festzulegen, nachdem das Ereignis playing ausgelöst wurde? oder vielleicht sogar das canplaythrough Ereignis

einen Blick auf die Quelle von this page Nehmen Sie eine ganze Liste von Ereignissen zu sehen, die (in der Javascript-Datei) verwendet werden kann

+0

Bereits versucht: - \. Kein Würfel. – K2xL

4

auf iOS, Videos Last at play time (siehe Punkt # 2), nicht zur Seitenladezeit. Meine Vermutung ist, dass das Video nicht geladen wird, wenn Sie this.currentTime = X ausführen, also hat es keinen Effekt. Dies erklärt auch, warum eine Verzögerung des Vorgangs manchmal das Problem beheben kann: Manchmal ist es nach einer Sekunde geladen, manchmal nicht.

Ich habe nicht ein iOS-Gerät zu testen, aber ich würde vorschlagen, einen loadeddata Zuhörer an die Video Bindung, so dass Ihre currentTime Manipulation geschieht erst nach der Video-Laden beginnt:

// within the play event handler... 
if(!isIOSDevice) { 
    this.currentTime = X; 
} else { 
    function trackTo(evt) { 
     evt.target.currentTime = X; 
     evt.target.removeEventListener("loadeddata", trackTo) 
    }); 
    this.addEventListener("loadeddata", trackTo); 
} 

Sie über Sie müssen isIOSDevice an anderer Stelle in Ihrem Code festlegen, abhängig davon, ob der aktuelle Besuch von einem iOS-Gerät stammt.

+1

wow. es hat tatsächlich funktioniert. endete mit der Verwendung von Popcorn-Bibliothek (für diejenigen, die auch Popcorn js, hören für loadedata Ereignis) – K2xL

+0

+1 schön detaillierte, aber prägnante Antwort – steveax

+0

@ K2xL Großartig, froh, dass Sie es behoben! Ich habe meine Antwort aktualisiert, um 'loadeddata' zu verwenden, wie Sie vorschlagen. (Und es stellt sich heraus, 'loadeddata' ist ein Standard-HTML5-Ereignis, nicht nur ein benutzerdefiniertes Popcorn-Ereignis.) – apsillers

3

Während diese Frage ziemlich alt ist, bleibt das Problem offen. Ich habe eine Lösung gefunden, die auf mehreren getesteten iPads funktioniert (1 + 2 + 3) für iOS 5 und 6 (iOS3 + 4 nicht getestet):

Grundsätzlich müssen Sie zunächst auf das ursprüngliche Ereignis playing warten und dann eine Eins hinzufügen Zeitbinder für canplaythrough und dann für progress - nur dann können Sie tatsächlich den currentTime Wert ändern. Alle Versuche davor werden fehlschlagen!

Das Video muss zuerst abgespielt werden, was eine schwarze Ebene über dem Videoelement praktisch macht. Leider klingt, in dem Video nicht über Javascript deaktiviert werden kann -> kein perfektes UX

// https://github.com/JoernBerkefeld/iOSvideoSeekOnLoad/MIT License 
// requires jQuery 1.8+ 
// seekToInitially (float) : video-time in seconds 
function loadingSeek(seekToInitially, callback) { 
    if("undefined"==typeof callback) { 
     callback = function() {}; 
    } 
    var video = $("video"), 
     video0 = video[0], 
     isiOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/) !== null, 
     test; 
    if(isiOS) { // get the iOS Version 
     test =navigator.userAgent.match("OS ([0-9]{1})_([0-9]{1})"); 
     // you could add a loading spinner and a black layer onPlay HERE to hide the video as it starts at 0:00 before seeking 
     // don't add it before or ppl will not click on the play button, thinking the player still needs to load 
    } 
    video.one("playing",function() { 
     if(seekToInitially > 0) { 
      //log("seekToInitially: "+seekToInitially); 
      if(isiOS) { 
       // iOS devices fire an error if currentTime is set before the video started playing 
       // this will only set the time on the first timeupdate after canplaythrough... everything else fails 
       video.one("canplaythrough",function() { 
        video.one("progress",function() { 
         video0.currentTime = seekToInitially; 
         video.one("seeked",function() { 
          // hide the loading spinner and the black layer HERE if you added one before 

          // optionally execute a callback function once seeking is done 
          callback(); 
         }); 
        }); 
       }); 
      } else { 
       // seek directly after play was executed for all other devices 
       video0.currentTime = seekToInitially; 

       // optionally execute a callback function once seeking is done 
       callback(); 
      } 
     } else { 
      // seek not necessary 

      // optionally execute a callback function once seeking is done 
      callback(); 
     } 
    }); 
} 

das Ganze von my GitHub repo heruntergeladen werden kann

1

apsillers ist richtig.Sobald das Video abgespielt wird, erscheint der Quicktime-Player und das Video kann nicht gefunden werden, bis das erste "Fortschritt" -Ereignis ausgelöst wird. Wenn Sie versuchen, danach zu suchen, erhalten Sie einen ungültigen Statusfehler. Hier ist mein Code:

cueVideo = function (video, pos) { 
    try { 
     video.currentTime = pos; 

    // Mobile Safari's quicktime player will error if this doesn't work. 
    } catch(error) { 
     if (error.code === 11) { // Invalid State Error 

      // once 'progress' happens, the video will be seekable. 
      $(video).one('progress', cueVideo.bind(this, video, pos)); 
     } 
    } 
}