PHP Winamp durch counter.php schleifen, Stream öffnet leider nicht!

Belee

Lt. Commander
Registriert
Dez. 2006
Beiträge
1.518
Hallo Leute

Habe hier ein kleines Problem mit meinem Counter für die Streamplayer z.B. Winamp.
Problem ist, gibt man in Winamp den PHP-Streamlink ein...

HTML:
http://www.discoradioaction.eu/stream/player.php?id=winamp

Wird der Klick registriert und der Zähler in der Texdatei erhöht, das Problem ist aber das
Winamp den Stream nicht öffnen kann, Meldung "Fehler beim Synchronisieren".

Der Counter (player.php)
PHP:
 $file = file("data/links.txt");
   foreach($file as $line) 
{
 list($id,$url) = explode("|",$line);
  $down[$id] = $url;
}
 if(empty($_GET['id'])) 
{
 Header("Location: http://www.discoradioaction.eu");
} 
else 
{
 if(empty($down[$_GET['id']])) 
  {
 Header("Location: http://www.discoradioaction.eu");
} 
 
 Header("Location: ".$url);
 $id=$_GET['id'];
 $date = date("d.m.y");
 $time = date("H:i");
 $countfile="data/counter.txt";  
 $treffer=FALSE;  
 $file = file($countfile);
 $fd=fopen($countfile,"w+");    
 foreach ($file as $line) {
 $exp_line = explode("|", $line);
 if ($exp_line[0] == $id) {
 $count=$exp_line[1];
 $count++;
 $new_line = "$id|$count|$date|$time\n";
 fputs($fd, $new_line);
 }
 else {
 fputs($fd, $line);
 }
}
 fclose($fd);
}

Und die Textdatei in der die richtige URL eingetragen ist (links.txt)
HTML:
winamp|http://www.discoradioaction.eu/stream/disco.m3u|

Das ganze kann man sich hier anschauen:
http://www.discoradioaction.eu

Zurzeit ist nur der Winamp Player verlinkt. Wenn man das ganze über die
Webseite macht funktioniert es, kopiert man aber den Counter-Link in Winamp wird
der Count zwar erhöht aber der Stream nicht geöffnet.

Ist das Pech und es geht so nicht oder habe ich da etwas vergessen im Script?
Falls es so nicht geht könnte ich für jeden Player und Stream einen seperaten
Counter machen nur wie schleife ich den Winamp durch die counter.php wenn
diese direkt in Winamp eingetragen wird?

Danke.

Gruß
Belee
 
Zuletzt bearbeitet:
Evtl. kommt Winamp nicht mit der "Header:"-Weiterleitung klar. Wieso gibst du denn nicht einfach direkt den Inhalt aus sondern machst das über eine Browserweiterleitung?
 
Gute Frage @BerniG, ich denke weil ich es nicht anders kann/nicht hinbekomme :)
 
Einfach
Code:
echo file_get_contents("disco.m3u");
sollte den Inhalt ausgeben (evtl. musst du mit den Pfaden noch schauen; man könnte auch eine HTTP-URL angeben aber das ist performancetechnisch Schachsinn weil man dann nicht auf die Festplatte direkt zugreift sondern nochmal nen HTTP-Request macht). Ich gehe ja mal davon aus, dass die m3us sowieso alle bei dir auf dem Server liegen oder?
 
Hey BerniG, das wäre echt zu einfach, das kann aber nicht funktionieren. Mein Fehler weil ich im Eingangsposting halt noch ein altes Script gepostet habe.

Das Script startet einen Player via ID also script.php?id=winamp oder wmp oder pls oder real
Die richtigen Links stehen in einer Textdatei mit ID, das Script holt sich also aus dieser den richtigen Link, wenn also id=winamp kommt dann wird der Link für Winamp genommen usw.

Das Header bekommt ja mit $url den Link der per ID= gekommen ist, und es wird dann sofort weitergeleitet und nicht erst gewartet bis das Script den Hit geschrieben hat, ich schleife die Player einfach nur schnell durch das Script um an die ID=winamp oder =wmp usw. zu kommen.

