Sounddateien in Schleife abspielen

  • Hallo,

    ich habe ein Programm geschrieben, bei dem Sounddateien per rfid-reader gestartet werden.

    Alles funktioniert so weit. Es gibt allerdings ein Problem.

    Sobald eine Datei rfid gscannt wird während eine Sounddatei noch nicht zu Ende abgespielt wurde pipst das Gerät länger und das Programm stürzt ab.

    Ich brauche irgendwie eine Idee, wie das Programm pausiert bis die Sounddatei zu ende abgespielt wurde.

    Hat jemand eine Idee dazu?

    lg

    FrauBerry

  • Moinsen,

    Entschuldige, in deiner Themenüberschrift und deinem Anfragtext steckt ein Widerspruch.
    Entweder es ist eine Endlosschleife, dann gibt es kein Ende, oder ?

    Ich würde es von der Programmlogik her so aufbauen, ohne das ich schon mit Playsound oder was du verwendest gearbeitet habe:

    Einen Hintergrund-Thread für die RFID Abfrage starten, mit einen Übergabeparameter falls eine RFID bedingte Änderung eintritt. Damit das ganze nicht als Polling in einer Endlosschleife herum quirlt.
    Die RFID Kennung - Titelzuordnung würde ich zumindest im Ansatz über einen Dictionary bewerkstelligen.
    Bei größeren Listen dann sogar über eine '\t' formatierte Konfig-Datei, die man problemlos in jedem Editor anpassen und ändern kann.
    Über diesen Rückgabewet, nun weiß ich nicht wie das bei dir gestrickt ist, über einen Merker den Player veranlassen, den Titel noch zu Ende abzuspielen oder zu stoppen, um dann erst den neuen Titel wiederzugeben.

    Franky

    Franky

  • Danke für die Antwort, das mit dem Dictionary schaue ich mir an.

    Jetzt muss aber zuerst dieser Fehler ausgebessert werden. "Merker" an so etwas habe ich auch gedacht und ein Beispiel mit sleep gefunden, allerdings funktioniert das bisher nicht.

    Code
    Die Ausgabe:
    
    time.sleep(f.duration)
    AttributeError: 'Wave_read' object has no attribute 'duration'
  • Moinsen,

    Unter einem Merker versteht man eine Variable die einen Boolchen Inhalt , also nur die zwei Werte "True" und "False" kennt.
    Damit wäre das dann so, daß mit dem neu eingelesenen RFID-Wert / oder -Kennung zu einem geprüft wird ob sich der RFID Wert zum aktuellen noch in Verarbeitung befindlichen geändert hat. Ist es nun eine andere ID setzt man den Merker, entweder auf True oder False, je nachdem wie man die Abfrage gestaltet. Damit kannst du dann in deinem Programm die Entscheidung treffen, wenn der Merker eine Wert hat, der Zum Abbruch führen soll, dann wir als erstes der PLAY_STOPP Befehl ausgegeben. ( Falls das Möglich ist, oder gesagt wenn du mit dem Weidergabedurchlauf fertig bist hörst du auf )
    Nur mal zur Erklärung.
    So und nun startest du über den:

    Damit kannst du dir die gesamten IF Abfragen ersparen.
    Recht einfach. Jetzt mußt du natürlich noch die Abfrage Programmieren, und die neue ID mit dem akt. eingelesen ID vergleichen. In dem Falle wenn eine neue andere ID eingelesen wurde mußt du den Merker auf TRUE setzen.
    Ich hoffe ich habe das jetzt auf die Schnelle richtig zusammengestückelt ;)

    Ich hoffe das paßt so mit dem Ablauf und close() andersnfalls noch einen Play-Stopp Befehl vor close() einfügen

    Franky

    Franky

  • Beitrag von FrauBerry (19. August 2022 um 13:25)

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • Ok, habe eine Menge daran gebastelt.

    Ich denke es könnte funktionieren, wenn ich old_id auf "" ändere, wenn der Song zu Ende ist. Denn wenn ich es herausnehme wird nur ein Song abgespielt und das Programm wird beendet. Eine Idee dazu?

    play(device,f)

    f.close()

    rfid_id = ""

    old_id = ""

    Ich hab hier mal meinen ganzen Code:

  • Moinsen,

    Mach es dir doch nicht zu kompliziert !
    Mit den Dictionary hast du einen kompakten Aufruf der immer gültig ist.
    Und sobald old_id bei dir einen abweichenden Wert von '' erreicht, bricht logischer Weise die Programmschleife ab, weil True and False = False ergibt, und damit die Durchführungsbedingung für while nicht mehr gegeben ist

    Franky

    Franky

  • Das ist eine Art Musikbox. An den Pi angeschlossen ist eine Soundkarte mit Lautsprechern und ein Kartenlesegerät ist per USB angeschlossen. Wenn ich eine Karte drüber halte, dann startet ein Song. Eine extra karte ist fürs herunterfahren zuständig, da ich das mit dem "on/off Shim" erstmal aufgeschoben habe.

    Das funktioniert soweit alles super, nur, wenn ich die Karten draufhalte bevor der Song zu ende ist gibt es Probleme.

    Halte ich die Karte ca. 5-6 Sekunden nach der ersten drüber dann pipst das Gerät länger als normal, aber stürzt nicht ab. Wenn ich die Karte ein paar Sekunden nach der ersten drüber halte, dann stürzt das Programm ab.

  • Moinsen,

    So wie ich das sehe ist das ganz normal die Reaktion. Wenn die erste Karte das Playing gestartet hat, so wie es in deinem Zerfransten Code steht hängt das Programm in einer Abspielschleife fest. Nun kommt der Reader über den USB als solches angeflattert, und will den zweiten Play starten obwohl da noch was am playen ist.
    Deswegen hatte ich dir auch schon empfohlen, lagere das Play oder die Abfrage in einen Thread aus, das diese beiden sich erst einmal nicht bekriegen können.
    Mußte es unbedingt ein solcher USB Reader sein ? Ich frage ja nur mal nach. Diese RFID Player gibt eigentlich schon fertig als Imges auch MOD Baukasten für das Arduino. Aber dort werden keine USB RFID Reader genutzt nur einfach SPI Reader.

    Löse dich bitte mal nur vorübergehend von deinem Programmkonzept, versuche mal ob die Wiedergabe auch über Playsound funktionieren würde. Dann hätten wir einen Lösungsansatz :bravo2:

    Ich weiß nicht wie ich es vorsichtig ausdrücken soll, ohne dir zu nahe treten zu wollen, du versuchst das Rad neu zu erfinden.
    Es gibt so tolle MP3 Player mit Verstärker 3 Watt und LINE OUT Ausgang als kleines Platinchen für das Steckboard. Man kann dort auch Drähte anlöten ;) Und einfache RFID Reader wie den RFID522 , da sendet man via der RX/TX Pins einen Play-Befehl zum MP3 Player- Cardreader und steuert das ganze nur über wenige Codezeilen.

    Solange wir nicht auflösen können, oder herausbekommen, warum der USB RFID diesen Spuck veranstaltet, und du keine Fehler anzeigen kannst , kommen wir an dem Punkt kaum weiter. So gerne ich dir helfen wollte. Ich kann es nicht nachvollziehen. :gk1:

    Franky

    Franky

  • Moinsen,

    Ja ich noch einmal ;)
    Versuche doch erst einmal folgende auf die Reihe oder vom Programmablauf hinzubekommen.
    Über einen Event zB eine Tasterauslösung an einem x Beliebigen GPIO PIN das Playen von einem Song zu starten, und diesen auch wieder über den selben Taster zu stoppen.
    Das wäre die Grundanforderung des Programms welches du aufbauen möchtest. Wenn das klappt, dann kannst du den Event-Auslöser tauschen, in dem du statt des Tasters den RFID Reader ins spiel bringst, und dann die Ergänzung der Playliste.
    Oder auch schon davor. Das du mit jedem Tastendruck in der Playliste einen Titel weiterspringen kannst. Dabei der gerade laufende beendet wird, und anschließend erst der neue Titel begonnen wird.
    Das ist das unumstößlich Grundkonzept.

    Franky

    Franky

  • Oh, ich dachte eigentlich ich hätte eine möglichst simple Lösung gefunden. Ich hatte Ursprünglich die Anleitung für so eine selbstgebaute Musikbox und habe alles wie Buttons und sowas halt weggelassen. Das es noch etwas einfacheres gibt wusste ich nicht. Jetzt muss ich es so weitermachen, habe leider nur noch ein paar Tage übrig bis es aufgebaut werden muss.

    Gute Idee, versuche ich.

    Als Taste könnte ich aber auch einfach eine Eingabe per ssh nehmen machen oder? Ist ja erstmal nur zum Testen.

    Playsound oder so klappt leider nicht. Anfangs habe ich alle Soundklassen ausprobiert. alsaaudio wurde für die Tests der Soundkarte verwendet. Das war die einzige mit der ich es geschafft habe Sound abzuspielen.

  • Ok, probiere mich gerade an den Threads, dass kannte ich vorher noch nicht. Ist genau das was ich brauche, aber ich kriege das mit den Gültigkeiten gerade nicht hin.

    Starten der Musik mit "start" funktioniert. Wenn ich stoppen will, dann sagt er mir das f nicht definiert ist.

    Wie kriege ich das hin, dass ich vom zweiten Task auf dasselbe Objekt zugreifen kann?

  • Code
    global f

    Oje, das wird immer schlimmer. Sorry! :no_sad:

    Das von Dir kopierte Skript ist uralt. Woher ich das weiß? Daher:

    from __future__ import print_function

    und dem anderen Kram, der eigentlich total umständlich ist, wie z.B.:

    Code
    import wave
    import getopt
    import alsaaudio

    Verwende ein aktuelles Player-Modul oder dessen Wrapper-Modul wie z.B.

    Code
    import vlc

    oder

    Code
    import pygame.mixer

    oder ...

    Da ich keinen RFID-Reader habe, kann ich leider nicht testen und hätte dafür momentan auch keine Zeit. Aber so schwer kann das doch nicht sein ein Dict anzulegen, den RFID-Key mit dem Dict-Key zu vergleichen und bei einem Treffer den entsprechenden Sound abzuspielen. :conf:

Jetzt mitmachen!

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