Zurück   Flashforum > Flash > Stuff

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 25-02-2008, 19:53   #1 (permalink)
Neuer User
 
Registriert seit: Mar 2006
Beiträge: 177
[Stuff]mp3 Player

Hallo Leute, möchte mich hiermit mal für die Hilfe bedanken und gleichzeitig anderen damit helfen

Also ich habe einen Mp3 Player erstellt, den stelle ich euch nun zur verfügung . (( musste die RAR splitten auf 2 á 48kb))

+++++++++++++++++++++++++
+ features: +
+++++++++++++++++++++++++
- Play / Pause Button
- Next / Prevous Button
- Stop Button
- Mute Button
- Volume Fader
- Position Fader
- ID3 Tag Anzeige
- scrollable Playlist
- XML Data Input
- kleines PHP Script zum erzeugen der XML Datei
- ev. ein bisschen Dirrty Code


Ihr könnt den Player erweitern, frei benutzen, ändern , Fehler finden ^^

So denn wünsche ich viel Spaß damit, und ich hoffe einige lernen daraus noch ein bisschen


Hier nochmal der Main Code:
PHP-Code:

//Array of Songs
var sa:Array = new Array();

// Current Playing Song
var cps:Number = -1;

//Position of Music
var pos:Number;

//old Playlist Height

oldPlh playlist._height;


//save last Volume
var lastVol:Number 100;

//load XML for Songs
var xml:XML = new XML();
xml.ignoreWhite true;
xml.onLoad = function(){
    var 
nodes:Array = this.firstChild.childNodes;
    for(var 
i=0i<nodes.length;i++)
    {
        
sa.push("mp3s/"+nodes[i].attributes.name);
        
playlist.cont.attachMovie("plBtn","plBtn"+i,playlist.cont.getNextHighestDepth());
        
playlist.cont["plBtn"+i]._y i*playlist.cont["plBtn"+i]._height;
        
playlist.cont["plBtn"+i].btn_txt.text nodes[i].attributes.name;
        
playlist.cont["plBtn"+i].id i;
        
playlist.cont["plBtn"+i].onRollOver = function(){
            
this.gotoAndStop(2);
        }
        
playlist.cont["plBtn"+i].onRollOut = function(){
            
this.gotoAndStop(1);
        }
        
playlist.cont["plBtn"+i].onRelease = function(){
            
cps this.id-1
            playSong
();
        }
    }
    
playSong();
}

xml.load("tracks.xml");

//Play the mp3
function playSong():Void
{
    
arrow._x posLine._x;
    
delete arrow.onEnterFrame;
    
= new Sound();
    
s.onSoundComplete playSong;
    
s.onLoad getPos;
    if(
cps==sa.length-1)
    {
        
cps=0;
        
s.loadSound(sa[cps],true);
        
synth.synthOn();
        
setTime();
        
s.onID3 = function(){
        
idtag.text s.id3.artist+" - "+s.id3.songname;
        };
    }else{
        
s.loadSound(sa[++cps],true);
        
synth.synthOn();
        
setTime();
        
s.onID3 = function(){
        
idtag.text s.id3.artist+" - "+s.id3.songname;
        };
    }
    
playPause.gotoAndStop("pause");
}
//pauses the Music

function pauseIt():Void
{
    
synth.synthOff();
    
pos s.position;
    
s.stop();
}

function 
unPauseIt():Void
{
    
synth.synthOn();
    
s.start(pos/1000);
    
setTime();
}







// Music Controls

