python + mplayer Problem mit Pfaden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nexusplanet
User
Beiträge: 2
Registriert: Samstag 6. Januar 2018, 18:16

Hallo Community.

Ein Bisschen Vorgeschichte:

Ich möchte einen kleinen Musik-Player auf Basis des Raspberry Pi bauen. Da ich zum Auslesen der GPIO's Python mit RPi.GPIO verwende wollte ich zur Steuerung des Players gleich bei Python bleiben. Als Player soll mplayer herhalten.
Ich habe die Pfade zu meiner Musik und zu Internet-Streams in seperaten Dateien hinterlegt, welche in etwa so aussehen:

Code: Alles auswählen

Amon Amarth
/home/user/music/Metal-Rock-Etc/Amon-Amarth/*flac
Children of Bodom
/home/user/music/Metal-Rock-Etc/Children of Bodom/*.flac
.
.
Hardbase.FM
http://listen.hardbase.fm/tunein-aacisdn-pls
usw.

Ich hole mir per linecache über die ungeraden lines den Artist, welcher auf einem 16x2 LCD ausgegeben wird und mit den geraden lines den Pfad.
Das sieht in etwa so aus.

Code: Alles auswählen

play_artitst = linecache.getline('./liste', gerade)
play_path = linecache.getline('./liste', ungerade)
Die Variablen gerade und ungerade werden per Knopfdruck um je 2 erhöht. So weit so gut. Beim abspielen klemmt es aber. Dazu verwende ich folgenden Code:

Code: Alles auswählen

subprocess.call(['mplayer', play_path])
Beim Internetradio ist alles fein, aber lokale Musik mag er irgendwie nicht. Es kommt immer die Fehlermeldung "File not found". Auch wenn ich statt play_path den Pfad direkt eintrage verweigert mplayer den Dienst. Was mache ich fasch? Bitte helft mir.

MFG

NeXuS

EDIT:

print.play_path gibt mir den Pfad (meiner Meinung nach) korrekt aus. Nur der Subprocess scheint ihn irgendwie nicht richtig verarbeiten zu können. Wenn ich den selben Pfad im Terminal mit mplayer Pfad eingeben klappt es auch.
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dein Problem ist, das die Shell fuer dich die Expansion macht, so das aus *.foo dann a.foo b.foo c.foo werden. Das macht subprocess von alleine allerdings nicht. Dazu musst du den Parameter shell=True uebergeben, dann sollte es klappen.

Noch besser waere es allerdings, wenn du die Liste der Dateien selbst erstellst, und dann konkret uebergibst. Das geht zB mit dem glob-Modul, das verarbeitet eben genau diese Shell-Argumente.

shell=True kann naemlich zu Sicherheitsproblemen fuehren, siehe https://stackoverflow.com/questions/317 ... subprocess
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: warum schlägst Du dann überhaupt »shell=True« vor?

@nexusplanet: Du hast Ersetzungzeichen in Deinen Dateinamen. Die werden nicht automatisch aufgelöst. Am Einfachsten geht das per »glob«:

Code: Alles auswählen

subprocess.call(['mplayer'] + glob.glob(play_path))
Zum Rest: warum verwendest Du »linecache« wenn ein einfaches Lesen der Datei auch reichen würde. Statt zwei Listen mit über den Index verknüpften Werten solltest Du eine Liste mit Tupeln als Inhalt verwwenden:

Code: Alles auswählen

with open("./liste") as lines:
    lines = (l.strip() for l in lines)
    playlist = list(zip(lines,lines))
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sirius3 hat geschrieben:@__deets__: warum schlägst Du dann überhaupt »shell=True« vor?
Und dadurch das ich das nicht erwaehne, und auch nicht auf die Risiken hinweise, findet er das irgendwann selbst und ist magisch davon abgehalten es zu benutzen?
nexusplanet
User
Beiträge: 2
Registriert: Samstag 6. Januar 2018, 18:16

Danke euch beiden für die schnelle Hilfe. Mit glob klappt es nun einwandfrei.

@Sirius3:

Danke für den Hinweis auf Tupel. Da es jetzt funktioniert werde ich vorerst bei meinen Listen bleiben, jedoch werde ich mir die Tupel Liste auch mal näher anschauen und bei Gelegenheit einbinden.

Vielen Dank :D
Antworten