Web-MP3-Jukebox

  • Vielen Dank an:
    • Annekatrin Hopf, für mehrmaliges Korrekturlesen dieser Dokumentation

1. Grundlagen (MP3 und MP3-Tagging)

1.1 Grundlagen MP3

  • entwickelt 1987 am Fraunhofer Institut in Erlangen
  • Dateiformat mit verlustbehafteter Audiokompression
  • Komprimierung der Audiodaten angepasst auf das menschliche Gehör
  • geringer Speicherbedarf der Audiodaten
  • variable Bitrate bis zu 320 kbit/s
  • im Internet sehr weit verbreitet

1.2 Grundlagen MP3-Tagging

  • ermöglicht Metadaten unabhängig vom Dateinamen zu speichern
  • Mp3-Informationen dienen zur
    • Information über gerade gespielte Stücke
    • Sortierung der MP3-Dateien in Playlists
    • Organisation von Archiven
  • Versionen
    • ID3v1 beschränkt auf 30 Zeichen pro Eintrag
    • ID3v2 flexiblere Version, wird nicht von allen Hardwareplayern unterstützt

2. Projektanalyse

2.1 Anforderungsanalyse

  • soll vom Web erreichbar sein
  • einfache Fernsteuerung des Players
  • zentraler Zugang zur MP3-Sammlung
  • Funktionalität des Players (play stop skip)
  • Anzeige von Titelinformationen (MP3-Tag)
  • Funktionalität einer Playlist und eines Filebrowsers

2.2 Auswahl der Tools

2.2.1 mpg123

  • Multimedia-Anwendung ist beschränkt in PHP möglich
  • Auswahl des Tools MPG123 zum Abspielen der MP3-Dateien
  • MPG123
    • ist ein Linux- und Kommandozeilenprogramm
    • stellt die grundlegenden Playerfunktionen zur Verfügung

2.2.2 ID3V2

  • Auslesen der ID3-Tags ist in PHP noch nicht möglich
  • Auswahl des Tools ID3V2 um die Titelinformationen auszulesen
  • Id3v2
    • ist ein Linux- und Kommandozeilenprogramm
    • Auslesen der MP3-Tags

3. Implementierung

Realisierung

  • für die Realisierung wurde PHP ausgewählt
    • Gründe
      • serverseitiges Ausführen der Scripte
      • einfache Implementierung in einen Webserver
      • Möglichkeit, externe Programme einzubinden
  • Einsatz von HTML und CSS

4. PHP und HTML im Detail

4.1 Crashkurs HTML

4.1.1 Was ist HTML?

  • HTML (Hypertext Markup Language oder zu Deutsch Hypertext Auszeichnungssprache)
  • HTML ist eine Beschreibungssprache für Webdokumente
  • HTML definiert ganz allgemein gesehen die Struktur eines Dokuments
  • Beispiel: Beschreibung an welcher Stelle ein Bild zu finden sein soll, wo Text ist und wie eine Tabelle strukturiert ist

4.1.2 Was kann HTML?

  • Hypertext Markup Language ist eine statische Sprache
  • das heißt, es ist keine echte Programmiersprache
  • aus diesem Grund bezeichnet man das Erstellen einer Seite nicht als „programmieren“ sondern „notieren“
  • HTML ist eine reine Struktursprache
  • es sind keine dynamischen Elemente wie bewegte Texte, Ausklappmenüs oder „fliegende Bilder“ integriert
  • aber: HTML bietet sehr gute Erweiterungsmöglichkeiten durch andere (dynamische) Sprachen wie PHP oder Java

4.1.3 Was braucht man für HTML?

  • zum Betrachten einer HTML-Seite benötigt man einen Web-Browser
  • Aufgaben eines Browsers:
    1. Einlesen des Dokuments
    2. Auswerten des Dokuments
    3. Anzeigen des Dokuments
  • Beispiele:
    • Internet Explorer
    • Netscape Navigator
    • Opera
  • Web-Dokumente selbst zu notieren ist sehr leicht und bedarf weniger Hilfsmittel
  • ein einfacher Texteditor reicht dabei aus
  • dies ist möglich, da HTML–Dateien reine ASCII-Dateien sind
  • mehr Komfort und eine große Hilfe bei größeren Projekten bieten spezielle Editoren
    • Vorteile von speziellen Editoren
      1. genaue Strukturierung
      2. Vorschau des erstellten Dokuments
      3. Syntaxhilfen (Erkennen von Schlüsselwörtern)
      4. Syntaxhighlighting
      5. Debugging mit Fehlererkennung