//Play/Pause
playPause.onRollOver = function()
{
    if(
this._currentFrame == 1this.gotoAndStop("playOver");
    else 
this.gotoAndStop("pauseOver");
}
playPause.onRollOut playPause.onReleaseOutside = function()
{
    if(
this._currentFrame == 10this.gotoAndStop("play");
    else 
this.gotoAndStop("pause");
}
playPause.onRelease = function()
{
    
getPos();
    if(
this._currentframe == 30){
        
this.gotoAndStop("playOver")
        
this._parent.pauseIt();
    }else{
        
this.gotoAndStop("pauseOver")
        
this._parent.unPauseIt();
    }
}

//next Button
next.onRollOver = function()
{
    
this.gotoAndStop("nextOver");
}
next.onRollOut next.onReleaseOutside =  function()
{
    
this.gotoAndStop("next");
}

next.onRelease = function()
{
    
this._parent.playSong();
}
//Previous Button
prev.onRollOver = function()
{
    
this.gotoAndStop("prevOver");
}
prev.onRollOut prev.onReleaseOutside =  function()
{
    
this.gotoAndStop("prev");
}
prev.onRelease = function()
{
    if(
cps==0){
        
cps=sa.length;
        
cps -= 2;
        
this._parent.playSong();
    }else{
    
cps -= 2;
    
this._parent.playSong();
    }
}
//Stop Button
stop_btn.onRollOver = function()
{
    
this.gotoAndStop("stopOver");
}
stop_btn.onRollOut stop_btn.onReleaseOutside =  function()
{
    
this.gotoAndStop("stop");
}
stop_btn.onRelease = function(){
    
delete arrow.onEnterFrame;
    
arrow._x posLine._x;
    
pos 0;
    
playPause.gotoAndStop("play");
    
s.stop();
    
synth.synthOff();
    
delete this._parent.onEnterFrame;
    
time.text "0:00";
}

// Mute Button
mute.onRollOver = function()
{
    if(
this._currentFrame == 1this.gotoAndStop("offOver");
    else 
this.gotoAndStop("onOver");
}
mute.onRollOut mute.onReleaseOutside = function()
{
    if(
this._currentFrame == 10this.gotoAndStop("off");
    else 
this.gotoAndStop("on");
}
mute.onRelease = function(){
    if(
this._currentFrame == 10)
    {
        
this.gotoAndStop("onOver");
        
s.setVolume(0);
        
volDragger._y volLine._y;
    }else{
        
this.gotoAndStop("offOver");
        
s.setVolume(lastVol);
        
volDragger._y lastVol/(volFaktor*-1)+volLine._y;
    }
}
// Set the Time Display
function setTime(){
    
this.onEnterFrame = function(){
        var 
min:Number 0;
        var 
sec:Number 0;
        
min Math.floor(s.position/1000 /60);
        
sec Math.round(s.position/1000);
        if(
sec<60){
            
sec2 sec
        
}else{
            
sec2 Math.round(s.position/1000)-min*60;
        }
        if (
sec2<10)        time.text min+":0"+sec2;
        else     
time.text min+":"+sec2;
    }
}
// Get Volume by Dragger
var volFaktor:Number 100/volLine._height;
volDragger._x volLine._x;
volDragger._y volLine._y-volLine._height;
volDragger.onPress = function(){
    
startDrag(this,false,this._x,volLine._y,this._x,volLine._y-volLine._height);
    
this.onEnterFrame = function(){
    
vol Math.floor( (this._y-volLine._y) * volFaktor*-1);
    
s.setVolumevol )
    }
}
volDragger.onRelease volDragger.onReleaseOutside = function(){
    
delete this.onEnterFrame;
    
this.stopDrag()
    
lastVol s.getVolume();
    if(
vol == 0mute.gotoAndStop("on")
    else 
mute.gotoAndStop("off")
}
        
//Setup the Pos Fader

arrow._y posLine._y;
function 
getPos(){
    
soundLength s.duration;
    
slfaktor soundLength/posLine._width
    
    posLine
.onPress = function(){
        
arrow._x _xmouse;
        
s.start((arrow._x-posLine._x)*slfaktor/1000);
    }
    
    
    
arrow.onEnterFrame = function(){
        
this._x posLine._x+s.position/slfaktor;
    
    }
    
arrow.onPress = function(){
        
delete this.onEnterFrame;
        
startDrag(this,false,posLine._x,this._y,posLine._x+posLine._width,this._y);
    }
    
arrow.onRelease arrow.onReleaseOutside =  function()
    {
        
this.stopDrag();
        
s.start((this._x-posLine._x)*slfaktor/1000);
        
getPos();
        
    }
}

//scrolling the Playlist

plDown.onRollOver = function()
{
    
this.gotoAndStop(2);
    
playlist.cont.onEnterFrame = function()
        {
            if(
playlist.cont._y >= playlist._y+-(playlist.cont._height-oldPlh))
            {
            
playlist.cont._y -= 2;
            }
        }
}
plDown.onRollOut = function()
{
    
this.gotoAndStop(1);
    
delete playlist.cont.onEnterFrame;
}



plUp.onRollOver = function()
{
    
this.gotoAndStop(2);
    
playlist.cont.onEnterFrame = function()
        {
            if(
playlist.cont._y 0)
            {
            
playlist.cont._y += 2;
            }
        }
}
plUp.onRollOut = function()
{
    
this.gotoAndStop(1);
    
delete playlist.cont.onEnterFrame;

Und die Datei da ist alles drin, was ihr braucht.

Die Lieder in den Ordner "mp3s"
Wer es aufm Server hat, kann in die PHP seinen HTML Code reinhauen, damit die Lieder immer neu geladen werden, wenn man neue hochlädt.


So denn viel Spaß...
Angehängte Dateien
Dateityp: rar mp3.part1.rar (46,9 KB, 274x aufgerufen)
Dateityp: rar mp3.part2.rar (46,4 KB, 240x aufgerufen)
zirag ist offline   Mit Zitat antworten
Alt 19-03-2008, 10:52   #2 (permalink)
Neuer User
 
Benutzerbild von rosaviakosmos
 
Registriert seit: Aug 2001
Ort: Wiesbaden
Beiträge: 337
Hallo!

Das sieht doch super aus. Eine Frage trotzdem, da ich es leider nicht hinbekommen habe:

Was muss man tun, damit der Player am Ende eines Tracks stehen bleibt? Wenn nur ein Track im XML ist, läuft dieser endlos im Loop. Das wäre noch das iTüpfelchen.. :-)

Viele Grüße

Emil
__________________
Wissen kann man mitteilen,
Weisheit aber nicht.
Hermann Hesse
rosaviakosmos ist offline   Mit Zitat antworten
Alt 19-03-2008, 19:49   #3 (permalink)
Neuer User
 
Registriert seit: Mar 2006
Beiträge: 177
Hi, danke für´s Feedback, du bist der erste, der was dazu schreibt

also das ist ganz einfach.

In der Funktion "playSong" in der 4. Zeile:

PHP-Code:
s.onSoundComplete playSong
Das kannst du entweder rausnehmen, dann läuft aber das Diplay weiter.

Am besten du schreibst eine Funktion, da kannst du alles aus dem Stop Button rauskopieren

PHP-Code:

    delete arrow
.onEnterFrame;
    
arrow._x posLine._x;
    
pos 0;
    
playPause.gotoAndStop("play");
    
s.stop();
    
synth.synthOff();
    
delete this.onEnterFrame;
    
time.text "0:00"
Und dann änderst du das einfach in

PHP-Code:
s.onSoundComplete stopSong
wobei deine Funktion dann natürlich "stopSong" heissen muss


mfg

Geändert von zirag (19-03-2008 um 19:51 Uhr)
zirag ist offline   Mit Zitat antworten
Alt 19-03-2008, 23:52   #4 (permalink)
Neuer User
 
Benutzerbild von _crypto_
 
Registriert seit: Mar 2006
Beiträge: 1.573
wenn man hier schon gräbt dann hier noch n kommentar
ActionScript:
  1. sec = Math.round(s.position/1000);
  2.         if(sec<60){
  3.             sec2 = sec
  4.         }else{
  5.             sec2 = Math.round(s.position/1000)-min*60;
  6.         }
  7. // in
  8.  
  9. sec = (s.position / 1000) % 60;
erspart doch paar abfragen
__________________

Currently working on:

- --- ---

-----------------------------------------------------------------
ActionScript 3.0, C++, Java, Delphi
_crypto_ ist offline   Mit Zitat antworten
Alt 28-03-2008, 14:43   #5 (permalink)
Neuer User
 
Registriert seit: Apr 2006
Beiträge: 859
hi sieht echt gut aus, aber ist es möglich diese player für mehrere playliste zu benutzen.
palpalo ist offline   Mit Zitat antworten
Alt 28-03-2008, 16:04   #6 (permalink)
Neuer User
 
Registriert seit: Mar 2006
Beiträge: 177
Danke für´s Lob

Das musst du dann selber noch einbinden. Du kannst ja die XMLs über ein DropDown oder so auswählen.

Vielleicht mach ich das nochmal, wenn ich Zeit habe.


mfg
zirag ist offline   Mit Zitat antworten
Alt 27-08-2008, 11:55   #7 (permalink)
probierer&sucher
 
Registriert seit: Feb 2008
Ort: Berlin
Beiträge: 567
stecken geblieben

Hallo zirag,
Du scheinst ja von soundsteuerung weit mehr Ahnung zu haben als ich :-) Könntest Du mir vielleicht bei meinem kleinen Projekt weiterhelfen?
Ich bin leider an einigen Punkten stecken geblieben und leider gibt es keine Antworten auf meinen Beitrag.

Ich müßte zum Beispiel die Töne alle aud der Bibliothek laden und über zwei Schalter hin und her schalten. Auch habe ich das Problem, sobald ich das abspielen der Datei in eine Funktion packe, gelingt mir das asnteueren der Blance nicht mehr.

Gruß
Micha
__________________
Ich verwende Adobe Flash CS3 Professional mit Einstellung Flashplayer 9 und AS2
__________________________________________________ ____________________
jeder war bestimmt irgendwann mal ein Newbie ;-)
mfeske ist offline   Mit Zitat antworten
Alt 27-08-2008, 12:15   #8 (permalink)
Flashboarder
 
Registriert seit: May 2004
Beiträge: 234
Hi!

Ich kann part1 nicht öffnen. Liegt das Problem nur bei mir?

Gruß LasQ
fabian_lascu ist offline   Mit Zitat antworten
Alt 28-08-2008, 12:58   #9 (permalink)
probierer&sucher
 
Registriert seit: Feb 2008
Ort: Berlin
Beiträge: 567
hochladen

Hallo fabian_lascu,
beim mir hat das entpacken mit 7-zip funktioniert, dazu müssen aber beide Dateien im gleichen Verzeichnis sein.
Ich habe Dir das ganze hier nochmal als eine zip hochgeladen.

@zirag Ich habe die xml Datei mit wordpad berarebitet und die Dateien in das MP3 Verzeichnis gelegt. Sie werden in der Playlist auch angezeigt, aber hören tu ich leider nichts, woran könnte das liegen?

Gruß
Micha
__________________
Ich verwende Adobe Flash CS3 Professional mit Einstellung Flashplayer 9 und AS2
__________________________________________________ ____________________
jeder war bestimmt irgendwann mal ein Newbie ;-)

Geändert von mfeske (28-08-2008 um 13:18 Uhr)
mfeske ist offline   Mit Zitat antworten
Alt 04-09-2008, 09:44   #10 (permalink)
Flashboarder
 
Registriert seit: May 2004
Beiträge: 234
Vielen Dank mfeske,

was genau hast du an der XML Datei geändert?
Ich habe nämlich das gleiche Problem wie du.
Hast du mir deine geänderten Daten geschickt oder die original zip?
Also ich hab auch noch eben das Lied mit dem entsprechenden Namen in
das Verzeichnis aller Dateien gelegt. Man hört aber keine Musik.
Komisch ...

Gruß Las Q

EDIT: Wer lesen kann ist klar im Vorteil

Zitat:
Die Lieder in den Ordner "mp3s"
==>>> Hey mfeske - leg dir die Musikdatei einfach in einen neuen Ordner "mp3s" - was du da in der swf in der Liste siehst ist lediglich die Info der XML Datei, dass da ein Lied sein müsste.

Geändert von fabian_lascu (04-09-2008 um 09:49 Uhr)
fabian_lascu ist offline   Mit Zitat antworten
Alt 04-09-2008, 12:04   #11 (permalink)
probierer&sucher
 
Registriert seit: Feb 2008
Ort: Berlin
Beiträge: 567
und nochmal

Hallo fabian_lascu,
es ist das original und die Dateien hate ich in dem entsprechenden Ordner, aber leider tritzdem kein Ton. siehe auch hier.

Gruß
Micha
__________________
Ich verwende Adobe Flash CS3 Professional mit Einstellung Flashplayer 9 und AS2
__________________________________________________ ____________________
jeder war bestimmt irgendwann mal ein Newbie ;-)

Geändert von mfeske (04-09-2008 um 12:12 Uhr)
mfeske ist offline   Mit Zitat antworten
Alt 04-09-2008, 18:54   #12 (permalink)
Flashboarder
 
Registriert seit: May 2004
Beiträge: 234
sry, dass ich erst jetzt antworte.

Du musst schauen, dass der Dateiname in der XML Datei auch korrekt ist. Sonst klappt es nicht!

Code:
<?xml version='1.0' encoding='utf-8'?>
<tracks>
<track name= "0125.mp3"/>
<track name= "0250.mp3"/>
<track name= "0500.mp3"/>
</tracks>
So sollte es gehen. Oder du benennst eben deine Musikdatein im Ordner mp3s um. Anstatt 0125.mp3 eben Frequenz 125 Hz - 0125.mp3.

Grüße Las Q
fabian_lascu ist offline   Mit Zitat antworten
Alt 05-09-2008, 07:17   #13 (permalink)
probierer&sucher
 
Registriert seit: Feb 2008
Ort: Berlin
Beiträge: 567
mein fehler

.. stimmt jetzt funktioniert es.
Hast Du vielleicht auch noch eine Funktion entdeckt, wie der abgespielte Titel angezeigt wird, das ist bei mir nämlich nicht so, wenn ich ihn anklicke wird er orange, danach wird der nächste abgespielt, dieser wird aber nicht orange.
Gab es nicht auch irgendwo schon eine Lösung, das nicht sofort abgespielt wird?

