AllesMeins: MP3-Stream von entfernten Server weiterleiten

Hi,

kann ich per PHP-Skript die Anfragen eines Programmes und die Serverantworten einfach 1 zu 1 durchleiten? Also wie eine Art Proxy. Mir geht es vor allem um MP3-Dateien. Ich möchte also das mein MP3-Spieler mit meinem Skript kommuniziert und von diesem genau die Antworten bekommt, die er auch bekommen würde, wenn er direkt den Server anfragen würde.

Wozu das ganze?
Ich bastele gerade an einem kleinen Script das mir nach speziellen Kriterien eine MP3-Playliste erstellt (zusammengesetzt aus der Musik auf diesem Rechner aber auch Files die über Podcasts reinkommen). Da es nur lokal läuft muss ich nicht auf Probleme wie übermäßigen Bandbreitenverbrauch etc. achten.

Ich hab nun folgendes Problem: Wie kann ich einen Playlisten-Eintrag erstellen der beim abspielen ein PHP-Skript auslöst? Dabei geht es mir speziell um Podcasts die ich gerne "blacklisten" würde, sobald sie mir einmal abgespielt worden sind (und wirklich erst dann und nicht wenn sie in die Playliste aufgenommen wurden). Meine Idee war es soetwas wie http://localhost/play.php?file=http://www.podcast.de/datei.mp3 in die Playliste zu schreiben. Wenn der Player dann diese Datei aufruft kann ich dort meine Blackliste schreiben und ihn dann an das externe MP3-File weiterreichen. Habe bereits ein paar Ideen ausprobiert, die aber alle nicht wirklich funktioniert haben:

1.) per header("location: " . $_GET['file']); einfach auf die Datei weiterzuleiten. Das macht der Player leider nicht mit (bin aus anderen Gründen auch auf diesen einen Player (alsaplayer) beschränkt - es bringt mir also nichts wenn andere Player das können. Gibt es weiterleitungsmöglichkeiten von denen der Player gar nichts mitbekommt? Mit der Header-Variante muss er ja selber aktiv werden

2.) per readfile() die Datei ausgelesen und zurück gegeben

2b.) per readfile() die Datei ausgelesen und noch einen Satz header mitgeschickt:
header('Content-type: audio/mpeg');
header('Content-length: ' . getFileSize($_GET['url']));
header('Content-Disposition: filename="dradio_stream.mp3"');
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');

getFileSize() ist eine Funktion die per fsockopen den Content-length-Header vom Server holt

Bei 2 und 2b spielt der Player die erste Sekunde oder so ab und "denkt" dann die Datei sei zuende. Wahrscheinlich weil PHP nicht schnell genug nachschiebt oder so.

Fällt euch noch irgendwas ein, wie ich das Problem lösen könnte? Möglichst so, das auch der zickigste Player nichts davon mitbekommt bzw. nichts besonderes dafür können muss?

  1. hi,

    header('Content-type: audio/mpeg');

    dieser header reicht vollkommen. Danach eine Leerzeile und dann den Stream.

    header('Content-length: ' . getFileSize($_GET['url']));

    Content-length ist ein header, der in einen POST-Request gehört. Nicht jedoch in eine Response.

    Bei 2 und 2b spielt der Player die erste Sekunde oder so ab und "denkt" dann die Datei sei zuende. Wahrscheinlich weil PHP nicht schnell genug nachschiebt oder so.

    Mach mal einen TCPDump (PCAP) dann siehst Du was geht.

    Hotti

    1. Content-length ist ein header, der in einen POST-Request gehört. Nicht jedoch in eine Response.

      Da möchte ich widersprechen. Zum einen sendet der Original-Server auch solch einen Header und er macht auch im Verhalten einen Unterschied. So wie es aussieht scheint zum Beispiel der mplayer das zu nutzen um abschätzen zu können wie lange die Datei ist. Ohne diesen header sagt er als noch verbleibende Länge "(undefined)".

      Aber wie dem auch sei, ich habe das Problem gelöst und es war echt einfach. Da hab ich den Wald vor lauter Bäumen nicht gesehen. Als ich mich eben wieder dran gesetzt habe dachte ich mir "Was machst du da eigentlich für nen Unsinn, liest die Header aus um die Content-Länge zu bekommen und baust dir dann damit deine eigenen Header. Total bescheuert" - Jetzt habe ich nichts weiter gemacht als die Header vom Original-Server direkt auszugeben und danach dann den Stream und das klappt.
      Manchmal braucht man echt etwas Abstand von so nem Problem.

      Trotzdem danke für die Hilfe!

      Und für die die es interessiert - die Header die ich jezt sende sind:

      HTTP/1.1 200 OK
      Server: Apache/2.2.9 (Debian)
      ETag: "4838-1a1600-483cd5fa49ac0"
      Accept-Ranges: bytes
      Content-Length: 1709568
      Content-Type: audio/mpeg
      Age: 15602
      Date: Sun, 11 Apr 2010 21:19:19 GMT
      Last-Modified: Fri, 09 Apr 2010 13:00:03 GMT
      Connection: close

      Marc

  2. hi,

    Bei 2 und 2b spielt der Player die erste Sekunde oder so ab und "denkt" dann die Datei sei zuende. Wahrscheinlich weil PHP nicht schnell genug nachschiebt oder so.

    Ähm, ja, das Problem kenne ich irgendwie. Gelöst mit Perl:
    binmode STDOUT;

    Hotti