Beispiel für Browser und spezielle Editoren

browser.jpg editor.jpg

4.1.3 Elemente, Tags und der Syntax

Elemente
  • Elemente sind die wichtigsten Grundpfeiler von HTML
  • ein Element ist eine Einheit, die eine bestimmte Struktur oder Objekt darstellt
  • ein Element ist z.B. ein Bild oder ein Button, aber auch ein Absatz
  • HTML stellt viele Elemente zu Verfügung
Tags
  • ein Tag ist im Prinzip ein Element
  • Unterschied: Element ist die Gesamtheit eines bestimmten Bereiches und wird meist durch zwei Tags beschrieben
Syntax
<MeinElement> Ich bin Elementinhalt. </MeinElement>
  • mit dem ersten Tag beginnt auch der Bereich des Elements
  • ist der erste Tag (auch öffnender Tag genannt) abgeschlossen, folgt der Elementinhalt oder „Gültigkeitsbereich“
  • wird ein Elementinhalt abgeschlossen, folgt der zweite (schließende) Tag
  • bei manchen Elementen ist vorhersehbar, dass diese keinen Elementinhalt haben werden (z.B. bei Bildern, Buttons oder Zeilenumbrüchen)
  • aus diesem Grund gibt es Elemente, die nur einen Tag benötigen
  • diese werden auch „leere Elemente“ genannt
Das HTML "Grundgerüst"
<html>                   <!--HTML Eröffnungs-Tag-->
    <head>...</head>     <!--HTML Kopf (z.B. Name)-->
        <body>           <!--HTML Anweisungsteil-->
            ...
        </body>          <!--Ende Anweisungsteil-->
</html>                  <!--HTML Abschluss-Tag-->
Beispiele für HTML-Elemente
  • Bild mit definierter Höhe/ Breite einfügen:
<IMG SRC="PFAD" HEIGTH=X WIDTH=X>      <!--X=PIXEL-->
  • Hyperlink (URL/Datei) einfügen:
<A HREF="URL/DATEI">TEXT</A>
  • nummerierte Liste einfügen:
<OL><LI>....</LI></OL>
  • Tabelle einfügen:
<TABLE>....</TABLE>
  • Frames definieren:
<FRAMESET>...</FRAMESET>

4.2 Crashkurs PHP

4.2.1 Was ist PHP?

PHP (Akronym für „PHP: Hypertext Preprocessor“) ist eine weit verbreitete und für den allgemeinen Gebrauch bestimmte Open-Source-Skriptsprache, welche speziell für die Webprogrammierung geeignet ist, und in HTML eingebettet werden kann. Der Unterschied zu herkömmlichen Script-Sprachen ist die serverseitige Ausführung des Quellcodes

4.2.2 Was kann PHP?

  • PHP ist extrem simpel für Neulinge
  • es bietet einen riesigen Funktionsumfang für den professionellen Programmierer
  • es kann alles was andere CGI Programme können, wie z.B. Formulardaten sammeln, dynamische Inhalte für Websites generieren oder Cookies senden und empfangen
  • PHP kann auf allen gängigen Betriebssystemen verwendet werden, inkl. Linux, vielen Unix-Varianten (inkl. HP-UX, Solaris und OpenBSD), Microsoft Windows, Mac OS X, RISC OS
  • es unterstützt prozedurale, objektorientierte oder gemischte Programmierung
  • PHP bietet viele Bibliotheken und große Applikationen (inklusive der PEAR Bibliothek) exklusiv unter Verwendung von OOP-Code
  • PHP hat keine Beschränkung auf die Ausgabe von HTML
  • es erlaubt das dynamische Generieren von Bildern, PDF Dateien und Flash Animationen (mittels libswf und Ming)
  • bemerkenswerteste Stärke von PHP ist seine Unterstützung für eine breite Masse von Datenbanken (Adabas D, Ingres, Oracle (OCI7 und OCI8), dBase, InterBase, Ovrimos, Empress, FrontBase, PostgreSQL, FilePro (nur Lesezugriff), mSQL, Solid Hyperwave Direct, MS-SQL, Sybase, IBM, DB2, MySQL, Velocis, Informix, ODBC, Unix dbm)
  • PHP unterstützt auch die Kommunikation mit anderen Services, welche Protokolle wie LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (auf Windows) und unzählige andere
  • unterstützt auch eine CORBA-Erweiterung
  • auch die Instantiierung von Java Objekten wird unterstützt
  • …uvm