Gruß
Micha
__________________
Ich verwende Adobe Flash CS3 Professional mit Einstellung Flashplayer 9 und AS2
__________________________________________________ ____________________
jeder war bestimmt irgendwann mal ein Newbie ;-)
mfeske ist offline   Mit Zitat antworten
Alt 05-09-2008, 16:20   #14 (permalink)
Flashboarder
 
Registriert seit: May 2004
Beiträge: 234
Heyho!

Ja das gibt es sicherlich alles irgendwo - man muss nur suchen um es zu finden

Hab mir das ganze mal angeschaut, weils mich auch interessiert hat und hab beide deiner Änderungswünsche eingebaut.

Kopier den Code am besten nicht einfach blind, sondern versuch zu verstehen was er macht. Ich musste mich auch erst durch den Code arbeiten um zu verstehn was er macht.

Also los gehts:

Zunächst musst du dem Button plBtn einen weiteren Zustand zuweisen. Ich nenne ihn später nur noch "Over-Button". Der Zustand zeigt an welches Lied gerade gespielt wird. Dazu einfach die Ebenen AS und txt um einen Frame verlängern und die Ebene um ein Schlüsselbild erweitern. Da kannste dann auch die Farbe für diesen "Over-Button" festlegen.

Und dann das AS einfach abändern bzw. erweitern. Hab die entsprechenden Stellen nochmal auskommentiert.

