A List Apart: for people who make websites

Dieses Dokument ist eine Übersetzung von A List Apart: Flash Satay.


11. November 2002—Ausgabe: 154

 

Ich habe seit Jahren mit Flash gearbeitet und war immer ein bißchen unzufrieden mit dem zum Einbinden des Films in die Webseiten notwendigen Markup. Als ich kürzlich eine Seite in XHTML veröffentlich habe, wuchs meine Unzufriedenheit mit dem Markup als ich bemerkte, dass es in diesem Kontext einfach nicht gültig war und meine Seite unfassbar aufblähte. Eine schlankere und Standardkonforme Methode zum Einbinden von Flashfilmen mußte her.

Die 'Doppelt gemoppelt' Methode

Bei Flash ist immer auf dieselbe Methode zum Einbinden in eine HTML-Seite zurückgegriffen worden. Ursprünglich war es ein Tool namens "AfterShock". Seit der Veröffentlichung von Flash 4 können Autoren HTML-Seiten mit eingebetteten Filmen auch aus der Flash Entwicklungsumgebung exportiert werden. Das dabei produzierte Markup ist der de facto Standard, den man auf 99% der Seiten findet, die Flashfilme verwenden.

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
	codebase="http://download.macromedia.com
	/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
 	width="400" height="300" id="movie" align="">
  	<param name="movie" value="movie.swf">
	<embed src="movie.swf" quality="high" width="400"
		height="300" name="movie" align="" type="application/x-shockwave-flash"
		plug inspage="http://www.macromedia.com/go/getflashplayer"> 
</object>

Wie man sehen kann ist das ein Monster. Es gibt zwei Hauptelemente, die zum Einbinden benutzt werden, was dazu führt, dass die jeweiligen Attribute doppelt angegeben werden müssen. Der Internet Explorer und ihm nahestehende Browser verwenden in erster Linie das erste Element; Browser, die sich selbst eher als Freunde von Netscape sehen nutzen die andere Methode. Deswegen wird diese Methode als 'Doppelt gemoppelt' bezeichnet.

<object> ist Teil der XHTML Spezifikation, wird aber schlecht unterstützt. Es wird von der IE-Clique benutzt, um den Flash-Player zu starten und den angegebenen Film zu laden. Das <param> Element ist sein Spielgefährte, denn er liefert eine Reihe von Parametern, wenn der Spieler einmal läft.

<embed> ist kein Teil der XHTML Spezifikation und genau das verhindert, dass die Seite validiert werden kann. Es wird von Netscape und ähnlichen Browsern genutzt, um Flash anzuzeigen. Parameter werden innerhalb des Elementes als name/value Attributpaare übergeben.

Das <embed> Element

Das <embed> Element wurde von Netscape eingeführt, um Plug-ins und Player in Webseiten einzubinden. Es ist nicht in der XHTML Spezifikation enthalten und während es andere Browser als Netscape unterstützen ist es dennoch nicht Standardkonform und wird deswegen nicht weiter diskutiert.

Auf wiedersehen <embed>!

Das <object> Element

Ohne <embed>, bleibt nur das <object> Element übrig. Es wäre umsichtig, seine Fähigkeiten zur Gänze zu verstehen. Die großartige Neuigkeit ist, dass fast alle gängigen Browser das <object> Element auf die ein oder andere Art unterstützen.

Das <object> Element hat keine zwingenden Attribute, aber mehrere die angegeben werden können. Nachfolgend werden die Interessanteren mit editierten Angaben aus der W3C Spezifikation aufgeführt.

classid (URI) Dieses Attribut kann angegeben werden, um den Ort eines Objektes mittels einer URI anzugeben. Es kann zusammen oder auch als Alternative zu dem data Attribut in Abhängigkeit des Types des Objektes angegeben werden.

codebase (URI) Dieses Attribut bietet die Möglichkeit, einen Basispfad vorzugeben, anhand dessen relative URIs, die von den classid, data und archive Attributen gegeben werden, auflösbar sind. Wenn diese Angabe fehlt, ist die BaseURI des aktuellen Dokuments der Ausgangswert.

data (URI) Dieses Attribut kann den Ort der Daten des Objektes angeben, abstrakter gesprochen: eine serialisierte Form eines Objektes, die genutzt werden kann, um es wieder darzustellen.

type (content-type) Dieses Attribut gibt den Contenttype für die mittels data angegebenen Daten an.

codetype (content-type) Hier kann der Contenttype der zu erwartenden Daten angegeben werden, wenn das mittels der classid referenzierte Objekt heruntergeladen wird.

Es gibt weitere Attribute, die beispielsweise Referenzen auf archivierte Versionen erlauben, Text darstellen während das Objekt lädt (das geht ja auch schon mit Flash), sowie width, height, id, class und andere verbreitete Attribute. Die oben aufgeführten werden aber im Falle des Einbindens von Flashfilmen interessant.

Was ich nützlicherweise auch lernte ist, dass ein <object> Element auch Kindelemente beinhalten kann, die als Alternative gebraucht werden, wenn der Browser nicht die Fähigkeit zur Darstellung des Objektes selbst hat. Tatsächlich ist das die Art, auf die das ungewünschte <embed> bei Netscape arbeitet; dazu später mehr.

Der Prozess

Mit mehr Verständnis für das Markup ausgestattet machte ich mich daran, einige Tests in verschiedenen Browsern durchzuführen. Mein erster Schritt war, dass Markup von Macromedia mit herausgelöschtem <embed> zu versuchen und an XHTML anzupassen:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
	codebase="http://download.macromedia.com
	/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
 	width="400" height="300" />
  	<param name="movie" value="movie.swf" /> 
</object>

Bedauerlicherweise funktioniert das nur mit IE-Style Browsern. Nach ein bißchen herumfrickeln und einigem Googlen, fand ich heraus, dass das GUID im classid Attribut die für diese Browser spezifische ActiveX Konfiguration enthielt. Es bleibt festzuhalten, daß dies Netscape 7 und Mozilla zum völligen Ignorieren des Objektes veranlasst. Das classid Attribut hat aber eine wichtige Funktion: Es sagt dem Browser, welchen Player er benutzen soll. Wir können es also nicht einfach loswerden ohne die Funktionalität durch etwas anderes zu ersetzen.

Glücklicherweise ist der Flashplayer so konfiguriert, dass er auf den MIME-Type application/x-shockwave-flash reagiert. Das ist großartig, weil das type Attribut uns erlaubt, den Contenttype anzugeben. Demensprechend fliegt

classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"

raus und stattdessen nutzen wir:

type="application/x-shockwave-flash"

Codebase

Obige Änderung führt nicht dazu, dass Netscape Browser die Filme von alleine abspielen. Die nächste Kuriosität auf der Liste ist das codebase Attribut. Es enthält den Pfad zu einer Kopie des Flash Plug-Ins auf Macromedias Server. Eigentlich ist das unkorrekter Gebrauch des Attributes, weil sich der angegebene Pfad innerhalb derselben Domain befinden soll; ein Sicherheitsmerkmal.

In vielen Browser (in erster Linie dem IE) hat dieses Attribut noch eine weitere Funktion. Der Pfad enthält am Ende eine Zeichenfolge, die angibt, welche Version des Plug-Ins der Server liefern soll. Wenn die angegebene Version später als derzeit installierte ist, wird der Browser den Benutzer fragen, ob ein Update durchgeführt werden soll. Der Nachteil dabei ist, dass dieses Attribut auch das Abspielen des Filmes in Netscape und Mozilla stoppt, wenn es auf diese Art gebraucht wird. Es darf also nicht weiter vorkommen. Ein Workaround um dieses Problem wird später besprochen werden. Nach dem Löschen des codebase Attributes sieht unser Markup erfreulich schlank aus:

<object type="application/x-shockwave-flash" 
 	width="400" height="300" />
  	<param name="movie" value="movie.swf" /> 
</object>

Wenn man diesen Code ausprobiert, wird sich zeigen, dass ein Film im Netscape immer noch nicht lädt. Nachdem ich so weit gekommen war, fürchtete ich nun, dass es kein valides Markup geben würde, um Flash an Netscape Browser auszuliefern und jede online gestellte Frage in dieser Hinsicht sagte mir genau das. So machte ich das, was ich dann immer machte und fing Verrücktes an.

Erste Fortschritte

Als ich das data Attribut ausprobierte, hatte ich beinahe Zustände, denn plätzlich fingen die Fiilme in Netscape und Mozilla an zu spielen. Auch ein Test im IE zeigte, dass die Filme dort nach wie vor spielen.

<object type="application/x-shockwave-flash" data="movie.swf" 
	width="400" height="300">
	<param name="movie" value="movie.swf" />
</object>	

Nach Tests mit einigen größeren Filmen, bemerte ich, dass etwas fehlt. Während alle anderen Browser es richtig hinbekamen, wartete der IE/Windows beim Streamen auf den gesamten Film, bevor er anfing, diesen abzuspielen. Das mag für kurze Filme akzeptabel sein, aber für irgendwas ernsthaftes ist das Fehlen von Streaming inakzeptabel. Valides Markup war also möglich, sobald Microsoft dieses Problem mit seinem IE/Windows gelöst hatte.

Die Satay Methode

Ein paar Tage später diskutierte ich diese Sache mit Jeffrey Zeldman, erklärte ihm, wie ich bis ganz ganz kurz vor die Lösung gekommen war. Er hatte die Probleme kurz zuvor bei projekten selber erlebt und war demnach an meinem Ansatz interessiert. Das brachte mich ans Denken und auf dem Weg nach Hause kam die Lösung.

Mein einziges Problem mit dem Code war, dass IE/Windows keine Streams abspielt. Er wartet bis der gesamte Film geladen ist und spielt ihn erst dann ab. Das ist bei sehr kleinen Filmen in Ordnung, weil die Wartezeit nicht merkbar ist. Wie wäre es denn, vorab einen sehr kleinen Containerfilm zu laden, der vor dem echten Film lädt, den wir abspielen wollen?

Ich habe es getestet und es funktioniert. Es ist ein Stück Hack, aber ein valider und nach meiner Ansicht gerechtfertigt. Das wirklich gute ist, dass mein keinen gesonderten Containerfilm für jeden Film braucht — ein kleiner Container funktioniert mit jedem Film, der dieselben Ausmaße hat.

Der Containerfilm

Ich machte einen neuen Flashfilm und setzte das folgende ActionScript in Frame 1 direkt auf die Quelle des Films:

_root.loadMovie(_root.path,0);

Das weist den Flashplayer an, den Film zu laden, dessen Name in der Variable path des Roots ist, in den Level 0 des aktuellen Films zu laden. Alles was wir nun sicherstellen müssen ist, dass der Name des Filmes, den wir geladen haben möchten in der Variablen path erscheint.

Diesen Teil macht uns Flash einfach. Der Flashplayer lädt jedes Namen/Wert-Paar das in einem Query-string an den Player weitergeben wird, in die Wurzel des Films. Das ist bei einer Vielzahl von Anwendungen nützlich, aber konkret bedeutet es, dass wir den Film wie folgt benennen:

c.swf?path=movie.swf

Der Containerfilm ist c.swf. Ich gebe ihm die path genannte Variable mit dem Wert movie.swf. Das bedeutet, dass unser ActionScript nach dem Auswerten mit nachfolgendem gleich ist:

_root.loadMovie("movie.swf",0);

Dieses Verhalten des Containerfilms könnt Ihr frei modifizieren, solange er dabei klein bleibt. Man kann beispielsweise GET und POST nutzen, um Variablen über den Container hinaus weiterzugeben, wenn man das braucht. Diese Methode funktioniert jedoch nur, wenn der Containerfilm nur ein paar Kilobyte groß ist.