4.2.3 Was brauche ich für PHP?

  • zum Darstellen von PHP-Dateien muss bei Webservern die PHP-Unterstützung aktiviert sein
  • lokale Entwicklung von PHP: Installation eines Webservers, z.B.: Apache, PHP, MySQL
  • vorkonfigurierte Pakete sind oft frei downloadbar (z.B.: XAmpp)
  • dabei bietet die immer größer werdende Entwicklergemeinde guten Support, Userfreundlichkeit und eine sehr einfache Installation

4.2.4 Ein kleines Beispiel

Quelltext
<html>
    <head>
        <title>Ein PHP-Versuch</title>
    </head>
    <body>
        <?php
            echo "<p> Hallo Welt </p>";
        ?>
    </body>
</html>
Die Browserausgabe

browser2.jpg

5. Der Player

5.1 Systemvoraussetzungen

5.2 Installation

  • sicherstellen, dass alle vorausgesetzten Programme installiert sind (Systemvoraussetzungen).
  • Download: jukebox.rar [75kB]
  • Archiv entpacken
  • Verzeichnis beliebig umbenennen und in das Document-Root des Apache Webservers kopieren (Bsp: /srv/www/htdocs/jukebox)
  • _config.php konfigurieren

5.3 Konfiguration

  • _config.php (im Playerverzeichnis) in einem beliebigen Texteditor öffnen
  • _config.php:
<?php
//Verzeichnisse bitte alle ohne endenden '/' angeben
 
//Verzeichnis der MP3-Dateien
$mp3root='/usr/data/mp3';
 
//Verzeichnis der PHP-Dateien auf dem Server
$root='/srv/www/htdocs/jukebox';
 
//Pfad zum mpg123 Binary
$mpg123='/usr/bin/mpg123';
 
//Pfad zum id3v2 Binary
$id3v2='/usr/bin/id3v2';
?>
  • $mp3root - Pfad zu den MP3-Dateien (um später im Browser nicht in übergeordnete Verzeichnisse zu gelangen)
  • $root - Pfad zum Installationsverzeichnis im Directory-Root des Apache Webservers
  • $mpg123 - Angabe zum Ort des MPG123-Players
  • id3v2 - Angabe zum Ort des ID3-Tag Editors (optional)

5.4 Aufruf des Interfaces

jukebox.jpg

6. Quelltext

6.1 Modularer Aufbau

Um viele Seiten Quelltext überschaubar zu halten bietet es sich an, Software in einzelne Abschnitte zu gliedern und dementsprechend in gesonderte Dateien abzuspeichern. In PHP ist der Aufruf der jeweiligen Module mit der include()-Funktion möglich. In diesem Projekt wurde daher folgende Struktur angelegt:

  • [pix] - das Verzeichnis, in dem die Bilder für das Playerdesign gespeichert sind
  • path - hier wird der aktuelle Verzeichnispfad für den Filebrowser gespeichert
  • playlist - enthält die, in der aktuellen Playlist enthaltenen, Stücke in Textform
  • 6.2.1 style.css - Stylesheet-Datei für die farbliche Gestaltung
  • 6.2.2 _config.php - Konfigurationsdatei
  • 6.2.3 browser.php - Implementierung des Browsers
  • 6.2.4 id3.php - Auslesen der ID3-Tags
  • 6.2.5 index.php - Hauptseite
  • 6.2.6 player.php - aktivieren bzw. deaktivieren der Buttons im Player
  • 6.2.7 playlist.php - Verwaltung der aktuellen Playlist
  • 6.2.8 switch.php - entgegennehmen und verarbeiten der einzelnen Playerbefehle (Play, Stop, Skip…), Übergabe an Linux-Konsole
  • Grafische Darstellung zum Verständnis der Zusammenhänge:

