HTML5 Video als Flashfallback

Tja, das Web wäre soweit, aber die User noch nicht. Daher gibt es doch relativ oft die Anforderung einen bestehenden Flashplayer bei Geräten zu ersetzen die kein Flash installiert haben.

Dabei gibt es zwei Dinge zu beachten: Kann der Browser ohne Flash überhaupt HTML5 Video und liefert man die richtigen Codecs aus – sonst schaut der User ja auch wieder in die Röhre.

Wenn zum Beispiel ein IE8 kein Flash installiert hat und man einfach als Fallback den <video>-Tag eingebunden hat ist dem User nicht geholfen.

Mit folgendem Javascript Code kann man daher auf diesen Umstand reagieren:

if (!!(document.createElement('video').canPlayType)) {
  /* das hier wird nur von html5 browsern ausgeführt */
  ...
}

In dem oben genannten Fall (IE8 ohne Flash) reicht eigentlich die Ausgabe des „Installieren Sie doch mal Flash“ Textes.

Der zweite Punkt ist wesentlich interessanter. Als prominentester Nicht-MP4-Browser ist wohl Firefox anzuführen, dicht gefolgt vom Chromiun (nicht zu verwechseln mit Google Chrome). Wenn man diesen beiden Browser ein mp4 serviert, sagt Firefox nachdem man auf play geklickt hat, dass der mimetype nicht stimmt, und Chromium tut einfach so als würde er was laden, sagt aber nicht direkt warum nix angezeigt wird.

Das Codecproblem ist innerhalb des <video>-Tag gelöst indem man verschiedene Sourcen mit verschiedenen mime-types angibt:

Aber wenn man sowieso alles in Javascript schreibt, reicht auch die Angabe des einen richtigen Videos und dafür gibt es die Funktion canPlayType(). Diese Methode ist auf einem <video>|<audio> Tag verfügbar:

if (!!(document.createElement('video').canPlayType)) {
  /* das hier wird nur von html5 browsern ausgeführt */
  var v = document.createElement('video');
  if (!!v.canPlayType('video/mp4')) {
    /* hier kann man das Video Element einbinden */
  }
}

Die Dokumentation von canPlayType() ist sehr empfehlenswert. Als Rückgabewerte gibt es einen leeren String „“ wenn dieser Codectype nicht wiedergegeben werden kann, „maybe“ wenn es sein kann, und „probably“ wenn es wahrscheinlich ist. Solange man nur den Mimetype angibt kommen hier durchaus falsche Ergebnisse heraus, so wird dem Chromiun die MP4-Wiedergabe als „maybe“ bescheinigt. Wenn man also sicher ist, mit welchem Codec das Video kodiert ist, sollte man diesen auch mitangeben. Wie gesagt, das obige Beispiel erzeugt durchaus auch Fehleinschätzungen.

Wenn man relativ sicher ist, dass das Video wiedergegeben werden kann, kann man das erstellte <video>-Element konfiguieren:

if (!!(document.createElement('video').canPlayType)) {
  /* das hier wird nur von html5 browsern ausgeführt */
  var v = document.createElement('video');
  if (!!v.canPlayType('video/mp4')) {
    /* hier kann man das Video Element einbinden */
    $(v).attr('src','http://www.example.com/video.mp4'); // die URL zum Video
    $(v).attr('poster','http://www.example.com/poster.jpg'); // bei relativen Angaben bestrafen einen i-Devices indem sie kein Poster anzeigen
    $(v).attr('controls','true'); // zeige die Browser Controller
    $(v).attr('width','1920');
    $(v).attr('height','1080');
    $(v).attr('preload','none'); // keine Daten vorladen, nur poster anzeigen
  }
}

Fehlt nur noch die Einbindung in die Seite. Wenn man das Flashobjekt per Hand erstellt hat, bietet sich an, diesem eine ID zu geben und diese dann zu ersetzten, bei swfObject oder ähnlichem hat man ja meistens sowieso ein div mit einer id in das der Player eingefügt wird:

if (!!(document.createElement('video').canPlayType)) {
  /* das hier wird nur von html5 browsern ausgeführt */
  var v = document.createElement('video');
  if (!!v.canPlayType('video/mp4')) {
    /* hier kann man das Video Element einbinden */
    $(v).attr('src','http://www.example.com/video.mp4'); // die URL zum Video
    $(v).attr('poster','http://www.example.com/poster.jpg'); // bei relativen Angaben bestrafen einen i-Devices indem sie kein Poster anzeigen
    $(v).attr('controls','true'); // zeige die Browser Controller
    $(v).attr('width','1920');
    $(v).attr('height','1080');
    $(v).attr('preload','none'); // keine Daten vorladen, nur poster anzeigen
    $('#flashplayerid').replace(v); // flash objekt ersetzten
    $('#swfObjectdiv').append(v); // swfObject Ziel div befüllen
  }
}

Ein Tipp zur mp4-codierung für i-Devices: Die Kunst ein mp4-File i-Device kompatibel zu erstellen lagere ich mittlerweile immer an den Adobe Media Encoder aus, dieser hat eine Menge Presets die dann auch wirklich funktionieren.