Das Markup

Kommen wir zum letzten Schritt. Wir haben eine Menge Attribute weggelassen, einige neue eingefügt und alles aufgeräumt:

<object type="application/x-shockwave-flash" data="c.swf?path=movie.swf" 
	width="400" height="300">
	<param name="movie" value="c.swf?path=movie.swf" />
</object>	

Da ist es—geizig, schlanker und insgesamt besser für die Umwelt. Aber haben wir Funktionalität verloren, als wir das codebase eliminiert haben?

Der Ausgleich

Das Hauptproblem mit dem Weglassen des codebase Attributes war, dass der IE und ähnliche Browser den User auf ein zu altes Flash-PlugIn hingewiesen und zum Herunterladen einer neuen Version aufgefordert haben. Das ist sehr nützlich, denn es ist wahrscheinlich der einzige Weg, auf dem normale Webbenutzer Updates für ihren Player bekommen haben.

Die Umgehung ist simpel: bindet einfach einen überflüssigen Film am Anfang der Seite mit dem codebase-Attribut ein. Dieser Film braucht auf der Seite keinen Sinn zu machen—es ist einfach nur ein 1k großer leerer Film, der die Aufgabe hat, dem User das Herunterladen einer neuen Version zu ermöglichen, wenn seine zu alt ist. Nicht die sauberste Herangehensweise, aber eine praktische. Das sollte Euch keine Feinde machen.

Alternativer Inhalt

Erinnert Ihr Euch an das oben erwähnte Verhalten beim <object> Element, dass ein Browser das Kinelement parst, wenn er mit dem Objekt nichts anfangen kann? Das ist sehr sehr cool.

Wenn man sich den Quellcode von Macromedia.com anschaut, sieht man, dass sie ein Alternativbild anbieten, wenn der Besucher keine Flashfilme sehen kann. Sie ermitteln den Flashplayer mit JavaScript und benutzen dann abhängig vom Ergebnis der Suche JavaScript, um dynamisch das HTML zu schreiben. Sehr häßlich. Hier ist meine Herangehensweise:

<object type="application/x-shockwave-flash" data="c.swf?path=movie.swf" 
	width="400" height="300">
	<param name="movie" value="c.swf?path=movie.swf" />
	<img src="noflash.gif" width="200" height="100" alt="" />
</object>

Wenn der Browser nicht weiß, wie man Objekte mit dem MIME-Type application/x-shockwave-flash abspielt, sucht er nach dem nächsten Kindelement und versucht, dieses darzustellen. Ich denke, dass ein Bild für die meisten OK sein sollte. Wenn das nicht geht, kann man immer noch Text nehmen.

Eine Baustelle

Ich habe dieses Artikel mit der Kenntnis geschrieben, dass es nur das Wissen eines Einzelnen und demnach eine Baustelle ist. Betrachtet es als wissenschaftliche Theorie: was ich heute schreibe ist nur solange wahr, bis das Gegenteil bewiesen ist.

Ihr könnt (auf Englisch) den Fortschritt der Arbeit auf der Originalseite verfolgen, wo der Autor weitere Erkenntnisse dokumentieren wird.

Drew McLellan ist der Autor von Dreamweaver MX Web Development und ein Mitglied des Web Standards Project’s Dreamweaver Task Force. ::: Peter Richardson hat die Illustration diese Woche animiert

verwandte ALA-Stories (auf Englisch):
Flash MX: Clarifying the Concept: Joe Clark
Flash MX: Moving Toward Accessible Rich Media: Andrew Kirkpatrick
Modifying Dreamweaver to Produce Valid XHTML: Carrie Bickner

© 1998–2002 A List Apart
Übersetzt von Dominik Boecker, © 2003

dodabo.de Web-Technik und Anleitungen.

Ich danke Jeffrey Zeldman und Drew McLellan für Ihre Erlaubnis, dieses Dokument übersetzen zu dürfen.