• beyond tellerrand – play. Register Now!
Zurück   Flashforum > Flash > ActionScript > ActionScript 1

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 08-02-2005, 03:17   #1 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
[TUTORIAL]MP3-Player mit XML-Fütterungszeit - Part II

Das ist Part II zum Tutorial MP3-Player mit XML-Fütterungszeit - Part II
hier geht's zu Part I


MP3-Player mit XML-Fütterungszeit - Part II



Inhalt
0. Einleitung
1. Zeitanzeige
1.1. Digitale Zeitanzeige
1.2. Visuelle "Balken-Zeitanzeige" + Ladestatus der Mp3
1.2.1. wichtiges für's Layout
1.2.2. Script für Balken und Pointer
1.2.2.1. Preloader
1.2.2.2. Pointer
1.2.2.2.1. Vorarbeit (Bitrate der Mp3s)
1.2.2.2.2. XML update
1.2.2.2.3. Das Pointer-Script
1.2.2.3. fertiger Prototype
2. Lautstärkeregulierung
2.1. Vorüberlegungen und Umsetzung
2.2. neuer fertiger Prototype
3. fertiges Script
4. Ausleitung


0. Einleitung

Da jetzt doch schon ein paar mal nach der Zeitanzeige gefragt wurde, habe ich mich doch überwunden einen zweiten Teil des "MP3-Players mit XML-Fütterungszeit" zu schreiben!
Ich hab dann direkt noch die Lautstärkeregulierung mit erklärt.

Ich hoffe, dass sich der Aufwand gelohnt hat und ihr das gebrauchen könnt!!!
In diesem Teil werden oben genannte Themen behandelt.


1. Zeitanzeige

generell kommen wir an die Soundposition in Millisekunden mit SoundObjekt.position.
Soundobjekt.duration gibt uns die Soundlänge aus (soundobjekt.duration sollte man allerdings nicht im Zusammenhang mit gestreamten Sounds verwenden, da es uns nur die Länge des schon geladenen Teils ausgibt und man somit falsche Werte bekommen würde!)!

Zunächst einmal nur Soundobjekt.position, Die Länge kriegen Wir anders raus ...dazu später mehr !

1.1. Digitale Zeitanzeige

Als erstes benötigen wir ein dynamisches Textfeld, in dem wir die Zeit ausgeben werden!
Dem textfeld habe ich mal den Instanznamen "zeit_anz" gegeben!

Als nächstes müssen wir uns überlegen, wo wir es am geschicktesten unterbringen, die Zeitanzeige zu generieren!

Dazu fragen wir uns am besten, wann wir sie überhaupt benötigen!
Ich bin zu dem Schluss gekommen, dass wir sie erst benötigen, wenn der Sound abgespielt wird.. ansonsten ist sie zunächst einmal "00:00".
Das schreiben wir auch einfach in unser Textfeld rein!

Wenn wir uns an das Script aus Part I erinnern, dann wissen wir, dass dort bereits eine Abfrage genutzt wurde, um zu überprüfen, ob der Sound abgespielt wird (...bzw. ob die _soundbufftime geladen wurde).
Wenn das der Fall ist, können wir unsere Anzeige starten lassen!

Im script befinden wir uns also im MovieClip.prototype.song_starten und dort im onEnterFrame ereignis in dem oben Genanntes abgefragt wird.

Wie aber generieren wir die Zeitanzeige?

Das Soundobjekt befindet sich in dem Mc, auf den später der Prototyp angewand wird, also heißt es "this.sound_obj".
An die aktuelle Position koommen wir also mit "this.sound_obj.position".

Wir wollen uns die Zeit nicht genauer als auf die Sekunde ausgeben lassen, daher reicht ein SetInterval, indem wir die Zeitanzeige genereieren, mit einem Interval von 1000 Millisekunden (=1 sek) aus.
ActionScript:
  1. zeit_interval = setInterval(zeit,1000);

wie ihr seht habe ich direkt reingeschrieben, wie unsere funktion heißen wird: "zeit".

Also gehen wir's an.

zunächst das Allgemeine, um eine function zu deklarieren:
ActionScript:
  1. function zeit () {
  2.     //...
  3. }
Die function wird nun natürlich nicht im Prototypen geschrieben. Ich habe sie direkt über dem Prototypen deklariert!

