Python: Befehl Senden, um mplayer unter-slave-Modus
Ich versuche zu senden-Befehl via pipe zu mplayer, wenn dieses unter-slave-Modus so:
import subprocess, time
# start mplayer
song = 'mysong.mp3'
cmd = ['mplayer', '-slave', '-quiet', song]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
# send a command every 3 seconds.
# Full command reference here: http://www.mplayerhq.hu/DOCS/tech/slave.txt
while True:
print('sleep 3 seconds ...')
time.sleep(3)
cmd = 'get_meta_artist'
print('send command: {}'.format(cmd))
p.stdin.write(cmd)
output = p.communicate()[0]
print(output)
Aber der Ausgang war nichts.
Nahm ich das Beispiel aus diese Frage.
Läuft die gleiche mplayer-Befehl im terminal funktioniert einwandfrei. Was vermisse ich hier?
UPDATE:
Änderte ich meine cmd aus "get_meta_artist" zu "get_meta_artist\n" so, dass ein Zeilenumbruch gesendet wird, um das Rohr als gut, aber noch habe ich nichts in der Ausgabe.
UPDATE2:
Änderte ich die cmd in "\npause\n" und die Musik unterbrochen wurde. Das bedeutet also, dass das senden-Befehl über stdin gearbeitet. Es bedeutet, dass der Ausgang Zeichenfolge "\nget_meta_artist\n" - Befehl nicht bekomme, geleitet Sie zurück, als erwartet....
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nur verwenden
.communicate()
einmal pro Teilprozess. So ist es auch in einemwhile
Schleife funktioniert nicht.Stattdessen sollten Sie analysieren die Ausgabe von
p.stdout
direkt. Es scheint, eine Zeile pro Antwort, wenn es eine Antwort.Um zu verhindern, blockieren, haben Sie 3 Möglichkeiten:
Arbeit mit threads. Sie haben einen separaten thread, der liest aus
p.stdout
und sendet seine Daten an den Haupt-thread. Es blockiert, wenn keine Daten zur Verfügung stellen.Set
p.stdout
auf nicht-blockierenden Modus. Im wesentlichen, Sie haben, dies zu tun:Wenn du das liest dann, ohne dass die Daten zur Verfügung stehen, bekommen Sie eine exception (
IOError: [Errno 11] Resource temporarily unavailable
).Arbeit mit
select.select()
: führenp.stdout.readline()
nur, wennselect.select([p.stdout], [], [], <timeout>)[0]
ist eine nicht-leere Liste. In diesem Fall, die gegebenen file-Objekt, das garantiert wird, um Daten verfügbar und nicht blockiert zu Lesen.Zu trennen, um "Müll-Ausgang" aus "nützlich" - Ausgabe, Sie könnten dies tun:
tun, und dann
Ich bin jetzt dabei, es zu tun auf diese Weise, und ich fange an, Ausgabe:
Obwohl ich immer noch brauchen, um herauszufinden, einen Weg zur Umgehung des first flush von mplayer eigenen Initialisierung stdout aber ich denke, dass mein problem gelöst.
Dank glglgl, dass Sie mir nützliche Hinweise.