mpg123 über python steuern

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,

    Ich bin leider totaler Anfänger, deshalb bitte Entschuldigung, falls das Problem schlecht beschrieben ist!

    mein Raspberry soll MP3-Dateien automatisiert abspielen. Ich starte dazu mit Python über os.system("mpg123 meinedatei.MP3") die Wiedergabe. Das Problem: Die Kommandozeile springt jetzt in einen Modus, in dem sie keine Befehle mehr annimmt und ich kann die Wiedergabe nicht mehr steuern oder abbrechen.

    Alternativ habe ich versucht, die Wiedergabe mit dem Parameter -C zu starten. Jetzt kann ich per Tastatur die Wiedergabe steuern, aber die Befehle, die ich von Python absetze, kommen trotzdem erst an, wenn ich den Player manuell beendet habe.

    Weiß jemand, woran das liegt? Ich bin für jede Hilfe dankbar!
    Gruß, Semimemi

    Einmal editiert, zuletzt von semimemi (16. März 2014 um 20:28)

  • Hallo,

    habe ich auch probiert. Nach drei Tagen Probieren habe ich entnervt aufgegeben:

    Grundsätzlich kannst Du von Python aus per stdin Tastendrücke ins mpg321 reinschreiben und per stdout rauslesen, manche Informationen kommen auch per stderr. Das Problem: sie blocken sich gegenseitig und per flush() soll man sie aufheben können, das klappt aber nicht - Hier werden die Einschränkungen erläutert. Hier sind noch viele weitere Möglichkeiten erläutert, die aber auch alle nicht geklappt haben, weil mpg321 die Ausgaben offenbar nicht richtig flusht oder Python das nicht mitbekommt.

    Was ist die Lösung? pygame kann fast alles, was mpg321 auch kann - mal abgesehen vom Abspielen von mp3-Streams.

    Gruß,
    Arne

  • Danke für die schnelle und kompetente Antwort! Leider ist genau das mein Ziel: Internetradio abzuspielen, als MP3-Streams. Ich bin also über alle weiteren Tipps dankbar: Gibt es eine andere alternative Software mit der das geht? Oder einen Workaround, um das doch mit mpg123 hinzubekommen?

  • Hi,

    Hier gibt einen Haufen Tipps, am vielversprechendsten finde ich diese Anleitung, ich will es aber als Konsolenapp haben, deswegen finde ich das benötigte GTK nicht gut.

    Vielleicht könnte man aber auch einfach pygame auf eine Webressource umleiten: Pygame nimmt nicht nur einen Dateinamen, sondern auch ein Fileobjekt. Das magische Wort ist makefile des Socket-Objekts. Socket ist aber low-Level, d.h. erklärungsbedürftig, unpraktisch und vermutlich kompliziert. Was ich jetzt mal probieren wollte:
    - Socket zum Streaming-Server öffnen,
    - einen HTTP-Get-Request zusammenbauen,
    - an den Socket senden,
    - dann das Ergebnis mit makefile() zum File-Objekt machen und
    - schließlich dem pygame unterjubeln.
    Ich weiß nur nicht, was mit dem Kram passiert, den der Server vor dem eigentlichen File sendet - wird pygame ihn ignorieren oder zu Fall bringen?

    Melde mich, sobald ich es probiert habe...

    Arne

  • Hallo,

    meine Idee war gar nicht so schlecht, hat auch für Downloads auf Anhieb geklappt, für Streams aber nicht. Warum? Der Pygame.Mixer erkennt im laufenden Stream die MPEG-Frames nicht, versteht nicht, dass es sich um MP3 handelt, und meckert rum, dass er das Format nicht kennt.

    Ein MP3-File beginnt immer mit der Zeichenkette "ID3" und chr(3) - das muss man dem Socket beim ersten Zugriff des Pygame-Mixers untermogeln, dann klappt auch das Abspielen des Streams. Hier mein Beispiel (klappt bei mir mit SWR3). Ich habe die mp3streamfile-Klasse dem File Object (echt schlecht beschrieben in der Python-Doku) nachempfunden, die Attribute des Originals braucht man alle nicht und von den Methoden auch nur eine Handvoll.

    Was passiert? Ich lege ein mp3streamfile-Objekt an, das erst mal den Zugriff auf den Stream klar macht. Wenn wir das in pygame reinstecken und abspielen, wird mit "read" gelesen. Da liefern wir grundsätzlich den Stream aus, außer bei den ersten beiden Reads, da manipulieren wir das "ID3" rein. Und voila, schon versteht Pygame den Stream.

    Ein paar Sachen sind aber doch merkwürdig: pygame verwendet gar nicht Iterator- und Next-Methode. Und wenn man ihm bei "Tell" (was ist meine Position im MP3) eine 0 zurückgibt, dann schluckt er das reibungslos. Das hatte ich ja nun nicht erwartet...

    Spannend wird die ganze Geschichte dann noch mal, wenn man das Abspielen in einen Thread verlagert und die Steuerung in einen anderen. Ob der zum File gemachte Socket mitsamt Hack threadsafe ist?

    Nächste Aufgabe wird auch sein: Wir sollten aus dem Stream den Titel und Interpreten zur Anzeige herauslesen.

    Gruß,
    Arne

  • Arne, ich bin beeindruckt! Dein Quellcode funktioniert bei mir (allerdings erst, nachdem ich alle Einrückungen neu gemacht habe - keine Ahnung, was da gestört hat.) Leider bin ich aber in der Materie überhaupt nicht drin und verstehe nicht wirklich, was da passiert. Ich fürchte, dass mich mein Projekt trotz deiner klasse Hilfe überfordern wird.

    Trotzdem erstmal großen Respekt und vielen Dank!

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!