Und hier ist auch das Problem, wenn ich so einen Link auf der Seite anklicke ist alles ok, die Player starten mit der richtigen Streamdatei also Link, wenn ich aber den Link direkt in Winamp kopiere dann wird der Hit gezählt aber Winamp bleibt mit Fehlermeldung von wegen kann nicht Synchronisieren stehen. Ich denke das geht einfach nicht wenn man es direkt in Winamp eingibt weil Winamp ja kein PHP versteht, auf der Webseite muss er das ja nicht weil das dort nachdem man auf den Link geklickt hat per Header sofort die richtige Adresse kommt und Winamp dann ja sofort die m3u bekommt.

Oder aber ich habe einen Denkfehler :)
 
Also ich wüsste nicht wieso das nicht grundsätzlich funktionieren sollte. Hast dus denn überhaupt probiert? Du musst natürlich das "disco.m3u" noch dynamisch machen indem dus in deine Textdatei einbaust aber das sollte ja kein Problem sein.

Dass Winamp kein PHP versteht ist klar aber PHP wird auf dem Webserver ausgeführt und nicht im Client des Users. Der Client sieht nur HTML bzw. HTTP-Header und in dem Fall wird Winamp eben wie gesagt die Weiterleitung per "Header" nicht mögen. Daher muss dann eben direkt in dem Script die m3u-Datei ausgegeben werden.
 
Klar hab ich, ich teste immer was ihr hier postet, wenn ich dann einen Link auf der Seite anklicke öffnet sich eine weiße Seite in der dann die URL aus der Textdatei steht.
Also zB. ... http://www.discoradioaction.eu/stream/player/disco.m3u
Klicke ich einen anderen Link an zB. einen für Windwos Media, dann dito aber mit dem Link von WMP.

Ich teste jetzt mal mit Winamp direkt ..... mal sehen ob es am Header lag..

Test beendet: liegt nicht am Header, auch so gibt es eine Fehlermeldung im Winamp
 
Zuletzt bearbeitet:
Also, Punkt 1:
Dein Script von oben, Belee, kannste getrost in die Tonne kloppen. Warum? Ganz einfach: Du willst den Besucher an zwei Stellen weiterleiten - einmal an den Stream, danach an den Counter. Problem: Du kannst den user nur 1x (!) weiterleiten. Das ist der Sinn hinter header("Location: xyz.de").

Punkt 2:
Eine Header-Weiterleitung funktioniert nur im Browser und in Programmen, die extra so geschrieben wurden diese Weiterleitung zu verstehen. Und ein Musikprogramm kann datt in der Regel nicht, ich kenne da nicht ein Programm, welches das kann.

Punkt 3, insbesondere @BerniG
Es ist chwachsinnig einfach "echo file_gets_contents($textdatei)" ohne irgendwelche anderen Infos ausgeben zu wollen, denn dann wird ein simpler HTTP-Header gesetzt, den wiederum nur der Browser, nicht aber ein anderes Programm interpretieren kann. Und selbstredend (!) wäre dies eine stinknormale Echo-Ausgabe, eine M3U ist aber keine einfache HTML-Datei. Eine M3U muss jedoch vom Musikprogramm heruntergeladen werden. Und nirgends wird der Browser darauf hingewiesen die Daten zum Download bereit zustellen. Dumm gelaufen.

Lösung:

PHP:
<?php
// der Einfachheit halber... ggf. auch noch weitere Checks der Variable durchführen!
$id = $_GET["id"];

// Textdatei braucht gar nicht erst eingelesen werden, wenn ID nicht gegeben.
if(empty($id)) die("ups, keine ID angegeben!");

// oder alternativ:
#if(empty($id)) header("Location: domain.de");

// Textdatei einlesen:
$file = file("data/links.txt");
foreach($file as $line):
    list($stream,$url,$filename)    = explode("|",$line);
    $streamlist[$stream]            = array("url" => $url,
                                            "filename" => $filename
                                       );
endforeach;

// check, ob ID in der URL-Liste vorhanden ist
if(!array_key_exists($id,$streamlist)) die("ups, die angegebene ID ist nicht in der Steamliste!");

// oder alternativ:
#if(!in_array($id,$urllist)) header("Location: domain.de");


//
// HIER könnte dann z.B. auch noch dein Steamcounter eingebunden werden!
//


// And here comes the trick:
// korrekten Header setzen!
header("Content-Type: audio/mpegurl");
// Dem browser sagen, dass es eine Datei ist, die heruntergeladen werden soll!
header("Content-Disposition: attachment; filename=".$streamlist[$id]["filename"]);

// von mir aus auch noch die anderen Daten der aktuellen m3u davor:
echo <<<out
#EXTM3U
#EXTINF:5,Welcome To Disco Radio Action
http://www.discoradioaction.eu/stream/welcome.mp3
#EXTINF:-1,Main Stream
out;

// Steamlink ausgeben!
echo "\r\n".$streamlist[$id]["url"]."/".$streamlist[$id]["filename"];

// zur Sicherheit Script beenden
exit;
?>

In der Textdatei steht dann folgendes:

Code:
winamp|http://stream.laut.fm|disco.m3u
wmp|http://www.discoradioaction.eu/stream|disco2.m3u

Theoretisch müsste man auch noch die korrekte Dateilänge mit ausspucken, aber bei solch kleinen Dateien ist des nicht so wichtig wie bei Dateien, die mehrere MB tragen.
 
Zuletzt bearbeitet:
Und das funktioniert? hast du das probiert? ich kann dann folgende Adresse direkt in Winamp eintragen /player?id=winamp ?
Jetzt nur zur Versändigung, wenn ich auf der Seite so einen Link anklicke funktioniert es ja, nur halt nicht wenn ich den Link in Winamp direkt eintrage verstehst du?

die Streamfiles sind aber nicht immer "m3u" sondern,
Winamp = m3u
WMP = asx
Real = ram
Sonstige = pls

Das Script von oben wurde wegen dem Counter umgebaut, das sieht jetzt so aus:

PHP:
<?php
  $whitelist = array(
  'ex_di_wnp','ex_di_rlo','ex_di_wmp','ex_di_pls','ex_di_flh',
  'ex_it_wnp','ex_it_rlo','ex_it_wmp','ex_it_pls','ex_it_flh',
  'ex_os_wnp','ex_os_rlo','ex_os_wmp','ex_os_pls','ex_os_flh',
  'in_di_wnp','in_di_rlo','in_di_wmp','in_di_pls','in_di_flh',
  'in_it_wnp','in_it_rlo','in_it_wmp','in_it_pls','in_it_flh',
  'in_os_wnp','in_os_rlo','in_os_wmp','in_os_pls','in_os_flh',);
 
     $streamlinksPath = 'data/links.txt';
     $counterPath = 'data/counter.txt';
     $filelockPath = 'data/counter.lock';
     $writeRetries = 100;
     $streamID = trim($_GET['id']);
 
     $streamURL = false;
     if ($streamID !== "" && in_array($streamID, $whitelist)) {
   if (($streams = file($streamlinksPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)) !== false) {
 
     foreach ($streams as $stream) {
  list($t_streamID, $t_streamURL) = explode('|', $stream);
  if ($t_streamID === $streamID) {
  $streamURL = $t_streamURL;
  }
 }
 
     if ($streamURL !== false) {
 
   for($i=0,$written=false; ($i<$writeRetries && $written===false); $i++) {
 
    if (!file_exists($filelockPath) || @unlink($filelockPath)) {
 
        if (($filelockHandle = @fopen($filelockPath, 'xb')) !== false) {
 
         if (($counterLines = file($counterPath, FILE_SKIP_EMPTY_LINES)) !== false) {
 
   $written = true;
   @unlink($counterPath);
   $rand = rand();
   $counterHandle = fopen($counterPath . $rand, 'w');
 
   foreach ($counterLines as $line) {
   $expLine = explode('|', ltrim($line));
 
   if ($expLine[0] === $streamID) {
   $count = intval($expLine[1]) + 1;
   $line = $streamID . '|' . $count . '|' . date('d.m.y.') . '|' . date('H:i') . "\n";
     }
  fputs($counterHandle, $line);
  }
  fclose($counterHandle);
  rename($counterPath . $rand, $counterPath);
  fclose($filelockHandle);
  @unlink($filelockPath);
   }
 }
  }
}
  header('Location: ' . $streamURL);
  header('Cache-Control: must-revalidate, pre-check=0, no-store, no-cache, max-age=0, post-check=0');
   exit();
      }
   }
}
        header('Location: http://www.discoradioaction.eu');
         exit();
?>

So bleibt jetzt die Textdatei in der die Hits drin stehen ganz wenn viele Zugriffe stattfinden, zumindest bis jetzt.
Und du meinst ich kann dieses Script jetzt nochmal umbauen damit das mit dem durchschleifen direkt über den Player funktioniert?

Wichtig ist dann also nur das der Player korrekt weiter geleitet wird richtig? nur wo jetzt in diesem Script muss ich das anstellen weil das ist jetzt schon eine Hausnummer zu hoch für mich, da wo die headers stehen? die müssen ja beide den Player weiterleiten auch wenn der Counter mal nicht schreiben kann.
 
Ach verdammt, ich hab da ganz was vergessen, das was ich wollte ist noch gar nich fertig lol^^ Denn eine ganz wichtige Sache fehlt noch, denn ohne das funzt auch mein Script da nicht^^

Du hast 3 Möglichkeiten, eine sehr elegante, eine leicht weniger elegante und eine ganz unelegante, je nach dem, welche Methode du anwenden kannst.

Methode 1, die unelegante:
Du gibst dem Link einen weiteren GET-Parameter ganz am ENDE, so:

Code:
http://domain.de/stream.php?id=winamp&dummyvariable=stream.m3u

Ganz wichtig ist eben, dass dieses .m3u am Ende steht und nicht mittendrin. Winamp (ich weiß nicht wie des bei anderen Mediaplayern ist) ist schlicht und ergreifend zu dumm zu checken, dass die Anfrage an ein PHP-Script geht. Aber: So funktionierts, wenn folgende Methoden nicht funktionieren.


Methode 2 - Der Ordnertrick
Leider ist des auch nicht ganz so flexibel und es macht deine Streamliste überflüssig (wobei du die Streamlisten-Textdatei auch woanders platzieren kannst und dann den Code entsprechend anpasst), weil du pro Ordner sowieso nur einen Stream abfragen kannst. Gehen wir davon aus, dass du schon einen Ordner namens "stream" erstellt hast, dann erstellst du in diesem Ordner einen weiteren namens "winamp.m3u" - ganz wichtig ist der Punkt vor dem m3u!

In diesen Ordner platzierst du mein Script und nennst es index.php - ganz wichtig! Wie gesagt, entweder packste die Streamliste irgendwo anders hin, und setzt die $id statt auf $_GET["id"] eben auf "winamp" oder schreibst den Streamlink direkt unten in die PHP-Datei, whatever, wie es dir gefällt

Verlinken tust du den Stream dann wie folgt:

Code:
http://domain.de/stream/winamp.m3u

Grund, warum das funktioniert: Winamp weiß nicht, dass das ein Ordner ist. Der Webserver jedoch sieht, dass das keine solche Datei existiert, sondern ein Ordner mit diesem namen. Da der Webserver so eingestellt ist, dass entweder eine index.html oder eine index.php aufgerufen werden soll, wenn keine direkte Datei in der URL aufgelistet ist, nimmt der Webserver automatisch das Index-Dokument und gibt dessen Inhalt aus.

Du müsstest halt für jeden Steam, den du anbietest, einen solchen Ordner anlegen. Ist halt aber nicht so elegant, wie folgende Methode.

PS: Dieser Trick funktioniert übrigends auch ganz ganz prima für dynamische, per PHP generierte Bilder als Forensignatur! Foren checken in der Regel die Dateiendung, ob das per -Tag eingebundene Bild auch wirklich eines ist, bei .php wird eine Einbindung verboten. Das umgeht man mit diesem Trick hier, einfach den Ordner "signatur.jpg" erstellen, dort eine index.php hinein und schwupps kann man sich via PHP dynamische Signaturen erstellen lasse ;) Vll ganz nett für dein Radio!