module.jpg

6.2 Die Module

6.2.1 style.css

  • Beispiel zur Schriftgestaltung mit CSS:
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 12px;
font-variant: normal;
background-color: #CCA241;
  • Erläuterung:
    • font-family - Schriftart
    • font-size - Schriftgröße in Pixel
    • font-variant - Bsp: fett, kursiv, kapitälchen…
    • background-color - Hintergrundfarbe
  • Beispiel zur Gestaltung von Hyperlinks mit CSS:
a:link {color: #000000;}
a:visited {color: #123456;}
a:hover {color: #654321;}
a:active {color: #111111;}
  • Hyperlinks werden nun, je nach Status, verschiedenfarbig dargestellt

6.2.2 _config.php

6.2.3 browser.php

  • Der Filebrowser hat einen Parser integriert, der die über die Browserzeile übergebene Variable path in die für PHP verständliche Variable $getpath überführt und auswertet.
  • Codeauszug:
<?php
 
//ist die Variable "path" definiert?
if (!isset($getpath))
{
  //Pfad-Datei auslesen (hier wird immer der aktuelle Pfad in Textform gespeichert)
  $setq=file($root."/path");
 
  //ist in der Pfad-Datei kein Pfad enthalten?
  if ($setq[0]=='')
  {
 
    //öffne Pfad-Datei
    $setfile = fopen($root."/path", "w");
 
    //schreibe den in der _config.php angegebenen MP3-root-Pfad in Pfad-Datei
    fwrite($setfile,$mp3root);
 
    //Datei schließen
    fclose($setfile);
 
    //Verzeichniswechsel zum MP3-Root-Verzeichnis
    chdir($mp3root);
  }
  else
    {
      //ansonsten wechsele zum ausgelesenen Pfad
      chdir($setq[0]);
    }
}
?>
  • neue Tracks werden mit folgenden Hyperlinks in die Playlist übertragen:
for ($i=0; $i<=(count($filearr)-1); $i++)
{
  $playlistdir=getcwd();
  $addtitle=$playlistdir."/".$filearr[$i];
  echo "<a href=\"./index.php?action=add&addtitle=$addtitle\">$filearr[$i]</a>";
}
  • Erläuterung:
    • $filearr - enthält alle im aktuellen Verzeichnis befindlichen MP3-Dateinamen
    • $addtitle - setzt sich aus dem kompletten Pfad und dem jeweiligen Dateinamen zusammen
    • im Hyperlink werden dann alle notwendigen Informationen übergeben

6.2.4 id3.php

  • alle benötigten ID3-Tags werden mittels shell_exec() über die Kommandozeile ausgelesen
  • Beispiel:
<?php
shell_exec("id3v2 -l mp3datei.mp3 | grep -m 1 Title")
//Ausgabe: "Title: Mein Lied         Artist: Mein Künstler"
?>
  • für das o.g. Beispiel gibt shell_exec() einen String zurück, der dann folgendermaßen auf den Titel gekürzt wird:
<?php
//$title wird vorher festgelegt und enthält den Dateinamen
$out=shell_exec($id3v2.' -l '.$title.' |grep -m 1 Title');
 
//Stringteile vor dem ":" werden entfernt
$out=substr($out,strpos($out,':')+1);
 
//Stringteile ab "Artist" werden entfernt
$out=substr($out,0,strpos($out,'Artist:')-9);
 
//Ausgabe im Browser: "Titel: Mein Lied"
echo "Titel: ".$out;
?>

6.2.5 index.php

  • HTML-Dokument, in dem alle nötigen Scripte mit dem PHP-Befehl include() eingefügt werden
<html>
  <head>
    <title>Web MP3 Jukebox</title>
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
<body class="body">
  <?php
 
    //einbinden der Konfigurationsvariablen
    include("./_config.php");
 
    //abfangen der übergebenen Variablen
    $getaction=$_GET['action'];
    $gettitle=$_GET['title'];
    $getremtitle=$_GET['remtitle'];
    $getaddtitle=$_GET['addtitle'];
    $getpath=$_GET['path'];
 
    //wenn kein aktueller Titel gesetzt, dann = 0
    if (!isset($gettitle))
    {
      $gettitle=0;
    }
 
    //Auswerten der übergebenen Variablen
    include($root."/switch.php");
  ?>
 
  <!-- Haupttabelle Start !-->
  <table width="840" cellpadding="0" cellspacing="0" class="main">
 
    <!-- obere Zeile Start !-->
    <tr>
 
      <!-- Zelle oben links (Player) !-->
      <td width="420" class="border">
        <div></div>
        <?php include($root.'/player.php'); ?>
      </td>
 
      <!-- Zelle oben rechts (ID3 Informationen) !-->
      <td width="420" class="border">
        <div></div>
        <?php include($root.'/id3.php'); ?>
      </td>
 
    </tr>
    <!-- obere Zeile Ende !-->
 
    <!-- untere Zeile Start !-->
    <tr height="400">
 
      <!-- Zelle unten links (Playliste) !-->
      <td width="420" class="border">
        <div></div>
        <?php include($root.'/playlist.php'); ?>
      </td>
 
      <!-- Zelle unten rechts (Browser) !-->
      <td width="420" class="border">
        <div></div>
        <?php include($root.'/browser.php'); ?>
      </td>
 
    </tr>
    <!-- untere Zeile Ende !-->
 
  </table>
  <!-- Haupttabelle Ende !-->
 
</body>
</html>

6.2.6 player.php

  • Um eine Fehlbedienung und Missverständnisse zu umgehen, müssen die Buttons im Player, je nach Funktion aktiv oder inaktiv gestaltet werden.
  • folgender Codeauszug zeigt die Aktivierung des „Play“-Buttons bei einer vorhandenen Playliste, die Deaktivierung beim Status „spielt momentan ab“ und die Deaktivierung bei nicht vorhandener Playliste:
<?php
//Länge der Playlist<1? -> Bild für inaktiven Button
if (count($playlist)<1)
  { echo "<td width=\"85\"><img src=\"./pix/player_play_inact.jpg\"></td>"; }
 
//Player spielt gerade? -> Bild für "spielt gerade"-Button
elseif ($getaction=='play')
  { echo "<td width=\"85\"><img src=\"./pix/player_play_play.jpg\"></td>"; }
 
//alle andern Fälle -> Bild für aktiven button und Hyperlink,
//um den Player mit entsprechenden Parametern zu starten
else
  { echo "<td width=\"85\">
          <a href=\"./index.php?action=play&title=$gettitle\">
          <img src=\"./pix/player_play_act.jpg\" class=\"pix\">
          </a>
          </td>"; }
 
?>

6.2.7 playlist.php

  • die aktuelle Playlist wird in einer Textdatei (getrennt durch Zeilenumbrüche) gespeichert
  • einzelne Titel werden als Hyperlinks dargestellt, um das selektionsgebundene Abspielen zu ermöglichen
  • hinter jedem einzelnen Titel ist ein „x“ vorhanden, um diesen aus der Playlist zu entfernen
  • „remove all“ löscht die Playlist komplett
<?php
 
//Playlist aus Datei einlesen
$playlist=file($root."/playlist");
 
//Nummern für die Aufzählung bestimmen
for ($k=0; $k<=count($playlist)-1; $k++)
{
  $l=$k+1;
  if ($l<=9)
  {
    $l="0".$l;
  }
 
  //Nummern für die Aufzählung ausgeben
  echo "<tr width=\"30\"><td>".$l.'. </td>';
 
  //Pfadangabe aus dem String für die Dateinamen entfernen
  $listtitle=substr_replace($playlist[$k],'',0,strrpos($playlist[$k],"/")+1);
 
  echo "<td width="340">";
  if ($k==$gettitle) {echo "<b>";}
 
  //Link mit Zeiger auf den Titel und Dateinamen ausgeben
  echo "<a href=\"./index.php?action=play&title=$k\">$listtitle</a>";
  if ($k==$gettitle) {echo '</b>';}
  echo "</td>";
 
  //"X" zum entfernen des Titels mit Zeiger auf den Titel ausgeben
  echo "<td width=\"10\">
        <a href=\"./index.php?action=remove&remtitle=$k\" class=\"rem\">X</a>"
        ."</td></tr>";
 
}
echo "</table></td></tr>";
 
//falls Titel in Playlist vorhanden, "remove all" Button aktivieren
if (count($playlist)>=1)
{
  echo "<tr valign=\"bottom\"><td><br><p>
        <a href=\"./index.php?action=removeall\" class=\"rem\">remove all</a>
        </p></td></tr>";
}
?>

6.2.8 switch.php

  • wertet die Variable $getaction aus und steuert somit die einzelnen Befehle des Players
  • Auswertung mittels switch()
  • Codeauszug mit Beispiel für $getaction='play' (spiele Lied ab):
<?php
switch($getaction)
{
//[...]
case 'play':
 
//falls Player noch spielt, Prozess beenden
exec('killall mpg123');
 
//Playliste aus Datei in Array einlesen
$playlist=file($root.'/playlist');
 
//zu spielenden Title aus Array auswählen
$title=$playlist[$gettitle];
 
//Leerzeichen für die Übergabe an die Konsole entfernen
$title=str_replace(' ','\ ',$title);
 
//Zeilenumbrüche für die Übergabe an die Konsole entfernen
$title=ereg_replace("[\n\r]","\ ",$title);
 
//String zur Konsolenübergabe
$execstr=$mpg123.' '.$title.' 1>/dev/null 2>&1 &';
 
//Bsp: $execstr="/usr/bin/mpg123 /verzeichnis/kuenstler/lied.mp3 1>/dev/null 2>&1 &";
//zur Unterdrückung von Rückmeldungen der Konsole:
//"1>/dev/null 2>&1 &" (Browserfenster friert sonst ein)
 
//übergebe Zeichenstring an die Kommandozeile
exec($execstr);
 
//Ende "case" Bereich
break;
}
?>

7. Zusammenfassung

Die Entwicklung dieses Players war mit dem Hintergedanken verbunden, einen in unserer Studenten-WG bereits vorhandenen Linux-Router (ohne grafische Oberfläche, Monitor, Tastatur etc.) als Jukebox für Küche, Bad oder Flur zu betreiben. Nach intensiver Recherche im Internet fanden wir zwar zahlreiche Möglichkeiten, diese Aufgabe zu realisieren, jedoch erschien uns keine der Lösungen akzeptabel. Der Player sollte plattformunabhängig, von jedem Rechner im WG-Netz erreichbar und steuerbar sein. Ein Webinterface erschien also am einfachsten und für den nicht sonderlich leistungsstarken WG-Router am meisten ressourcensparend.

Die Suche nach geeigneten Konsolenprogrammen zum Apspielen der MP3-Dateien und zum Auslesen der ID3-Tags führte uns zu den o.g. MPG123 und ID3V2. Eine einfache Installation in das Linux System und die simple Handhabung waren dabei, für uns entscheidende, Suchkriterien.

Der Entwicklungsstatus des Players ist momentan auf einem Stand, in dem er problemlos erweitert und verändert werden kann. Ideen für weitere Module wären beispielsweise eine Anzeige der Länge der einzelnen Titel oder eine Art Schiebebalken, um an bestimmte stellen des jeweiligen Musikstückes zu „spulen“.

Alle hier vorgestellten Ausarbeitungen und Implementierungen dürfen frei heruntergeladen, bearbeitet und weiterverbreitet werden. Über ein Feedback von Interessenten und Entwicklern, die sich mit unserem Projekt beschäftigen, würden wir uns sehr freuen.

 
wiki/docs.musys.txt · Zuletzt geändert: 2008/10/07 16:09 von admin
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki