19 Vorladen und Player erkennen
Filme vorladen und veröffentlichenSie werden lernen:- Wie laden Sie den Inhalt eines Flash-Films vor?
- Wie viel Vorladen macht Sinn?
- Wie unterscheiden sich verschiedene Flash-Player-Versionen?
- Wann ist eine Unterscheidung der Versionen angebracht?
Wer recht erkennen will, muss zuvor in richtiger Weise gezweifelt haben. – Aristoteles
Bei größeren Filmen »tröpfeln« die Daten manchmal sehr langsam durch die Leitung. Damit die schöne Animation oder das mitreißende Video nicht mit Aussetzern abgespielt wird oder der Nutzer womöglich gar kein Bild sieht, kommen Preloader zum Einsatz. Auf Deutsch heißt Preloader einfach Vorlader. Solche Preloader gibt es mehr als genug im Netz. Wir zeigen Ihnen hier, was an ActionScript dahinter steckt.
Im Gegensatz zum Preloader kommt die Versionserkennung für den Flash-Player eher selten zum Einsatz. Dabei kann sie durchaus interessante Fragen beantworten: Ist ein Flash-Player vorhanden? Wenn ja, welche Version?
19.1 Vorladen
Vorladen ist einfach zu realisieren. Sie benötigen:
- eine Grafik oder ein Textfeld, das den Ladestatus anzeigt;
- ein Skript, das prüft, wie viel Prozent eines Films schon geladen sind.
Ursprung |
Besonders wichtig ist der Registrierungspunkt des Balkens. Da der Balken in diesem Beispiel nach rechts verlaufen soll, befindet sich der Registrierungspunkt an seinem linken Rand. Der Grund dafür: Das Laufen des Balkens wird mit seiner Breite _width angepasst. Wenn Sie die Breite verändern, geschieht das ausgehend vom Registrierungspunkt in positiver Richtung (also nach links). Sollte der Balken in die andere Richtung gehen, müsste sich der Balken links vom Registrierungspunkt befinden. |
Die Technik, die hinter dem Skript steckt, besteht aus zwei Eigenschaften und zwei Methoden der MovieClip-Klasse:
- _framesloaded ist eine Eigenschaft, die anzeigt, wie viele Bilder eines MovieClips bereits geladen wurden.
- _framestotal liefert als Eigenschaft, wie viele Bilder ein MovieClip besitzt.
- getBytesLoaded() gibt an, wie viele Bytes eines MovieClips schon geladen sind. Diese Methode ist etwas genauer als die Angabe der Bilder, da ein Bild unter Umständen mehrere Daten enthalten kann.
- getBytesLoaded() liefert als Methode die Gesamtgröße des MovieClips.
Aus diesen Eigenschaften und Methoden ergeben sich zwei Möglichkeiten, einen Preloader zu realisieren: entweder mit Bildern oder mit Bytes.
Mit Bildern
Ein Preloader mit Bildern hat einen großen Nachteil: Jedes Bild kann unterschiedlich große Datenmengen beinhalten. Sehen Sie sich am folgenden Beispiel an, wie der Preloader funktioniert, aber auch wo er unpraktisch ist.
Ausgangssituation ist die Datei preloader_bilder.fla auf der CD-ROM. Sie besteht aus drei Bildern, wobei das dritte Bild den eigentlichen Inhalt des Films enthält, hier ein Video. Die ersten zwei Bilder beinhalten den Preloader.
Abbildung 19.1 Die Flash-Rohform der Preloader-Elemente.
Unser Preloader soll aus mehreren Elementen bestehen: Zwei Textfelder nehmen die Gesamtzahl der Bilder (Variable bildergesamt_str) und die bereits geladenen Bilder (bildergeladen_str) auf. Ein Fortschrittsbalken (balken_mc) zeigt, wie weit der Ladevorgang bereits gediehen ist. Die zwei Pfeile über dem Balken drehen sich, um einen Ladevorgang anzudeuten.
Schritt für Schritt: Preloader mit Bildern
Für den Preloader landet der Code komplett in den Schlüsselbildern des Hauptfilms.
Zuerst stellen Sie in Schlüsselbild 1 (auf der Ebene ActionScript) fest, wie viele Bilder der Flash-Film beinhaltet (_totalframes) und schreiben diese Zahl in das zugehörige Textfeld:
var bildergesamt_num:Number = this._totalframes; bildergesamt_str = bildergesamt_num.toString();
Anschließend definieren Sie eine Variable, die die geladenen Bilder aufnehmen soll:
var bildergeladen_num:Number;
Nun benötigen Sie ein wiederkehrendes Ereignis. Seit Flash 5 bietet sich dazu das Ereignis enterFrame an. Wir setzen es hier direkt als Ereignisprozedur ein:
this.onEnterFrame = function() {
Ereignisprozeduren sind auf Versionen ab Flash MX beschränkt. Insofern müssen Sie in Flash 5 das Ereignis enterFrame in der Aktion eines MovieClips aufrufen.
Anschließend stellen Sie mit der Eigenschaft _framesloaded fest, wie viele Bilder des Hauptfilms bereits geladen sind:
bildergeladen_num = this._framesloaded; bildergeladen_str = bildergeladen_num.toString();
Entsprechend ändern Sie die Breite auf dem Fortschrittsbalken:
balken_mc._width = Math.round((bildergeladen_num / bildergesamt_num) * 200);
Die Breite berechnet sich aus den geladenen Bildern geteilt durch die Gesamtzahl der Bilder. Dies liefert einen Wert zwischen 0 (kein Bild geladen) und 1 (alles geladen). Mit 200 multipliziert wird daraus die Länge des Fortschrittsbalkens, wenn er maximal 200 Pixel lang werden kann. Dieser Wert lässt sich bei einem längeren Fortschrittsbalken einfach anpassen.
Prüfen Sie, ob bereits alle Bilder geladen sind. Wenn ja, wird der eigentliche Film abgespielt. Wenn nein, macht der Fim einfach mit Bild 2 weiter. Der eigentliche Film kann natürlich auch in einer neuen Szene beginnen. Wir starten ihn hier in Bild 3.
if (bildergeladen_num > 0 && bildergeladen_num == bildergesamt_num) { gotoAndStop(3); } };
Die Überprüfung stellt nicht nur fest, ob die Zahl der geladenen Bilder der Gesamtzahl aller Bilder des Films entspricht, sondern schließt von vorneherein aus, dass noch gar kein Bild geladen wurde (bildergeladen_num > 0). Somit besteht auch nicht die Gefahr, dass ein Film beispielsweise gelöscht wurde und deswegen die Länge 0 hat.
Wenn der Film in Schlüsselbild 2 weiterspielt, ist das Vorladen noch nicht beendet. Deswegen springen Sie in diesem Film wieder zurück auf Bild 1:
gotoAndPlay(1);
Wenn Sie das Ergebnis testen möchten, werden Sie auf einem lokalen System eine Überraschung erleben: Das dritte Schlüsselbild erscheint quasi sofort. Das liegt daran, dass der lade-intensive Film im dritten Schlüsselbild nur aus dem Dateisystem des Rechners geholt und nicht aus dem Internet geladen werden muss. Sie können beim Testen aber auch einen Download simulieren. Klicken Sie dazu nach dem Aufruf von Testen ( + ) auf das Menü Ansicht • Download simulieren. Mit dem Befehl darunter, Ansicht • Download-Einstellungen, können Sie die simulierte Übertragungsgeschwindigkeit ändern.
In Flash MX gibt es Download simulieren noch nicht. Hier muss der Bandbreiten-Profiler aktiviert sein (Menü Ansicht). Unter Fehlersuche ändern Sie die Download-Geschwindigkeit.
Abbildung 19.2 Links läuft noch der Fortschrittsbalken, rechts startet schon der Film.
Sie finden die Datei unter dem Namen preloader_bilder_AS2.fla bzw. preloader_bilder_AS1.fla auf der CD-ROM. Das Beispiel zeigt das Problem, wenn Sie Bilder verwenden: Das Laden des Videos dauert besonders lange, das erste Bild ist dagegen sofort geladen. Im nächsten Abschnitt lesen Sie, wie Sie dieses Problem lösen, indem Sie die geladenen Bytes überprüfen.
Mit Bytes
Je ungleicher die Datengrößen in den einzelnen Bildern sind, desto schwieriger wird es, den Fortschritt mit Bildern zu überprüfen. In solchen Fällen eignet sich die Filmgröße gemessen in Bytes besser.
Bits und Bytes |
Ein Byte besteht aus acht Bit. Dateigrößen werden im Allgemeinen in Kilobyte (KB) angegeben. Um Bytes in Kilobytes umzurechnen, teilen Sie die Bytes durch 1024 (entspricht 210). |
Um Ihnen das zu zeigen, wandeln wir das Beispiel aus dem letzten Abschnitt leicht ab. Die Ausgangsdatei auf der beiliegenden CD-ROM heißt preloader_bytes.fla. Die Textfelder zeigen nicht die Bilder, sondern Kilobytes an (Variablen kbgesamt_str und kbgeladen_str).
Schritt für Schritt: Preloader mit Bytes
Auch hier landet der Code in den Schlüsselbildern des Hauptfilms.
Zuerst stellen Sie in Schlüsselbild 1 auf der Ebene ActionScript fest, wie groß der MovieClip ist, und geben diese Information umgewandelt in Kilobytes aus:
var kbgesamt_num:Number = Math.round(this.getBytesTotal()/1024); kbgesamt_str = kbgesamt_num.toString(); var kbgeladen_num:Number;
Als Nächstes folgt die Ereignisprozedur, um zu überprüfen, wie viele Bytes geladen sind:
this.onEnterFrame = function() {
Mit getBytesLoaded() testen Sie, wie viele Bytes des MovieClips bereits geladen sind:
kbgeladen_num = Math.round(this.getBytesLoaded()/1024); kbgeladen_str = kbgeladen_num.toString();
Wir wandeln hier die Bytes in Kilobytes um.
Die Breite des Fortschrittsbalkens berechnet sich aus den geladenen Kilobytes, geteilt durch die gesamten Kilobytes und multipliziert mit der maximalen Länge des Balkens:
balken_mc._width = Math.round((kbgeladen_num / kbgesamt_num) * 200);
Wurde der Balken komplett geladen, springen Sie auf Schlüsselbild 3:
if (kbgeladen_num > 0 && kbgeladen_num == kbgesamt_num) { gotoAndStop(3); } };
In Schlüsselbild 2 der Ebene ActionScript springen Sie zurück auf Bild 1, da der Film in diesem Fall noch nicht komplett geladen ist:
gotoAndPlay(1);
Abbildung 19.3 Der Fortschrittsbalken kriecht linear, wenn Sie einen Download simulieren.
Die fertige Datei finden Sie auf der CD-ROM unter dem Namen preloader_bytes_AS2.fla. Die Datei preloader_bytes_ohnebild2_AS2.fla enthält eine Variante: Der Film wird auf Schlüsselbild 1, also bei der Fortschrittsanzeige, angehalten und Bild 2 ist komplett herausgelöscht. Beide Dateien finden Sie auch für ActionScript 1 im Ordner Flash MX.
Restzeit berechnen
Interessant bei einem Download können ein paar andere Informationen sein, beispielsweise wie viel Prozent schon geladen sind. Diese Berechnung kennen Sie von der Länge des Balkens, nur dass Sie statt mit der Balkenlänge jetzt mit dem Prozentwert 100 multiplizieren müssen:
var prozent:Number = Math.round((kbgeladen_num / kbgesamt_num) * 100);
Eine zweite interessante Information ist die Ladezeit, die noch benötigt wird. Hier greifen Sie auf die bereits geladene Byte-Menge zu und messen mit der bisher vergangenen Zeit die aktuelle Ladegeschwindigkeit.
Mit wenigen Anpassungen können Sie diese Funktionalität in den verwendeten Preloader integrieren. Die Ausgangsdatei für die nächsten Schritte ist preloader_restzeit.fla auf der CD-ROM. Als einzigen Unterschied zu den vorigen Varianten finden Sie hier ein Textfeld für die verbleibende Zeit (Variable verbleibend_str).
Schritt für Schritt: Restzeit berechnen
Der Code für den Preloader landet komplett im ersten Schlüsselbild des Hauptfilms auf der Ebene ActionScript.
Zu Anfang speichern Sie die Gesamtzahl der Kilobytes in einer Variablen und geben Sie aus:
var kbgesamt_num:Number = Math.round(this.getBytesTotal() / 1024); kbgesamt_str = kbgesamt_num.toString();
Außerdem definieren Sie Variablen für die geladenen kilobyte und für die verbleibende Zeit. Die Variable i dient als Zeitzähler.
var kbgeladen_num:Number; var verbleibend_num:Number; var i:Number = 0;
Der Zeitzähler ist das entscheidende Element. Um die bisherige Ladegeschwindigkeit zu erhalten, müssen Sie die Zeit mit einberechnen, in der die bereits geladenen Kilobytes durch die Leitung gekommen sind.
Da die Ereignisprozedur onEnterFrame von der Abspielgeschwindigkeit des Films abhängig ist, verwenden Sie stattdessen setInterval(Funktion, Interval), um in regelmäßigen Abständen den Ladezustand zu prüfen:
var id:Number = setInterval(pruefen, 100);
Sie rufen die Funktion pruefen() alle 100 Millisekunden auf.
Den Anfang der Funktion pruefen() kennen Sie bereits: Sie stellen die gerade geladenen Kilobytes fest und bestimmen die Länge des Fortschrittsbalkens.
function pruefen() { kbgeladen_num = Math.round(_root.getBytesLoaded() / 1024); kbgeladen_str = kbgeladen_num.toString(); balken_mc._width = Math.round((kbgeladen_num / kbgesamt_num) * 200);
In den nächsten Schritten erweitern Sie die Funktion um die Restzeit-Berechnung.
Zählen Sie den Zähler um 100 nach oben:
i += 100;
Vielleicht erkennen Sie jetzt schon den Sinn des Zählers: Er nimmt die bereits vergangene Zeit in Millisekunden auf.
Anschließend berechnen Sie mit folgender Formel die verbleibende Downloadzeit:
verbleibend_num = Math.round((kbgesamt_num – kbgeladen_num) / ((kbgeladen_num / i) * 1000));
Die Restzeit ist die verbleibende Byte-Menge (Kilobyte-Gesamtzahl abzüglich der bereits geladenen Kilobytezahl) geteilt durch die Ladegeschwindigkeit. Die Geschwindigkeit setzt sich zusammen aus der geladenen Kilobytemenge geteilt durch die vergangenen Millisekunden. Beides multiplizieren Sie mit 1000, um die Geschwindigkeit in KB pro Sekunde zu erhalten. Da insgesamt KB durch KB pro Sekunde geteilt werden, erscheint das Ergebnis als Zeit in Sekunden.
Die Restzeit übergeben Sie an das Textfeld und fügen zwecks ordentlicher Formatierung noch einen String mit der Zeiteinheit an:
verbleibend_str = verbleibend_num.toString() + " S.";
Wenn die Datei komplett geladen ist, beenden Sie das Intervall und springen auf das zweite Schlüsselbild – und damit auf den Inhalt des SWF-Films:
if (kbgeladen_num > 0 && kbgeladen_num == kbgesamt_num) { clearInterval(id); gotoAndStop(2); } }
Sie sollten das Intervall immer löschen, da die dauernden Funktionsaufrufe sonst zu viel Performance auf Ihrem Rechner kosten. Beim Testen fällt auf, dass am Anfang die verbleibende Zeit hochschnellt und sich dann erst einpendelt.
Abbildung 19.4 Bei langsamer Download-Geschwindigkeit kann es etwas dauern.
Die fertige Datei finden Sie unter preloader_restzeit_AS2.fla bzw. preloader_restzeit_AS1.fla auf der CD-ROM zum Buch.
Preloader mit externer Datei
Ein Preloader in einer Datei ist nicht immer erwünscht, weil er nicht sehr modular ist, das heißt, bereits die ersten Bilder des Films belegt und von dort auch nur umständlich zu entfernen ist. Praktischer wäre es, wenn der Preloader ein eigenes SWF wäre und den Hauptfilm als externes SWF laden würde.
Hier gibt es nur ein Hindernis: getBytesTotal() liefert erst nach einer kurzen Zeit die korrekte Gesamtzahl an Bytes. Dieser Moment sorgt dafür, dass Sie einen Trick anwenden müssen: Sie prüfen die Gesamtzahl der Bytes erst nach einer kurzen Zeitspanne, die Sie mit setInterval() erreichen. Sonst würde am Anfang die Gesamtzahl der Bytes falsch berechnet. setInterval() können Sie auch dazu verwenden, den Ladefortschritt zu überwachen. Die Änderungen gegenüber dem normalen Preloader finden Sie im folgenden Code fett hervorgehoben:
Adressierungsprobleme |
Vorsicht, wenn Sie im Hauptfilm die absolute Adressierung verwenden, führt das externe Laden des Hauptfilms in den Film des Preloaders zu Problemen, wenn der Hauptfilm nicht auf Level 0 kommt. In diesem Fall können Sie in Flash MX 2004 und 8 die Eigenschaft _lockroot für den MovieClip, in den der Hauptfilm geladen wird, auf true schalten. Dieses Problem finden Sie ausführlicher besprochen in Kapitel 18, »Externe Filme«. |
_root.createEmptyMovieClip("inhalt_mc", 0); _root.inhalt_mc._lockroot = true; _root.inhalt_mc.loadMovie("testvideo.swf"); var kbgeladen_num:Number; var kbgesamt_num:Number; var id = setInterval(pruefen, 100); function pruefen() { kbgesamt_num = Math.round(_root.inhalt_mc.getBytesTotal() / 1024); kbgesamt_str = kbgesamt_num.toString(); kbgeladen_num = Math.round(_root.inhalt_mc.getBytesLoaded() / 1024); kbgeladen_str = kbgeladen_num.toString(); balken_mc._width = Math.round((kbgeladen_num / kbgesamt_num) * 200); if (kbgeladen_num > 0 && kbgeladen_num == kbgesamt_num) { clearInterval(id); } }
Die fertige Datei finden Sie auf der CD-ROM unter preloader_extern_AS2.fla bzw. für Flash MX unter preloader_extern_AS1.fla im Ordner FlashMX.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.