Seite 1 von 1

Nur Schleife, nicht Programm beenden?

Verfasst: Mittwoch 13. August 2008, 18:19
von snafu
Hallo!

In einem kleinen Skript spiele ich alle Soundfiles ab, die ihm als Argument übergeben werden:

Code: Alles auswählen

import sys

import ao
import mad

def main():
    del sys.argv[0]
    for song in sys.argv:
        play(song)

def play(song):
    mf = mad.MadFile(song)
    dev = ao.AudioDevice('alsa')
    print 'PLAYING: %s' % song
    while True:
        buf = mf.read()
        if buf is None:
            break
        dev.play(buf, len(buf))

if __name__ == '__main__':
    main()
Ist es möglich, einen Song per Tastendruck "vorzuspulen", indem man "play" unterbricht, so dass der nächste Song startet? Noch besser wäre es natürlich, wenn er zur Laufzeit auf bestimmte Tastendrucks mit entsprechenden Aktionen reagieren würde. Ich plane so eine Art Mini-MP3-Player auf der Shell, aber eben ohne ncurses-Oberfläche, wie man es z.B. bei moc hat, sondern nur auf Kommandozeilenebene.

Verfasst: Mittwoch 13. August 2008, 18:42
von Hyperion
Naja, Du müßtest eben Tastatureingaben abfragen und dann entsprechend reagieren! Vermutlich geht das dann nur per Threads, also einen für das Abspielen und einen für das Warten auf Tastaturabfragen.

Verfasst: Mittwoch 13. August 2008, 18:54
von snafu
Kann jemand ein Modul empfehlen, das auf Tastatureingaben reagiert?

Verfasst: Mittwoch 13. August 2008, 19:04
von Hyperion
na curses z.B.

Ansonsten ist so was ja recht stark Plattform abhängig. Mag sein, dass es für WIndows speziellere Sachen gibt.

Verfasst: Mittwoch 13. August 2008, 19:20
von numerix
Kleine Anmerkung zu Zeile 7/8:
Es gibt keinen Grund, das erste Listenelement zu löschen. Du kannst beim Iterieren über die Liste einfach beim 2. Element beginnen:

Code: Alles auswählen

def main():    
    for song in sys.argv[1:]:
        play(song)

Verfasst: Mittwoch 13. August 2008, 19:20
von snafu
Sorry, aber wie funktioniert das denn? Ich habe mal "auf doof" das probiert:

Code: Alles auswählen

while True:
    if curses.has_key(97):
        break
Aber beim Druck auf 'a' tut sich nichts weiter.

Ansonsten werde ich wohl das übernehmen: http://snippets.dzone.com/posts/show/3084

Verfasst: Mittwoch 13. August 2008, 19:22
von snafu
numerix hat geschrieben:Kleine Anmerkung zu Zeile 7/8:
Es gibt keinen Grund, das erste Listenelement zu löschen. Du kannst beim Iterieren über die Liste einfach beim 2. Element beginnen:

Code: Alles auswählen

def main():    
    for song in sys.argv[1:]:
        play(song)
Jau, das hab ich gesucht, aber ich wusste nicht, wie ich es ausdrücken kann. Danke. ^^

Verfasst: Mittwoch 13. August 2008, 20:39
von Hyperion

Verfasst: Donnerstag 14. August 2008, 08:34
von snafu
Hi!

Irgendwie komme ich mit den Threads nicht klar. Ich mach hier wahrscheinlich voll das wirsche Zeug:

Code: Alles auswählen

import os
import sys
import termios
from threading import Thread
import time

import ao
import mad

def main():
    for song in sys.argv[1:]:
        play(song)

def play(song):
    getchar().start()
    mf = mad.MadFile(song)
    dev = ao.AudioDevice('alsa')
    print 'PLAYING: %s' % song
    while True:
        buf = mf.read()
        if buf is None or getchar() is 'n':
            break
        dev.play(buf, len(buf))

class getchar(Thread):
    def __init__(self):
        Thread.__init__(self)
    def run(self):
        fd = sys.stdin.fileno()
        if os.isatty(fd):
            old = termios.tcgetattr(fd)
            new = termios.tcgetattr(fd)
            new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
            new[6] [termios.VMIN] = 1
            new[6] [termios.VTIME] = 0
            try:
                termios.tcsetattr(fd, termios.TCSANOW, new)
                termios.tcsendbreak(fd,0)
                ch = os.read(fd,7)
            finally:
                termios.tcsetattr(fd, termios.TCSAFLUSH, old)
        else:
            ch = os.read(fd,7)
        return(ch)

if __name__ == '__main__':
    main()
Wäre nett wenn mir jemand helfen könnte. :)

Verfasst: Donnerstag 14. August 2008, 08:37
von Hyperion
Wie wäre es, wenn Du erst mal zwei primitive Threads erstellst, die nix weiter machen als irgend wie Zahlen auszugeben und die mal parallel ablaufen lässt. Dann bist Du fit, das ganze auf Dein Problem zu mappen.

Bist Du sicher, dass das while True in Zeile 19 überhaupt so funzt, wie Du Dir das vorstellst? Ich hege da meine Zweifel ...

Verfasst: Donnerstag 14. August 2008, 09:13
von snafu
Hyperion hat geschrieben:Bist Du sicher, dass das while True in Zeile 19 überhaupt so funzt, wie Du Dir das vorstellst? Ich hege da meine Zweifel ...
Ja, das klappt. Ging ja in der anfänglichen Version auch problemlos. So ganz bin ich da ehrlich gesagt noch nicht durchgestiegen (hatte das aus einem Beispiel übernommen), aber ich vermute er spielt Frame für Frame ab und wenn buf halt kein Frame mehr liefert, wird die Schleife beendet.

Das mit den Threads werde ich mir nochmal genauer ansehen.

Verfasst: Donnerstag 14. August 2008, 15:05
von Hyperion
snafu hat geschrieben: Ja, das klappt. Ging ja in der anfänglichen Version auch problemlos. So ganz bin ich da ehrlich gesagt noch nicht durchgestiegen (hatte das aus einem Beispiel übernommen), aber ich vermute er spielt Frame für Frame ab und wenn buf halt kein Frame mehr liefert, wird die Schleife beendet.
Ach so, ja, das klingt plausibel!