ActionScript:
  1. //load XML for Songs
  2. var xml:XML = new XML();
  3. xml.ignoreWhite = true;
  4. xml.onLoad = function(){
  5.     var nodes:Array = this.firstChild.childNodes;
  6.     for(var i=0; i<nodes.length;i++)
  7.     {
  8.         sa.push("mp3s/"+nodes[i].attributes.name);
  9.         playlist.cont.attachMovie("plBtn","plBtn"+i,playlist.cont.getNextHighestDepth());
  10.         playlist.cont["plBtn"+i]._y = i*playlist.cont["plBtn"+i]._height;
  11.         playlist.cont["plBtn"+i].btn_txt.text = nodes[i].attributes.name;
  12.         playlist.cont["plBtn"+i].id = i;
  13.        
  14.         playlist.cont["plBtn"+i].onRollOver = function(){
  15.             if (this._currentframe == 1) { //Wenn Button im Grundzustand ...
  16.                 this.gotoAndStop(2); //geh zum Frame für RollOver-Zustand
  17.             }
  18.         }
  19.        
  20.         playlist.cont["plBtn"+i].onRollOut = function(){
  21.             if (this._currentframe == 2) { //Wenn Button im RollOver-Zustand ...
  22.                 this.gotoAndStop(1); //... wechsle in Grundzustand beim Herausrollen
  23.             }
  24.         }
  25.        
  26.         playlist.cont["plBtn"+i].onRelease = function(){
  27.             for (a = 0; a <i; a++) {
  28.                 //a zählt nochmals die Anzahl der Buttons für die Lieder  durch
  29.                 playlist.cont["plBtn"+a].gotoAndStop(1);
  30.                 //... und setzt alle Buttons in den Grundzustand
  31.             }
  32.             this.gotoAndStop(3);
  33.             //... damit danach nur der geklickte Button den "Over-Zustand" bekommt
  34.             cps = this.id-1
  35.             playSong();
  36.         }
  37.  
  38.     }
  39.     //playSong();
  40.     //Hier ist die verantwortliche Funktion für das sofortige Abspielen der Songs
  41. }
  42.  
  43. xml.load("tracks.xml");
  44.  
  45. //Play the mp3
  46. function playSong():Void {
  47.     arrow._x = posLine._x;
  48.     delete arrow.onEnterFrame;
  49.     s = new Sound();
  50.     s.onSoundComplete = playSong;
  51.     s.onLoad = getPos;
  52.     if(cps==sa.length-1){
  53.         playlist.cont["plBtn"+(cps)].gotoAndStop(1);
  54.         /*Hier muss das Script für den "Over"-Zustand jedes Buttons geändert werden,
  55.         da er ja abhängig vom gerade gespielten Song ist -> deswegen in der playSong()
  56.         Funktion */
  57.         //cps gibt die Nummer des aktuell spielenden Songs wieder (siehe oben).
  58.         /*Wenn die Songs alle einmal durchgespielt wurden, dann fängt er wieder von
  59.         vorne an. Deswegen setzen wir den letzten Liedbutton hier in den Grundzustand.*/
  60.         playlist.cont["plBtn"+(cps-1)].gotoAndStop(3); //
  61.         /*... und hier setzen wir den ersten Liedbutton in den "Over-Zustand"*/
  62.         cps=0;
  63.         s.loadSound(sa[cps],true);
  64.         synth.synthOn();
  65.         setTime();
  66.         s.onID3 = function(){
  67.         idtag.text = s.id3.artist+" - "+s.id3.songname;
  68.         };
  69.     }else{
  70.         playlist.cont["plBtn"+(cps)].gotoAndStop(1);
  71.         /*Wenn der Song fertig gespielt wurde, dann setze diesen Button fürs Lied in
  72.         den Grundzustand*/
  73.         playlist.cont["plBtn"+(cps+1)].gotoAndStop(3);
  74.         /*... und setze den nächsten Songbutton in den Over-Zustand*/
  75.         s.loadSound(sa[++cps],true);
  76.         synth.synthOn();
  77.         setTime();
  78.         s.onID3 = function(){
  79.         idtag.text = s.id3.artist+" - "+s.id3.songname;
  80.         };
  81.     }
  82.     playPause.gotoAndStop("pause");
  83. }

Noch was ... da am Anfang ja kein Lied gespielt wird, hängt der Cursor für die momentane Abspielposition etwas in der Luft. Du kannst ihn aber einfach außerhalb der Bühne schieben. Dann sieht man ihn anfangs nicht und er wird später an die richtige Position gesetzt. Wenn du ihn löscht, musst du das AS wieder ummodeln ...

Grüße Las Q

Geändert von fabian_lascu (05-09-2008 um 16:22 Uhr)
fabian_lascu ist offline   Mit Zitat antworten
Alt 16-09-2008, 22:15   #15 (permalink)
Neuer User
 
Registriert seit: Sep 2008
Beiträge: 25
Ich hab das zum testen mal auf den server geladen.

Bei mir funzt das php script irgendwie nicht. also, musik kommt aber die beschreibung der tracks.xml kommt nicht. chmod ist 777

Idee'n?
DiscJockey5 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 18:33 Uhr.

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


Copyright ©1999 – 2012 Marc Thiele