[B]Methode 3 - die Elegante[/B]

Wenn du mod_rewrite nutzen kannst, dann ist DAS für dich das non-plus-ultra. Du musst dir eine .htaccess-Datei mit folgendem Inhalt anlegen:

[code]
RewriteEngine On
RewriteBase /

RewriteRule ^stream/([a-z]+).m3u$ /stream.php?id=$1
[/code]

Verlinken tust du dann den Stream wie folgt:

[code]http://domain.de/stream/winamp.m3u[/code]

Zur Erklärung: mod_rewrite ist ein URL-Rewriter, kann also eine URL eines bestimmten Formates in ein passendes Format wandeln. Des wird gerne bei Blogs, bei manchen Foren und auch bei der Computerbase auf der Startseite bei den News genutzt - sogenannte SEO-Urls, suchmaschinenfreundliche URLs. Der Code ([a-z]+) sagt dem Webserver, dass alle Zeichen (von a bis z) zwischen / und dem . als Variable an das aufzurufende PHP-Script weitergeben soll. Im Beispiel wärens die Zeichen "winamp".

Du kannst beim mod_rewrite natürlich herumspieln wie du blöde bist, zahlen erlauben, weitere Parameter hinzufügen:

[code]
RewriteEngine On
RewriteBase /

RewriteRule ^stream/([a-z]+)-([0-9]).m3u$ /stream.php?id=$1&stream_mirror=$2
[/code]

Mit der Methode biste jedenfalls am freiesten, behälst deine Übersicht.


So, das warn die drei Methoden, eine von denen brauchste aber nur. Weiß ja nicht, wie gut dein Webspace ausgerüstet ist, aber mindestens eine davon funktioniert auf jedenfall.


//Edit
Ahm, nochmal zu deiner Frage da... Ja, der Counter kann DIREKT in mein Script mit eingebaut werden, da brauchste dann auch NICHT mit einer Headerweiterleitung zu arbeiten, sondern zählst direkt bei Aufruf dieser Stream.php den Hit. Suchmaschinen werden diese Datei in der Regel nicht aufrufen, schätze ich mal, eben wegen der Dateiendung ".m3u". Hochwichtig ist blos, dass du PHP dazu zwingst keine Fehler auszugeben, denn dann funktioniert das Senden der Header auch nicht (oder du nutzt output buffering). Eleganter ist:

[code]error_reporting(0);[/code]

Das am Anfang der Datei. Die Dateiheader setzt du am Ende des Scripts - ich hab dir im Codebeispiel oben ja als Kommentar hingeschrieben, wo du deinen Counter platzieren kannst ;) Wenn der Counter mal NICHT schreiben kann, ist es nicht schlimm, solang error_reporting deaktiviert ist - du musst nur zusehen, dass das Script nicht in einer Schleife läuft (darum wäre eine Datenbank auch absolut besser geeignet).

Jedenfalls, das ganze funktioniert dann selbstredend auch von Winamp aus, wenn der Steamlink genau so aufgerufen wird. Allerdings ist mir aufgefallen, dass Winamp sich die beiden Links aus der M3U herausholt und genau diese Links dann auch für die Playlist verwendet, statt des einzelnen Links zur .m3u ...

Und ja - du kannst natürlich statt .m3u auch .pls und co verwenden, du musst halt nur die Ordnernamen, Variablen oder die Zeile RewriteRule in der .htaccess dublizieren und statt .m3u eben .pls einsetzen^^


Hoffe, ich konnt dir helfen - lies es dir am besten ein paar mal durch.


// Nachtrag 01.10. 12:47 Uhr

Mir ist noch eingefallen, dass du in meinem Script bei

[php]header("Content-Type: audio/mpegurl");[/php]

das audio/mpegurl eventuell für andere Dateiendungen als .m3u ändern musst, da müssteste bei Google mal suchen wies für .pls usw ist und dementsprechend dann das Script bei der Header-Ausgabe noch anpassen.
 
Zuletzt bearbeitet:

Ähnliche Themen

Zurück
Oben