Als Paramter geben wir ihr das Soundobjekt mit.
Mit einem trace(sound_obj.poition können wir uns schon einmal die Millisekunden der Soundposition ausgeben lassen:
ActionScript:
  1. function zeit(sound_obj) {
  2.     trace(sound_obj.position);
  3. }
  4.  
  5. //...
  6. zeit_interval = setInterval(zeit,1000,this.sound_obj);

Jetzt wollen wir uns aber die Soundposition nicht ausgeben lassen, sondern in das Textfeld schreiben:
ActionScript:
  1. zeit_anz.text=sound_obj.position;

Nur das was wir nun sehen ist ja in keinsterweise zufriedenstellend.. oder?
Wir wollen die Zeitanzeige natürlich nicht in Millisekunden, sondern als eine schön formatierte Minuten und Sekunden Anzeige!

Dazu sind ein paar Schritte nötig.
Als erstes würde ich sagen, speichern wir unsere Anzeige mal in der Variablen "time" und teilen die Position durch 1000 um die Sekunden zu erhalten:
ActionScript:
  1. time=sound_obj.position/1000;
  2. zeit_anz.text=time;

So, nun kommt der wesentliche Schritt bei der Anzeige!
Wir wollen unsere in Sekunden vorligende Zeit in Minuten und Sekunden (bis 59, dann wieder 0) aufsplitten!
Um die Minuten zu berechnen, können wir einfach schauen wie oft die 60 (60Sek.==1Min.^^) in unsere Sekunden passt!
Um keine Kommazahlen angezeigt zu bekommen, runden wir das Ergebnis ab mit Math.floor(wert);
also:
ActionScript:
  1. min = Math.floor(time/60);

Die eigentliche Sekunden haben wir ja schon... aber jetzt wollen wir nicht die schon abgespielten Sekunden insgesamt, sondern nur die Sekunden der aktuellen Minute (also die Anzeige soll immer von 0 bis 59 laufen und wieder vorne anfangen!)
Diese Sekunden zu berechnen ist uns möglich mit dem sogenannten Modulo: x % y
Diese Operation gibt den Rest der Division von x/y aus!

Wenn wir nun also unsere Sekunden durch 60 teilen, bleibt meist ein Rest übrig... die Sekunden.
Bsp.:
Wenn Sekunde 80 sind und wir nun 80%60 rechnen, erhalten wir 20 (die 60 passt 1 mal in die 80; der Rest ist 20 (80-60*1))
Wenn Sekunde 169 sind und wir nun 169%60 rechnen, erhalten wir 49 (die 60 passt 2 mal in die 169; der Rest ist 49 (169-60*2))

wenn wir dieses Wissen also auf unsere Zeitanzeige anwenden und auch diesen Wert abrunden, würde das so aussehen:
ActionScript:
  1. sek = Math.floor(time%60);

Eine sache fehlt bei den Sekunden allerdings und ist euch bestimt auch schon aufgefallen:

Wenn die Sekunden unter 10 liegen, dann sollte die Anzeige natürlich z.b. so aussehen: 05
also benötigen wir für die sekunden noch mal eine Abfrage und hängen ggf. die 0 vorne dran:
ActionScript:
  1. if(sek<10) {
  2.     sek="0"+sek
  3. }
oder kurz:
ActionScript:
  1. sek=(sek<10)? "0"+sek : sek;
das gleiche machen wir der Schönheit wegen auch noch bei den Minuten:
ActionScript:
  1. min=(min<10)? "0"+min : min;
Um die Zeit dann formatiert auszugeben schreiben wir einfach:
ActionScript:
  1. zeit_anz.text=min+":"+sek;
Die gesamte function sieht somit so aus:
ActionScript:
  1. function zeit(sound_obj) {
  2.     time = sound_obj.position/1000;//aktuelle position (millisekunden ) in Sekunden umwandeln
  3.     min = Math.floor(time/60);//Minuten berechnen
  4.     min=(min<10)? "0"+min : min;//ggf. bei den Minuten ne 0 vorne dran
  5.     sek = Math.floor(time%60);//Sekunden berechnen
  6.     sek=(sek<10)? "0"+sek : sek;//ggf. bei den Sekunden ne 0 vorne dran
  7.     zeit_anz.text=min+":"+sek;//Zeitausgabe ins Textfeld
  8. }
und der Aufruf aus dem Prototypen per setInterval nochmal:
ActionScript:
  1. MovieClip.prototype.song_starten = function (file, name) {
  2.     this.sound_obj.loadSound(file,true)//true steht hier für streaming=an
  3.     this.onEnterFrame = function () {//das onEnterFrame Ereignis
  4.         if(this.sound_obj.position>0) {//wenn der Sound startet
  5.             delete this.onEnterFrame; // das onEnterFrame Ereignis löschen
  6.             this._parent.anz.text=name; //name wurde als parameter it übergeben
  7.             zeit_interval = setInterval(zeit,1000,this.sound_obj);//Zeitanzeige starten <<<<<<<<<<--------------hier
  8.         } else {
  9.             this._parent.anz.text="loading..." //this._parent heißt soviel wie: dieser_mc_hier.die_übergeordnete_instanz dort liegt nämlich das textfeld.
  10.         }
  11.     }
  12.     //......
  13. }

Das war es eigentlich schon, bis auf, dass wir nun noch beim Stoppen der Wiedergabe auch das Interval wieder löschen können.
Wir können es übrigens auch bei den anderen buttons machen, da es neu angelegt wird, sobald der sound wieder anfängt zu spielen!
Wir Löschen das Interval mit: clearInterval(zeit_interval);
...und dann setzen wir noch die Textfeldanzeige zurück auf "00:00".
Unsere Button-functions sehen nun so aus:
ActionScript:
  1. btn_play.onRelease = function () {
  2.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  3.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  4.     this._parent.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//aktuell ausgewählten Song starten
  5. }
  6. btn_stop.onRelease = function() {
  7.     this._parent.sound_mc.sound_obj.stop(); //Wiedergabe stoppen
  8.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  9.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  10.     this._parent.anz.text="Wiedergabe gestoppt";
  11. }
  12. btn_next.onRelease = function () {
  13.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  14.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  15.     (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  16.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  17. }
  18. btn_prev.onRelease = function () {
  19.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  20.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  21.     (song_nr==0)? _global.song_nr=songfiles.length-1 : _global.song_nr--;//vorherigen Song auswählen(song_nr--) es seiden der erste wurde grade abgespielt.. dann wieder hinten anfangen
  22.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//vorherigen Song starten
  23. }

Geändert von pape (08-02-2005 um 03:39 Uhr)
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 03:18   #2 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
Einen Fall haben wir noch nicht berücksichtigt. Und zwar den normalsten^^.
Wenn ein Sound einfach bis zum Ende abgespielt wird, müssen wir die Zeitanzeige natürlich auch resetten und das Interval löschen, da es beim starten des nächsten Songs wieder erstellt wird:
ActionScript:
  1. // im prototype
  2. // ...
  3. this.sound_obj.onSoundComplete = function () {//wenn der sound fertig abgespielt wurde
  4.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  5.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  6.     (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  7.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  8. }

Das wird nun leider noch überhaupt nicht funktinoieren wie ihr wahrscheinlich schon gemerkt habt, wenn ihr das mal getestet habt:
Wenn man z.b. btn_next klickt wird die Zeitanzeige zwar kurz zurückgesetzt, aber dann geht die Anzeige dort weiter, wo sie vorher stehen geblieben ist!
Um das zu vermeiden müssen wir das SoundObjekt löschen und wieder neu erstellen!
Das machen wir im Prototypen direkt am anfang.
Wir gucken ob ein SoundObjekt existiert und wenn ja, dann löschen wir es.
Danach erstellen wir es dann wieder neu:
ActionScript:
  1. MovieClip.prototype.song_starten = function (file, name) {
  2.     if (this.sound_obj) {//wenn ein SoundObjekt existiert
  3.         delete this.sound_obj;//löschen
  4.     }
  5.     this.sound_obj = new Sound(this);//neues SoundObjek erstellen
  6.     //...
  7.  
Aufgrund der Tatsache, dass wir das SoundObjekt im Prototypen erstellen, können wir aus der songlist.onLoad function diese zeile löschen:
ActionScript:
  1. _root.sound_mc.sound_obj = new Sound(_root.sound_mc);

Wenn ihr das jetzt einmal testet werdet ihr feststellen, dass nun zwar die Anzeige funktinoiert, aber sobald man z.b. btn_next oder btn_play drückt ein weiterer Song anfängt zu spielen ohne, dass der alte aufhört...
Das liegt daran, dass wir das SoundObjekt löschen, aber den Sound vorher nicht stoppen!
Deswegen werden wir das auch noch kurz machen:

ActionScript:
  1. MovieClip.prototype.song_starten = function (file, name) {
  2.     if (this.sound_obj) {//wenn ein SoundObjekt existiert
  3.         this.sound_obj.stop();//stoppen
  4.         delete this.sound_obj;//und löschen
  5.     }
  6.     this.sound_obj = new Sound(this);//neues SoundObjek erstellen
  7.     //...
  8.  

Nun sollte die Anzeige korrekt funktionieren!


1.2. Visuelle "Balken-Zeitanzeige" + Ladestatus der Mp3

Der Ladestatus ist ein normaler Preloader.

Für die Zeitanzeige benutzen wir einen kleinen senkrechten Strich, der auf dem Preloader wandelt...

Also gehen wir's an...

1.2.1. wichtiges für's Layout

Wir malen einen Balken auf die Bühne (ohne Rand).
Meiner ist 250 lang und 12 hoch.
Dann drücken wir F8 und wandeln das Shape in einen Movieclip um!
Ich habe ihm den Instanznamen "balken" gegeben um später im Script auf diesen zugreifen zu können!
Wichtig ist, dass das balken-Shape im Mc "balken" den x wert 0 hat.. also auf x=0 ausgerichtet wird!

Nun malen wir den Rahmen für den balken auf einer höheren Ebene, sodass man später sehen kann, wieviel überhaupt geladen werden muss, wenn man keine weitere Text-Preloaderanzeige hat
Das ganze (mc:"balken" und das Rahmenshape) packen wir wieder in einen mc (F8).
Diesem mc habe ich den Instanznamen "anz_balken" gegeben.

Wechselt in diesen (doppelklick) und malt auf einer neuen Ebene, am besten zwischen Balken und Rahmen, einen kleinen Senkrechten Strich über den Preloader, wandelt diesen dann wieder in einen mc um (F8) und gebt ihm den Instanznamen "pointer".

Es ist wichtig, dass wir nun unsere ganzen Elemente in dem anz_balken auf x=0 setzen!
Und als letztes ehe wir uns dem Script zuwenden: den Mc "balken" auf breite:1 skalieren.
(Man sollte nun einen leeren Rahmen sehen, der bei x=0 liegt.)

Wechselt wieder in die Hauptzeitleiste und positioniert den Rahmen (und somit auch die darin enthaltenen Elemente) neu.

1.2.2. Script für Balken und Pointer

Zunächst wieder die Frage wo wir unser Script sinnvoll unterbringen können.
Die Anzeige für den Preloader muss gestartet werden sobald ein Sound gestartet wird.
Also können wir dies direkt in unserem "song_starten" Prototypen machen.

Der Pointer muss, genau wie die Zeitanzeige im Textfeld, erst starten, wenn die _soundbufftime geladen wurde.
Also kommt das Script auch in den prototypen, allerdings dorthin, wo auch das zeit_interval gestartet wird!

1.2.2.1. Preloader

Den Preloader können wir ganz einfach über die scale-Eigenschaft vergrößern.
Da die Scaleeigenschaft prozentual ist, berechnen wir den prozentualen Teil, der vom Sound schon geladen wurde und skalieren den balken dem entsprechend.
Da wir das ständig und nicht nur ein einziges mal tuen müssen, machen wir das in einem OnEnterFrame.
Wir benutzen dazu den anz_balken mc!
Um aus dem Prototypen auf diesen zuzugreifen müssen wir zunächst eine Instanz höher (this._parent) und können dort dann den Mc ansprechen und ihm ein OnEnterFrame zuweisen:
ActionScript:
  1. this._parent.anz_balken.onEnterFrame = function() {...}
um in dem anz_balken onEnterFrame auf unser SoundObjekt zugreifen zu können, müssen wir von diesem aus wieder zurück in den sound_mc mit "this._parent.sound_mc"... zugegebener maßen etwas umständlich^^.
So können wir dann aber die schon geladenen und die Totalen Bytes unseres Sounds auslesen:
ActionScript:
  1. this._parent.anz_balken.onEnterFrame = function() {
  2.     var l = this._parent.sound_mc.sound_obj.getBytesLoaded();
  3.     var t = this._parent.sound_mc.sound_obj.getBytesTotal();
  4. }
Um den geldenen Teil in Prozenten zu bekommen, teilen wir die schon geladenen Bytes durch die Totalen und multiplizieren das mit 100 (Klasse 7 - Prozentrechnung!)
ActionScript:
  1. var p = (l/t)*100;
die variable können wir uns natürlich auch sparen und dem Balken den Wert direkt als ._xscale zuweisen.

Sobald die geladenen Bytes größer oder gelcih den Totalen sind, können wir das onEnterFrame Ereignis wieder löschen, sodass das vollständige onEnterFrame so aussieht:
ActionScript:
  1. // im prototype
  2. //...
  3. this.onEnterFrame = function {
  4. //...
  5. }
  6. this._parent.anz_balken.onEnterFrame = function() {//dem "anz_balken" mc ein onEnterFrame Ereignis zuweisen
  7.     var l = this._parent.sound_mc.sound_obj.getBytesLoaded();//Die schon geladenen Byets des Sounds auslesen
  8.     var t = this._parent.sound_mc.sound_obj.getBytesTotal();//Die gesamten Byets des Sounds auslesen
  9.     this.balken._xscale = (l/t)*100;//dem "balken" den schon geladenen Teil in Prozent als _xscale zuweisen
  10.     if (l>=t && l>20) {//Wenn der Song fertig geladen wurde (und sicher gestellt wurde, dass angefangen wurde zu laden)
  11.         delete this.onEnterFrame;// das onEnterFrame löschen
  12.     }
  13. }
  14. //...
  15.  

Das wars schon!

Als nächstes müssen wir noch den Pointer bewegen.

1.2.2.2. Pointer

Der Pointer soll die aktuelle abspiel Position des Songs anzeigen, indem er sich auf dem "preloader" bewegt!

Wir werden auf jedenfall die genaue Länge unserer Mp3s brauchen.. das schon mal vorweg!
Leider bekommen wir diese nicht so einfach, weil sound_obj.duration ja nur die Länge des schon geladenen Sounds hergibt.
Daher können wir die duration eigenschaft nicht nutzen.

Geändert von pape (09-02-2005 um 02:57 Uhr)
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 03:19   #3 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
1.2.2.2.1. Vorarbeit (Bitrate der Mp3s)

Um die Soundlänge zu erhalten, müssen wir uns kurz von action scipt verabschieden und in PHP weitermachen!

Ich habe grad mal nen kleines Script geschrieben, dass die Dateien eines Ordners durchsucht und ggf. die Bitrate der Mp3s in dem Ordner ausgibt!
Zudem gibt die datei des direkt in xml-form aus, sodass man nur noch den namen anpassen muss.
Falls ihr kein PHP - webspace habt ist das nicht schlimm! Dann müsst ihr eure Bitrates eben selber nachgucken!
Das soll nur als kleines Hilfsmittel nutzen!
Leute mit PHP-Webspace können sich das auch umschreiben und die Datei direkt von Flash aus aufrufen um dann die bitrate weiterzuverarbeiten!

Ich gehe nicht weiter auf das PHP Script ein weil das hier kein PHP tut werden soll.
habe es nur für die die's interessiert mal auskommentiert.
Bei fragen stehe ich dennoch zur verfügung!
Und nicht wundern wenn das dingen mal fehler ausspuckt... ich hab das wirklich nur kurz geschrieben ohne großartige !"Falsche Benutzereingaben" abzufangen usw..

Legt es einfach auf euren server und gebt den entsprechenden Pfad zu eruem Ordner mit den Songs (MP3s) an.
Wenn ihr die Datei in den selben Ordner legt, wo auch die main.swf des Mp3 players später aufgerufen wird, könnt ihr die XML strings die ihr rausbekommt direkt verwenden.
Wenn nicht, dann müsst ihr die pfade anpassen!
Ihr könnt die Datei aber auch einfach benutzen um nur kurz die Bitrates auszulesen und sie dann per Hand in eure vorhandene XML datei reinschreiben!

Hier mal das Script (Datei ist auch im Anhang)
PHP-Code:
<?
function rate($mp3) { //neue Funktion rate mit Parameter $mp3
    //Array mit den Verschiedenen Bitrates
    
$bitrates = array(=> "VBR"=> 32=> 40=> 48=> 56=> 64=> 80=> 96=> 112=> 12810 => 16011 => 19212 => 22413 => 25614 => 320);
    
$f fopen($mp3"r");//datei die als Parameter übergeben wurde öffnen (r=nur lesen)
    
$header fread($f4);//header auslesen (ersten 4 Bytes auslesen)
    
fclose($f);//datei schließen
    
$header unpack("n2word"$header); //(n=)Short-Typ ohne Vorzeichen in Worte aus dem String $header in array "verwandeln"
    
if ($header['word1'] != 0xFFFB) {//wenns nicht ner Mp3 entspricht
        
$bitrate false//false als bitrate ausgeben
    
} else {//sonst
        
$bitrate_index $header['word2'] >> 12;//bitrate index auslesen
        
$bitrate $bitrates[$bitrate_index];//bitrate "nachschlagen"
    
}
    return 
$bitrate;//bitrate zurückgeben (oder false)
}
?>
<html><!--html document-->
    <body><!--body-->
<?
if(isset($_POST['pfad'])) {//wenn ein Pfad übergeben wurde
    
$andere_files = array(); //neues leeres Array für andere Daten im verzeichnis als Mp3s
    
if(''==trim($_POST['pfad'])) {//wenn der pfad leer ist
        
$_POST['pfad']=".";// gleichen ordner wo die datei liegt als pfad nehmen
    
}
    if(
$p=opendir(trim($_POST['pfad']))){ //verzeichnis öffnnen und verzeichnis handle speichern
        
while($datei=readdir($p)){//datei lesen
            
if ($datei!="." && $datei!=".."){//wenn datei nicht der eigene ordner oder der Verweis zum nächst höheren ist
                
if(!is_dir($datei)){//wenn datei kein Verzeichnis ist
                    
if($br=rate($_POST['pfad']."/".$datei)){//bitrate auslesen; wenn es ne MP3 is
                        
echo "&lt;song name=&quot;&quot; file=&quot;".$_POST['pfad']."/".$datei."&quot; bitrate=&quot;".$br."&quot;/&gt;<br>\n";//als XML string ausgeben
                    
} else {//sonst
                        
array_push($andere_files,$_POST['pfad']."/".$datei);//als andere Datei im Array speichern
                    
}
                }
            }
        }
        
closedir($p);//verzeichnis schließen
    
}
}
if(
count($andere_files)>0){//wenn andere Files vorhanden sind
    
echo "<br><u><font color=\"#990000\">Weitere gefundene Dateien:</u><br>\n";//verzierung
    
foreach($andere_files as $datei) {//alle dateien im array
        
echo $datei."<br>\n";// ausgeben
    
}
    echo 
"</font><br>\n";//verzierung ende
}
?>
        <form action="mp3bitrates2xml.php" method="post"><!-- form -->
            Pfad:<input name="pfad" type="text"><br><!-- Textfeld für den Pfad-->
            <input type="submit" value="Bitrates suchen"><!-- Submitbutton -->
        </form><!-- / form-->
    </body><!-- / body-->
</html><!-- / html document-->
1.2.2.2.2. XML update

Jedenfalls erweitern wir unsere XML datei um ein attribute "bitrate", sodass sie z.b. so aussehen könnte:
Code:
<?xml version='1.0' encoding='utf-8'?>
<songs>
    <song name="Lied1" file="songs/lied1.mp3" bitrate="128"/>
    <song name="Lied2" file="songs/lied2.mp3" bitrate="128"/>
</songs>
So nachdem wir also die Bitrate haben, besinnen wir uns wieder auf Action Script und ändern erstmal unsere XML.onLoad function so ab, dass wir die Bitrates der Mp3s in einem Array bitrates haben:

ActionScript:
  1. songliste.onLoad = function (success) {//onLoad function (wird ausgeführt, wenn die daten geladen werden)
  2.     if(success) {//wenn das laden erfolgreich war
  3.         //arrays erstellen
  4.         _global.songnamen = [];
  5.         _global.songfiles = [];
  6.         _global.bitrates = [];//neues Array "bitrates"
  7.         for (var i=0; i<songliste.firstChild.childNodes.length; i++) {//für alle Elemente in der XMLfile
  8.             //Die attribute auslesen und in die Arrays packen
  9.             _global.songnamen[i] = songliste.firstChild.childNodes[i].attributes.name;
  10.             _global.songfiles[i] = songliste.firstChild.childNodes[i].attributes.file;
  11.             _global.bitrates[i] = songliste.firstChild.childNodes[i].attributes.bitrate;
  12.         }
  13.     //...
  14.  

1.2.2.2.3. Das Pointer-Script

Nach diesem Stück vorarbeit wirds jetzt aber wirklich Zeit, dass wir unseren Pointer bewegen!

Als erstest weisen wir dem Pointer mc im anz_balken mc ein onEnterFrame zu.
Um den mc an zu sprechen , müssen wir im prototypen zunächst eine Instanz höher und dort dann in den mc anz_balken, wo dann unser pointer mc liegt:
ActionScript:
  1. // im prototype
  2. //...
  3. this.onEnterFrame = function () {//das onEnterFrame Ereignis
  4.     if(this.sound_obj.position>0) {//wenn der Sound startet
  5.         //...
  6.         this._parent.anz_balken.pointer.onEnterFrame = function() {...}

Die Prozentuale Abspielposition müssen wir nun rauskriegen, um unseren Pointer dann wiederrum prozentual gesehen zum balken zu positionieren....
Hört sich kompliziert an.. is aber immernoch Prrozentrechnung aus Klasse 7 ^^

Die absolute Abspielposition kriegen wir wieder mit sound_obj.position.
Um die Sekunden anstatt die Millisekunden zu bekommen, teilen wir durch 1000:
ActionScript:
  1. var pos = this._parent._parent.sound_mc.sound_obj.position/1000;

Die gesamte Länge des Sounds bekommen wir mit Hilfe der Bitrate raus.
Bitrate bedeutet, dass pro Sekunde, z.b. bei einer Bitrate von 128, 128 Bits pro sekunde abgespielt werden.

Als erstes teilen wir daher die Bitrate durch 8 um die KiloBytes/s statt den KiloBits/s zu bekommen (8Bits == 1Byte).
Die Bitrate des aktuellen Songs steht im globalen Array, welches wir ja in der songlist.onLoad function erstellt haben: bitrates[song_nr] (wir erinnern uns an Part I des Tutorials: song_nr istr eine globale variable, in der die Aktuelle Song-id gespeichert wird):
ActionScript:
  1. bitrates[song_nr]/8
Nun lesen wir die totalen Bytes des Songs aus und teilen Sie durch 1024 um die KiloBytes des Songs zu bekommen (2^10Bytes == 1024 Bytes == 1KiloByte[KB]):
ActionScript:
  1. s_obj.getBytesTotal()/1024
Wenn wir jetzt mal nen bischen nachdenken, sehen wir, dass wir nun ausrechnen können, wieviele Sekunden unser Song lang ist:
Die Gesamte Größe geteilt durch die Abspielrate = Länge des Sounds.

[off topic]
OK ich weiß, dass ist nicht soooo leicht zu verstehen... (aber ich sag euch: es ist auch nicht leicht das zu erklären^^)
Ich hoffe ich ihr habt das verstanden, ansonsten vielleicht diesen Abschnitt nocheinmal lesen.
Im Grunde ist es ziemlich Simpel!
Falls ihr es dann immernoch nicht versteht, dann nehmt es einfach so hin!
Es stimmt jedenfalls!
[/off topic]
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 03:20   #4 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
weiter im text:

In Action Scipt sähe das nun so aus:
ActionScript:
  1. var ges = (this._parent._parent.sound_mc.sound_obj.getBytesTotal()/1024)/(bitrates[song_nr]/8);
weil ich jetzt nich immer
"this._parent._parent.sound_mc.sound_obj" schreiben möchte, lege ich mal eine referenz dahin... d.h. ich speichere so zu sagen den Pfad zum SoundObjekt in einer Variablen:
ActionScript:
  1. var s_obj = this._parent._parent.sound_mc.sound_obj
Das Script für das onEnterFrame sieht mit dieser Referenz so aus:
ActionScript:
  1. this._parent.anz_balken.pointer.onEnterFrame = function() {//pointer ein OnEnterFrame ereignis zuweisen
  2.     var s_obj = this._parent._parent.sound_mc.sound_obj// weil des so viel zu schreiben wäre, habe ich das mal referenziert
  3.     var pos = s_obj.position/1000;// Abspieloposition in Sekunden
  4.     var ges = (s_obj.getBytesTotal()/1024)/(bitrates[song_nr]/8);//Soundlänge in Sekunden berechnen
  5. }
Keine Ahnung warum, aber wenn wir das genau so lassen, dann wird der Pointer am Ende immer ein Stückchen zuweit laufen.. also über den Preloader/die gesamte Länge hinaus...
Letztes Jahr noch, habe ich einfach getrickst und einfach 3 abgezogen...
Ich habe nun aber durch Zufall herausgefunden, dass wenn man statt den 1024 Bytes, bei der Umrechnung der TotalenBytes ins KiloBytes, 1000 nimmt, es genau hinkommt!
Nehmen wir das einfach mal so hin und verwenden es mit TotalBytes/1000.

Das reicht jetzt aber auch noch nicht, um den Pointer zu bewegen.

Wie gesagt müssen wir jetzt die prozentuale Abspielposition rauskriegen. Das machen wir wie bei nem Preloader oder halt wie in Klasse 7 mit den Zinsen:
ActionScript:
  1. var p = (pos/ges)*100;
Jetzt können wir unseren Pointer bewegen, indem wir den x-Wert prozentual zur Breite des Preloaders/gesamten Länge verändern.
Das machen wir indem wir unsere Prozentrechnung umdrehen und die Länge des Balkens als 100% ansehen (this._parent.balken._width/100).
das ganze dann multipliziert mit der prozentualen Abspielposition die wir zuvor ausgerechnet haben ergibt nun endlich unsere _x Position für den Pointer:
ActionScript:
  1. this._x = p*(this._parent.balken._width/100);//this bezieht sich hier auf den Pointer
  2.  
Hier sieht man, warum es so wichtig ist, dass die ganzen Elemente aus dem Mc "anz_balken" auf _x=0 liegen, da sonst die Anzeigen und der Preloader völlig verrückt spielen würden!

1.2.2.3. fertiger Prototype

Nach diesem Brocken sieht unser kommpletter Prototype so aus:
ActionScript:
  1. MovieClip.prototype.song_starten = function (file, name) {
  2.     if (this.sound_obj) {//wenn ein SoundObjekt existiert
  3.         this.sound_obj.stop();//stoppen
  4.         delete this.sound_obj;//und löschen
  5.     }
  6.     this.sound_obj = new Sound(this);//neues SoundObjek erstellen
  7.     this.sound_obj.loadSound(file,true)//true steht hier für streaming=an
  8.     this.onEnterFrame = function () {//das onEnterFrame Ereignis
  9.         if(this.sound_obj.position>0) {//wenn der Sound startet
  10.             delete this.onEnterFrame; // das onEnterFrame Ereignis löschen
  11.             this._parent.anz.text=name; //name wurde als parameter it übergeben
  12.             zeit_interval = setInterval(zeit,1000,this.sound_obj);//Zeitanzeige starten
  13.             this._parent.anz_balken.pointer.onEnterFrame = function() {//pointer ein OnEnterFrame ereignis zuweisen
  14.                 var s_obj = this._parent._parent.sound_mc.sound_obj// weil's so viel zu schreiben wäre, habe ich's referenziert
  15.                 var pos = s_obj.position/1000;// Abspieloposition in Sekunden
  16.                 var ges = (s_obj.getBytesTotal()/1000)/(bitrates[song_nr]/8);//Soundlänge berechnen
  17.                 var p = (pos/ges)*100;//prozentuale Abspielposition
  18.                 this._x = p*(this._parent.balken._width/100);//_x position prozentual zur Breite des Preloaders bewegen
  19.             }
  20.         } else {
  21.             this._parent.anz.text="loading..." //this._parent heißt soviel wie: dieser_mc_hier.die_übergeordnete_instanz dort liegt nämlich das textfeld "anz".
  22.         }
  23.     }
  24.     this._parent.anz_balken.onEnterFrame = function() {//dem "anz_balken" mc ein onEnterFrame Ereignis zuweisen
  25.         var l = this._parent.sound_mc.sound_obj.getBytesLoaded();//Die schon geladenen Byets des Sounds auslesen
  26.         var t = this._parent.sound_mc.sound_obj.getBytesTotal();//Die gesamten Byets des Sounds auslesen
  27.         this.balken._xscale = (l/t)*100;//dem "balken" den schon geladenen Teil in Prozent als _xscale zuweisen
  28.         if (l>=t && l>20) {//Wenn der Song fertig geladen wurde (und sicher gestellt wurde, dass angefangen wurde zu laden)
  29.             delete this.onEnterFrame;// das onEnterFrame löschen
  30.         }
  31.     }
  32.     this.sound_obj.onSoundComplete = function () {//wenn der sound fertig abgespielt wurde
  33.         clearInterval(zeit_interval);//Zeitanzeige stoppen
  34.         this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  35.         (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  36.         _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  37.     }
  38. }

Nur noch eine Sache und wir sind fertig mit dem Pointer:
Wenn der Stop button gedrückt wird, dann können wir das onEnterFrame ereignis des pointers löschen, da die Position bzw. die Abspielposition sich ja nicht merh verändert:
ActionScript:
  1. btn_stop.onRelease = function() {
  2.     this._parent.sound_mc.sound_obj.stop(); //Wiedergabe stoppen
  3.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  4.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  5. /*-->*/ delete this._parent.anz_balken.pointer.onEnterFrame;//pointer onEnterFrame löschen
  6.     this._parent.anz.text="Wiedergabe gestoppt";
  7. }

Geändert von pape (09-02-2005 um 02:59 Uhr)
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 03:24   #5 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
2. Lautstärkeregulierung

Für eine Lautstärkeregulierung sind eigentlich nur wenige Schritte notwendig, welche auch nicht schwer verständlich sein sollten da sie recht simpel sind:

2.1. Vorüberlegungen und Umsetzung

Ähnlich wie bei der Zeitanzeige und dem ladestatus ist es wichtig, dass wir hier unsere Elemente intern auf _x=0 ausrichten!
Da das ganze natürlich auch auf der y-Achse funktioniert, mache ich das nun mal dieser y, da wir unseren Preloader und die visuelle Abspielposition schon auf der x-Achse realisiert haben (natürlich auch auf anderen.. oder im Kreis... aber das würde jetzt wirklich den Rahmen sprengen..^^.. wer's machen will sollte mal nach sin und cos suchen und später seine Ergebnisse posten!)
Es ist also egal auf welchem x Wert die Objekte liegen, aber wichtig, dass die Objekte den y Wert 0 haben.

Als erstes malen wir mal ein schönes Bildchen, dass später der Hintergrund vom Lautstärkeregler sein soll
Ich habe einfach ein Shape gemalt, dass von unten nach oben immer breiter wird.
Dazu habe ich einfach Ein Rechteck gemalt und dann mit dem ganz normalen Pfeilwerkzeug (v) auf die untere rechte Ecke geklickt und sie zur unteren linken Ecke "gedragt" (gezogen).
Die Maße sind egal und ihr könnt natürlich auch viel aufwendigere Bilder verwenden.. aber das hier ist ja kein Design Tutorial sondern ein ActionScript Tutorial.. deswegen gehe ich auch nicht auf irgendwelche derartigen Sachen weiter ein!

Also nachdem Ihr euer Shape habt, selektiert ihr es und wandelt es in einen MovieClip um (F8).
ich habe ihm den Instanznamen "laut" gegeben.

Als nächstes malt ihr euren Regler, den Ihr später ziehen könnt, um damit die Soundlautstärke zu regulieren.
Makiert diesen wieder und wandelt ihn in einen Mc (F8).
Ich hab diesem den Instanznamen "pegel" gegeben.

Makiert die beiden Elemente und drückt wieder F8 um diese wieder in einen Mc zu verwandeln.
Diesem habe ich den Instanznamen "vol" gegeben.

Doppelklickt auf den Mc um ihn in zu wechseln.
Jetzt müüsst ohr die Objekte wieder auf _y=0 ausrichten, damit dasd Script später überhaupt funktionieren kann!
Ich habe meinen pegel mc ganz oben vom laut mc positioniert (also beide auf y=0) da die Lautstärke am Anfang 100 sein wird.

Jetzt können wir uns um das Script kümmern.

Generell kann man die aktuelle Lautstärke eines SoundObjekeass mit sound_obj.getVolume() auslesen und mit sound_obj.setVolume(Wert) verändern.

Wo fangen wir an... genau im Prototypen...warum?... genau... weil dort ein Sound gestartet wird und sobald ein Sound gestartet wird, kann man auch dessen Lautstärke ändern!

Drag & Drop sollte bekannt sein, falls nicht: Drag=Ziehen Drop= fallenlassen.
Das meint im Endeffekt einfach, dass man einen Gegenstand durch die gegenzieht indem man mit der Maustaste auf ihn klickt, die maustaste gedrückt hält während man die maus umherbewegt und man das Objekt wieder loslässt bzw. fallen lässt wenn man die Maustaste loslässt!

In Flash gibt es nun 2 wichtige Ereignisse:
ActionScript:
  1. MovieClip.onPress // Wenn "MovieClip" gedrückt wird
  2. MovieClip.onRelease // Wenn "MovieClip" losgelassen wird
  3.  
Diese beiden Ereignisse stehen auch bei Buttons zur verfügung, wir benutzen allerdings Mcs!
Diesen Ereiggnisen kann man functions zuweisen (genau wie dem onEnterFrame) die Ausgeführt werden, sobald das entsprechende Ereignis eintrifft!

Sas machen wir auch direkt. Und zwar dort wo wir auch das onEnterFrame Ereigniss zuweisen, sodass wir 3 Funktionen für den Pegel mc haben:
ActionScript:
  1. this._parent.vol.pegel.onPress = function () {...}
  2. this._parent.vol.pegel.onRelease = function () {...}
in Flash gibt es nun zwei weitere Funktionen:
startDrag(); und stopDrag();
Die Funktionsnamen sagen ja bereits was passiert.
startDrag(ziel,[einrasten ,links ,oben ,rechts,unten])
Was die Parameter alles bewirken, könnt Ihr in der Flash internen Referenz nachlesen.

Wenn ihr das getan habt dann könnt ihr beruhigt weiter lesen

Unser "ziel" ist der pegel Mc, wir wollen, dass er einrastet (da er sonst komisch springen wird.. und das können wir hier net so gut gebrauchen) und die begrenzungen nehmen wir von unserem Mc "laut".
Die Begrenzungen vertikal (oben/unten) setzen wir abhängig von dem _y wert der Höhe des "laut" Mcs und die horizontale (links/rechts) Bewegung lassen wir erst gar nicht zu, indem wir hier zweimal den selben Parameter übergeben (nämlich den _x Wert des "pegel"s)
Da wir wissen, dass der _y Wert vom laut mc 0 ist, können wir für auch einfach eine 0 einsetzen.
Wir starten den Drag also im onPress Ereignis so:
ActionScript:
  1. this._parent.vol.pegel.onPress = function () {
  2.     startDrag(this,true,this._x,0,this._x,this._parent.laut._height);
  3. }
Der Drag sol aufhören, sobald wir die Maustaste loslassen. Also im onRelease Ereignis des Mcs:
ActionScript:
  1. this._parent.vol.pegel.onRelease = function () {
  2.     stopDrag();
  3. }
Um jetzt die Lautstärke zu verändern, setzen wir ein onEnterFrame, da nun ja etwas verändert wird und wir solange bis der Drag gestoppt wird (Mc.onRelease) den Wert entsprechend ständig ändern müssen, sobald der "pegel" mc geklickt wird, indem wir dann die Lautstärke setzen.
Das Soundobjekt liegt zwei Instanzen höher (this._parent._parent) und dort dann im mc sound_mc:
ActionScript:
  1. this._parent.vol.pegel.onPress = function () {
  2.     startDrag(this,true,this._x,0,this._x,this._parent.laut._height);
  3.     this.onEnterFrame = function () {
  4.         this._parent._parent.sound_mc.sound_obj.setVolume(...);
  5.     }
  6. }
Wie ihr seht, habe ich noch keinen Wert für das setVolume eingesetzt.
diesen müssen wir nun wieder ausrechnen.
Vorüberlegung:
Wenn der pegel mc auf y=0 liegt ist die Lautstärke 100.
Wenn man den "pegel" jetzt runter zieht, soll der Sound leiser werden, bis er schließlich 0 ist.
Der y-Wert vom "pegel" mc wird aber immer größer.
Wenn der pegel mc auf y=xxx liegt ist die Lautstärke 0.
y=xxx... geht natürlich nicht!
Die Lautstärke ist natürlich 0, wenn der "pegel" mc auf der maximalen _y Position ist, die durch das startDrag(...) bei dem unterem Punkt vom "laut" mc liegt (laut._height)

Soooo.
Wie verarbeiten wir das jetzt?
Zunächst mal müssen wir wieder mit Prozenten rechnen, da die maximale Lautstärke 100 ist (man kann sie auch höher setzen, aber das hört sich dann nicht mehr so doll an...)
Wir drücken also erst mal die y Position des "pegel" mcs bezüglich des "laut" mcs prozentual aus.
Dazu teilen wir die tatsächliche y Position durch die maximale und mutliplizieren dann noch mit 100:
ActionScript:
  1. var p = (this._y/this._parent.laut._height)*100;
Momentan ist würde die Regulierung genau falsch herum laufen, wenn wir jetzt einfach "p" als Wert für das setVolume nehmen.
Deswegen ziehen wir den Wert einfach von 100 ab um die Funktion zu invertieren und erhalten somit unseren Wert, den wir benutzen können:
ActionScript:
  1. var p = 100-(this._y/this._parent.laut._height)*100;
  2. this._parent._parent.sound_mc.sound_obj.setVolume(p);
Das einzige was wir jetzt noch machen müssen, ist das onEnterFrame Ereignis wieder zulöschen, wenn der Drag beendet wird, da es jetzt nicht mehr gebraucht wird:
ActionScript:
  1. this._parent.vol.pegel.onRelease = function () {
  2.     stopDrag();
  3.     delete this.onEnterFrame;
  4. }
Ihr könntet euch jetzt z.b. in einem textfeld noch die Lautstärke ausgeben lassen, indem ihr der anzeige des Textes immer den Wert von p im onEnterFrame zuweist.
Das Textfeld könntet ihr einfach mit draggen um es immer neben dem "pegel"mc laufen zu lassen usw... der Grundbaustein ist geschafft und wenn ihr es verstanden habt sollte das Alles keine Probleme mehr bereiten!
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 03:24   #6 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
2.2. neuer fertiger Prototype

Der neue fertige Prototype sieht jetzt so aus:
ActionScript:
  1. MovieClip.prototype.song_starten = function (file, name) {
  2.     if (this.sound_obj) {//wenn ein SoundObjekt existiert
  3.         this.sound_obj.stop();//stoppen
  4.         delete this.sound_obj;//und löschen
  5.     }
  6.     this.sound_obj = new Sound(this);//neues SoundObjek erstellen
  7.     this.sound_obj.loadSound(file,true)//true steht hier für streaming=an
  8.     this.onEnterFrame = function () {//das onEnterFrame Ereignis
  9.         if(this.sound_obj.position>0) {//wenn der Sound startet
  10.             delete this.onEnterFrame; // das onEnterFrame Ereignis löschen
  11.             this._parent.anz.text=name; //name wurde als parameter it übergeben
  12.             zeit_interval = setInterval(zeit,1000,this.sound_obj);//Zeitanzeige starten
  13.             this._parent.anz_balken.pointer.onEnterFrame = function() {//pointer ein OnEnterFrame ereignis zuweisen
  14.                 var s_obj = this._parent._parent.sound_mc.sound_obj// weil's so viel zu schreiben wäre, habe ich's referenziert
  15.                 var pos = s_obj.position/1000;// Abspieloposition in Sekunden
  16.                 var ges = (s_obj.getBytesTotal()/1000)/(bitrates[song_nr]/8);//Soundlänge berechnen
  17.                 var p = (pos/ges)*100;//prozentuale Abspielposition
  18.                 this._x = p*(this._parent.balken._width/100);//_x position prozentual zur Breite des Preloaders bewegen
  19.             }
  20.             this._parent.vol.pegel.onPress = function () {//dem pegel mc ein onPress Ereignis zuweisen
  21.                 startDrag(this,true,this._x,0,this._x,this._parent.laut._height);//Drag starten mit der y Begrenzung des "laut" mcs
  22.                 this.onEnterFrame = function () {//"pegel" ein onEnterFrame Ereignis zuweisen
  23.                     var p = 100-(this._y/this._parent.laut._height)*100;//Prozentwert für die Regulierung berechnen
  24.                     this._parent._parent.sound_mc.sound_obj.setVolume(p);//neuen Wert für die Lautstärke setzen
  25.                 }
  26.             }
  27.             this._parent.vol.pegel.onRelease = function () {//dem "pegel" mc ein onRelease Ereignis zuweisen
  28.                 stopDrag();//Drag stoppen
  29.                 delete this.onEnterFrame;//onEnterFrame vom "pegel" mc löschen
  30.             }
  31.         } else {
  32.             this._parent.anz.text="loading..." //this._parent heißt soviel wie: dieser_mc_hier.die_übergeordnete_instanz dort liegt nämlich das textfeld "anz".
  33.         }
  34.     }
  35.     this._parent.anz_balken.onEnterFrame = function() {//dem "anz_balken" mc ein onEnterFrame Ereignis zuweisen
  36.         var l = this._parent.sound_mc.sound_obj.getBytesLoaded();//Die schon geladenen Byets des Sounds auslesen
  37.         var t = this._parent.sound_mc.sound_obj.getBytesTotal();//Die gesamten Byets des Sounds auslesen
  38.         this.balken._xscale = (l/t)*100;//dem "balken" den schon geladenen Teil in Prozent als _xscale zuweisen
  39.         if (l>=t && l>20) {//Wenn der Song fertig geladen wurde (und sicher gestellt wurde, dass angefangen wurde zu laden)
  40.             delete this.onEnterFrame;// das onEnterFrame löschen
  41.         }
  42.     }
  43.     this.sound_obj.onSoundComplete = function () {//wenn der sound fertig abgespielt wurde
  44.         clearInterval(zeit_interval);//Zeitanzeige stoppen
  45.         this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  46.         (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  47.         _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  48.     }
  49. }

3. fertiges Script

Jetzt sind wir schon am Ende von Part II des Tutorials.
Das gesamte Script zur Steuerung sieht jetzt so aus :
ActionScript:
  1. stop();//film anhalten
  2. songliste = new XML();//neues XML Objekt
  3. songliste.ignoreWhite=true;//Leerzeichen ignorieren
  4. songliste.onLoad = function (success) {//onLoad function (wird ausgeführt, wenn die daten geladen werden)
  5.     if(success) {//wenn das laden erfolgreich war
  6.         //arrays erstellen
  7.         _global.songnamen = [];
  8.         _global.songfiles = [];
  9.         _global.bitrates = [];
  10.         for (var i=0; i<songliste.firstChild.childNodes.length; i++) {//für alle Elemente in der XMLfile
  11.             //Die attribute auslesen und in die Arrays packen
  12.             _global.songnamen[i] = songliste.firstChild.childNodes[i].attributes.name;
  13.             _global.songfiles[i] = songliste.firstChild.childNodes[i].attributes.file;
  14.             _global.bitrates[i] = songliste.firstChild.childNodes[i].attributes.bitrate;
  15.             trace(songnamen[i]+"  "+songfiles[i]);//überprüfen, ob wirklich die Daten richtig übergeben wurden
  16.         }
  17.         _root.createEmptyMovieClip("sound_mc",1);
  18.         _global.song_nr = random(songfiles.length); // per Zufall einen Song auswählen
  19.         _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]); // song, der grade per Zufall ausgewählt wurde starten
  20.     } else {anz.text="Fehler beim Laden der XML datei"}//falls ein Fehler auftritt beim Laden
  21. }
  22.  
  23. function zeit(sound_obj) {
  24.     time = sound_obj.position/1000;//aktuelle position (millisekunden ) in Sekunden umwandeln
  25.     min = Math.floor(time/60);//Minuten berechnen
  26.     min=(min<10)? "0"+min : min;//ggf. bei den Minuten ne 0 vorne dran
  27.     sek = Math.floor(time%60);//Sekunden berechnen
  28.     sek=(sek<10)? "0"+sek : sek;//ggf. bei den Sekunden ne 0 vorne dran
  29.     zeit_anz.text=min+":"+sek;//Zeitausgabe ins Textfeld
  30. }
  31.  
  32. MovieClip.prototype.song_starten = function (file, name) {
  33.     if (this.sound_obj) {//wenn ein SoundObjekt existiert
  34.         this.sound_obj.stop();//stoppen
  35.         delete this.sound_obj;//und löschen
  36.     }
  37.     this.sound_obj = new Sound(this);//neues SoundObjek erstellen
  38.     this.sound_obj.loadSound(file,true)//true steht hier für streaming=an
  39.     this.onEnterFrame = function () {//das onEnterFrame Ereignis
  40.         if(this.sound_obj.position>0) {//wenn der Sound startet
  41.             delete this.onEnterFrame; // das onEnterFrame Ereignis löschen
  42.             this._parent.anz.text=name; //name wurde als parameter it übergeben
  43.             zeit_interval = setInterval(zeit,1000,this.sound_obj);//Zeitanzeige starten
  44.             this._parent.anz_balken.pointer.onEnterFrame = function() {//pointer ein OnEnterFrame ereignis zuweisen
  45.                 var s_obj = this._parent._parent.sound_mc.sound_obj// weil's so viel zu schreiben wäre, habe ich's referenziert
  46.                 var pos = s_obj.position/1000;// Abspieloposition in Sekunden
  47.                 var ges = (s_obj.getBytesTotal()/1000)/(bitrates[song_nr]/8);//Soundlänge berechnen
  48.                 var p = (pos/ges)*100;//prozentuale Abspielposition
  49.                 this._x = p*(this._parent.balken._width/100);//_x position prozentual zur Breite des Preloaders bewegen
  50.             }
  51.             this._parent.vol.pegel.onPress = function () {//dem pegel mc ein onPress Ereignis zuweisen
  52.                 startDrag(this,true,this._x,0,this._x,this._parent.laut._height);//Drag starten mit der y Begrenzung des "laut" mcs
  53.                 this.onEnterFrame = function () {//"pegel" ein onEnterFrame Ereignis zuweisen
  54.                     var p = 100-(this._y/this._parent.laut._height)*100;//Prozentwert für die Regulierung berechnen
  55.                     this._parent._parent.sound_mc.sound_obj.setVolume(p);//neuen Wert für die Lautstärke setzen
  56.                 }
  57.             }
  58.             this._parent.vol.pegel.onRelease = function () {//dem "pegel" mc ein onRelease Ereignis zuweisen
  59.                 stopDrag();//Drag stoppen
  60.                 delete this.onEnterFrame;//onEnterFrame vom "pegel" mc löschen
  61.             }
  62.         } else {
  63.             this._parent.anz.text="loading..." //this._parent heißt soviel wie: dieser_mc_hier.die_übergeordnete_instanz dort liegt nämlich das textfeld "anz".
  64.         }
  65.     }
  66.     this._parent.anz_balken.onEnterFrame = function() {//dem "anz_balken" mc ein onEnterFrame Ereignis zuweisen
  67.         var l = this._parent.sound_mc.sound_obj.getBytesLoaded();//Die schon geladenen Byets des Sounds auslesen
  68.         var t = this._parent.sound_mc.sound_obj.getBytesTotal();//Die gesamten Byets des Sounds auslesen
  69.         this.balken._xscale = (l/t)*100;//dem "balken" den schon geladenen Teil in Prozent als _xscale zuweisen
  70.         if (l>=t && l>20) {//Wenn der Song fertig geladen wurde (und sicher gestellt wurde, dass angefangen wurde zu laden)
  71.             delete this.onEnterFrame;// das onEnterFrame löschen
  72.         }
  73.     }
  74.     this.sound_obj.onSoundComplete = function () {//wenn der sound fertig abgespielt wurde
  75.         clearInterval(zeit_interval);//Zeitanzeige stoppen
  76.         this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  77.         (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  78.         _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  79.     }
  80. }
  81.  
  82. btn_play.onRelease = function () {
  83.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  84.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  85.     this._parent.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//aktuell ausgewählten Song starten
  86. }
  87. btn_stop.onRelease = function() {
  88.     this._parent.sound_mc.sound_obj.stop(); //Wiedergabe stoppen
  89.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  90.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  91.     delete this._parent.anz_balken.pointer.onEnterFrame;//pointer onEnterFrame löschen
  92.     this._parent.anz.text="Wiedergabe gestoppt";
  93. }
  94. btn_next.onRelease = function () {
  95.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  96.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  97.     (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  98.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  99. }
  100. btn_prev.onRelease = function () {
  101.     clearInterval(zeit_interval);//Zeitanzeige stoppen
  102.     this._parent.zeit_anz.text="00:00";//Zeitanzeige zurücksetzen
  103.     (song_nr==0)? _global.song_nr=songfiles.length-1 : _global.song_nr--;//vorherigen Song auswählen(song_nr--) es seiden der erste wurde grade abgespielt.. dann wieder hinten anfangen
  104.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//vorherigen Song starten
  105. }
  106.  
  107. songliste.load("songlist.xml");//Liste laden
  108.  

Geändert von pape (09-02-2005 um 03:01 Uhr)
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 03:28   #7 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
4. Ausleitung

Endlich ist also Part II fertig.
Das war mit Abstand das längste Tutorial was ich bis jetzt geschrieben habe....!
Ich brauche nun echt mal ne Pause.. keine Ahnung wie lange ich jetzt daran gesessen habe!
Ich hoffe mal ihr könnt das irgendwie gebrauchen.

Wie auch in Part I muss ich aber leider Anmerken, dass es vorkommen kann, dass auf Grund der Länge des Tutorials hier und da der ein oder andere Fehler passiert ist, da ich unten was geändert habe und es oben vergessen habe oder so... ich hoffe, dass es nicht passiert ist.
Wenn doch, dann schreibt es bitte, falls ihr es merkt, damit Andere nicht weiter verwirrt werden.

Lob, Anmerkungen, Verbesserungsvorschläge und konstruktive Kritik ist natürlich, wie immer, erwünscht!

Wenn noch irgendwelche Fragen unbeantwortet geblieben sein sollten oder irgendwas im Tutorial nicht ganz klar wurde, dann fragt einfach!

So weit so gut! Die zum Tutorial gehörenden Dateien findet ihr im Anhang!

Angucken

mit freundlichen Grüßen,
Robert
Angehängte Dateien
Dateityp: zip mp3bitrates2xml.zip (1,4 KB, 869x aufgerufen)
Dateityp: rar mp3bitrates2xml.rar (1,3 KB, 639x aufgerufen)
Dateityp: zip tutorial_Mp3-Player_Part2.zip (6,8 KB, 870x aufgerufen)

Geändert von salazar (30-07-2006 um 23:43 Uhr)
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 17:03   #8 (permalink)
Rc-freak
 
Benutzerbild von Domsi
 
Registriert seit: Sep 2004
Ort: Steiermark (Ö)
Beiträge: 1.152
ich weiß nicht was da jetzt genau nicht funktioniert! , bin grad erst beim preloader, aber sollte der nicht schon funktionieren?

also bin vor dem pointer, aber es tut sich einfach nichts bei mir! So schaut zur zeit mein script aus, oder muss ich da zuerst das andere machen damit da mal der balken rüberfährt?
ActionScript:
  1. stop();
  2. songliste = new XML();
  3. songliste.ignoreWhite=true;
  4. songliste.onLoad = function(success){
  5.     if(success){
  6.         _global.songnamen = [];
  7.         _global.songfiles = [];
  8.         for(var i=0; i<songliste.firstChild.childNodes.length; i++){
  9.             _global.songnamen[i] = songliste.firstChild.childNodes[i].attributes.name;
  10.             _global.songfiles[i] = songliste.firstChild.childNodes[i].attributes.file;
  11.         trace(songnamen[i]+"  "+songfiles[i]);
  12.         }
  13.         _root.createEmptyMovieClip("sound_mc",1)
  14.         _root.sound_mc.soundobjekt = new Sound();
  15.         _global.song_nr = 0;
  16.         _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr])
  17.         }else {anz.text="Fehler beim Laden der XML datei"}
  18.     }
  19.     function zeit(soundobjekt) {
  20.  time=soundobjekt.position/1000;
  21. min = Math.floor(time/60);
  22. sek = Math.floor(time%60);
  23. min=(min<10)? "0"+min : min;
  24. sek=(sek<10)? "0"+sek : sek;
  25. zeit_anz.text=min+":"+sek;
  26. }
  27.     MovieClip.prototype.song_starten = function (file, name) {
  28.       if (this.soundobjekt) {
  29.         this.soundojekt.stop();
  30.         delete this.soundobjekt;
  31.     }
  32.     this.soundobjekt = new Sound(this);
  33.     this.soundobjekt.loadSound(file,true)
  34.     this.onEnterFrame = function () {
  35.         if(this.soundobjekt.position>0) {
  36.             zeit_interval = setInterval(zeit,1000,this.soundobjekt);
  37.             delete this.onEnterFrame;
  38.             this._parent.anz.text=name;
  39. this._parent.anz_balken.onEnterFrame = function() {//dem "anz_balken" mc ein onEnterFrame Ereignis zuweisen
  40.     var l = this._parent.sound_mc.soundobjekt.getBytesLoaded();//Die schon geladenen Byets des Sounds auslesen
  41.     var t = this._parent.sound_mc.soundobjekt.getBytesTotal();//Die gesamten Byets des Sounds auslesen
  42.     this.anz_balken.balken._xscale = (l/t)*100;//dem "balken" den schon geladenen Teil in Prozent als _xscale zuweisen
  43.     if (l>=t) {//Wenn der Song fertig geladen wurde
  44.         delete this.onEnterFrame;// das onEnterFrame löschen
  45.     }
  46. }
  47. } else {
  48.             this._parent.anz.text="loading..."
  49.         }
  50.     }
  51.     this.soundobjekt.onSoundComplete = function () {
  52.     clearInterval(zeit_interval);
  53.     this._parent.zeit_anz.text="00:00";
  54.         (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;
  55.         _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);
  56.     }
  57. }
  58. btn_play.onRelease = function () {
  59.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);
  60. clearInterval(zeit_interval);
  61.     this._parent.zeit_anz.text="00:00";
  62.     }
  63. btn_stop.onRelease = function () {
  64.     this._parent.sound_mc.soundobjekt.stop();
  65.     clearInterval(zeit_interval);
  66.     this._parent.zeit_anz.text="00:00";
  67.     this._parent.anz.text="Wiedergabe gestoppt";
  68. }
  69. btn_next.onRelease = function () {
  70.     (song_nr==songfiles.length-1)? _global.song_nr=0 : _global.song_nr++;//nächsten Song auswählen (-1 da song_nr bei 0 anfäng)
  71.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//nächsten Song starten
  72.     clearInterval(zeit_interval);
  73.     this._parent.zeit_anz.text="00:00";
  74.     }
  75. btn_prev.onRelease = function () {
  76.     (song_nr==0)? _global.song_nr=songfiles.length-1 : _global.song_nr--;
  77.     _root.sound_mc.song_starten(songfiles[song_nr],songnamen[song_nr]);//vorherigen Song starten
  78.     clearInterval(zeit_interval);
  79.     this._parent.zeit_anz.text="00:00";
  80.     }
  81.  
  82.  
  83. songliste.load("songlist.xml");

lg, Domsi
__________________
Für Rechtschreibfehler haftet meine Tastatur.

Frühstücken tun alle (Nutella)

http://www.dominik-klein.at|Einfache Flashanfängertuts|Geburtstagsreminder

lg, Domsi
Domsi ist offline   Mit Zitat antworten
Alt 08-02-2005, 20:38   #9 (permalink)
Neuer User
 
Registriert seit: Dec 2004
Beiträge: 31
ich liebe dieses tut!!

eine anmerkung bzw. frage habe ich dennoch:

ich hab den film getestet und bei der gelegenheit auch mal einen download simuliert und musste feststellen, dass bei ISDN (was es ja durchaus immernoch gibt) die mp3 schon mal ins schwitzen kommt, sprich sie "ruckelt".
daher wollte ich den code so abändern, das die mp3 etwas später abgespielt wird. kann irgentjemand nen tipp geben wo und wie man sowas am besten realisieren würde?!?

Gruß Daniel

PS: pape for president
bestboy ist offline   Mit Zitat antworten
Alt 08-02-2005, 20:48   #10 (permalink)
Flash-holic
 
Benutzerbild von DeMoehn
 
Registriert seit: Nov 2003
Ort: Neunkirchen(Saar)
Beiträge: 988
Weiß nich mehr genau, zumindest hatte ich es mal so gemacht, einfach ziemlich oben
ActionScript:
  1. _soundbuftime = 10;
somit sinds 10 sek wartezeit kannste ntürlich hochstellen, wenns nich funzt bescheid sagen
__________________
Wer Großes versucht, ist bewunderswert, auch wenn er fällt.
Lucius Annaeus Seneca
(ca. 4 v. Chr - 65 n. Chr.)


DeMoehn ist offline   Mit Zitat antworten
Alt 08-02-2005, 22:47   #11 (permalink)
-
 
Benutzerbild von pape
 
Registriert seit: Jan 2004
Beiträge: 3.002
@ domsi: du hast das Script für den Preloader in das onEnterFrame Ereignis des Prototypen gesetzt... das darfst du natürlich nicht.. so wie es bei dir da jetzt steht, wird der ladestatus erst angezeiget, wenn der Sound anfängt abzuspielen.. der soll aber ja direkt die ladeanzeige zeigen.. daher so:
ActionScript:
  1. //prototype...
  2. this.onEnterFrame = function () {
  3. //...anderes script
  4. }//<--- onEnterFrame end;
  5. //hier den Preloader hin!
  6.  

@bestboy: so wie BAdBoYY gesagt hat sollte es gehen!
Einfach direkt nach dem stop(); in der ersten Zeile des gesamten Scripts die _soundbufftime höher stellen!

grz
pape
pape ist offline   Mit Zitat antworten
Alt 08-02-2005, 23:04   #12 (permalink)
Rc-freak
 
Benutzerbild von Domsi
 
Registriert seit: Sep 2004
Ort: Steiermark (Ö)
Beiträge: 1.152
achso man blöd ja danke, jetzt funktz, is eigentlich fast logisch
__________________
Für Rechtschreibfehler haftet meine Tastatur.

Frühstücken tun alle (Nutella)

http://www.dominik-klein.at|Einfache Flashanfängertuts|Geburtstagsreminder

lg, Domsi
Domsi ist offline   Mit Zitat antworten
Alt 08-02-2005, 23:18   #13 (permalink)
Dr. Funk
 
Registriert seit: Sep 2001
Beiträge: 136
hallo pape,

ein ganz tolles tutorial, herzlichen glückwunsch dazu und vielen dank für deine mühe!

ein problem habe ich aber beim ausprobieren festgestellt:
PHP-Code:
// Preloader für die zu ladenden MP3's:
    
this._parent.anz_balken.onEnterFrame = function() {//dem "anz_balken" mc ein onEnterFrame Ereignis zuweisen 
        
var this._parent.sound_mc.sound_obj.getBytesLoaded();//Die schon geladenen Byets des Sounds auslesen 
        
var this._parent.sound_mc.sound_obj.getBytesTotal();//Die gesamten Byets des Sounds auslesen 
        // DEBUG:
        //this.anzL.text = l;
        //this.anzT.text = t;
        
this.balken._xscale = (l/t)*100;//dem "balken" den schon geladenen Teil in Prozent als _xscale zuweisen 
        
if (l>=t) {//Wenn der Song fertig geladen wurde 
            
delete this.onEnterFrame;// das onEnterFrame löschen 
        

    } 
wenn man das ganze online testet und mp3's streamt, funktioniert der mp3-preloader leider nicht.
die werte für "var l" und "var t" bleiben 0, somit wird der balken nicht "gefüllt".
das abspielen funktioniert hingegen einwandfrei, die datei wird also offensichtlich geladen.
anscheinend erkennt flash die werte von getBytesLoaded() und getBytesTotal() erst, wenn das mp3 komplett runtergeladen im cache liegt..

PHP-Code:
// Pointer bewegen
            
this._parent.anz_balken.pointer.onEnterFrame = function() {//pointer ein OnEnterFrame ereignis zuweisen 
                
var s_obj this._parent._parent.sound_mc.sound_obj// weil's so viel zu schreiben wäre, habe ich's referenziert 
                
var pos s_obj.position/1000;// Abspieloposition in Sekunden 
                
var ges = (s_obj.getBytesTotal()/1000)/(bitrates[song_nr]/8);//Soundlänge berechnen 
                
_global.songLength Math.round(ges);
                var 
Math.round((pos/ges)*100);//prozentuale Abspielposition
                // DEBUG:                
                //this.anzP.text = p;
                
this._x p*(this._parent.balken._width/100);//_x position prozentual zur Breite des Preloaders bewegen 
            

auch der pointer taucht erst auf, wenn man einen song zum zweiten mal startet (wahrscheinlich auch, weil dieser dann bereits im cache liegt..)

gibt es da vielleicht eine lösung für?

ansonsten wie gesagt: top!


(Nachtrag: Lokal funktioniert übrigens alles einwandfrei!
Und ich habe den kompletten Player nicht im _root, sondern in einem MC in einem anderen Film integriert.)
__________________
HEITER WEITER
q|_|@S|^^°^°

Geändert von quasimono (08-02-2005 um 23:23 Uhr)
quasimono ist offline   Mit Zitat antworten
Alt 08-02-2005, 23:22   #14 (permalink)
Rc-freak
 
Benutzerbild von Domsi
 
Registriert seit: Sep 2004
Ort: Steiermark (Ö)
Beiträge: 1.152
na ich weiß ich wollte das auch grad reinschreiben, bei mir muss auch ma im cach liegen, dann muss ich herumupfen aktualisieren wieder auf andere seiten usw.

hat irgendwas

edit: hier kann man sich das mal angucken: http://www.dominik-klein.at/test/mp3...mp3-player.swf
__________________
Für Rechtschreibfehler haftet meine Tastatur.

Frühstücken tun alle (Nutella)

http://www.dominik-klein.at|Einfache Flashanfängertuts|Geburtstagsreminder

lg, Domsi

Geändert von Domsi (08-02-2005 um 23:25 Uhr)
Domsi ist offline   Mit Zitat antworten
Alt 08-02-2005, 23:30   #15 (permalink)
Flash-holic
 
Benutzerbild von DeMoehn
 
Registriert seit: Nov 2003
Ort: Neunkirchen(Saar)
Beiträge: 988
Sachen die ich komisch oder einfach unschön finde:
Also:
1) Das var vor t und l
Meiner Meinung anch kommt var nur vor neu deklarierungen und muss auch heutzutage nich mehr sein, also warum dann var davor?
2) Den _xscale nciht in einer else
Also, ich find schöner wenns
ActionScript:
  1. // Preloader für die zu ladenden MP3's:
  2. ****this._parent.anz_balken.onEnterFrame = function() {***** 
  3.  l = this._parent.sound_mc.sound_obj.getBytesLoaded();
  4. ********t = this._parent.sound_mc.sound_obj.getBytesTotal();
  5. if (l>=t) {//Wenn der Song fertig geladen wurde
  6. ************delete this.onEnterFrame;// das onEnterFrame löschen
  7. ********}else{
  8. this.balken._xscale = (l/t)*100;
  9. }
  10. ****}
so aussehn würde
__________________
Wer Großes versucht, ist bewunderswert, auch wenn er fällt.
Lucius Annaeus Seneca
(ca. 4 v. Chr - 65 n. Chr.)


DeMoehn ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 04:23 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele