Nur Schleife, nicht Programm beenden?

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
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Zuletzt geändert von snafu am Mittwoch 13. August 2008, 18:50, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Kann jemand ein Modul empfehlen, das auf Tastatureingaben reagiert?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

na curses z.B.

Ansonsten ist so was ja recht stark Plattform abhängig. Mag sein, dass es für WIndows speziellere Sachen gibt.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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. ^^
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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. :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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 ...
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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!
Antworten