Python MP3 abspielen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Steffen21m
User
Beiträge: 3
Registriert: Dienstag 7. Mai 2019, 04:03

Hallo liebes Forum,
ich "bastele" gerade ein Abschiedsgeschenk für meinen Meister. Dazu habe ich in ein Wählscheibentelefon einen Raspberry eingebaut. Am GPIO13 ist eine Klingel angeschlossen. Am GPIO 11 die Gabel ob der Telefonhörer aufgelegt ist oder nicht. Die Hörmuschel im Telefonhörer ist am 3,5 Klinkenstecker angeschlossen. Nun soll das Telefon alle X Minuten klingeln. Wenn man den Hörer abnimmt, dann sollen die MP3's im Ordner Musik abgespielt werden (Shuffle Modus). Dazu habe ich folgende Python Zeilen zusammengeschrieben. Leider funktioniert die MP3 wiedergabe nicht, weil der Ordner angeblich nicht gefunden wird. Fallen euch die Fehler im Skript auf? Ich suche schon sehr lange und komme so langsam nicht mehr weiter:

import RPi.GPIO as GPIO
import time
import subprocess

GPIO.setmode (GPIO.BOARD)
GPIO.setup(11,GPIO.IN, pull_up_down _ GPIO.PUD_DOWN)
GPIO.setup(13,GPIO.OUT)

while True:
if(GPIO.input(11) == True):
GPIO.output(13,False)
subprocess.Popen(["mpg321", " Musik/*.mp3"])
print("AN")
else:
print("AUS")
time.sleep(20)
print("klingeln")
GPIO.output(13,True)

Vielen Dank für eure Unterstützung

Steffen
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Steffen21m: die Einrückungen sind kaputt. Einrückungen sind in Python wichtig, sonst können Programm-Blöcke nicht erkannt werden. Eingerückt wird immer mit 4 Leerzeichen pro Ebene. if ist keine Funktion, die Klammern also überflüssig. Man prüft nicht explizit auf True. Es fehlt ein cleanup. Der Pfad zur Musik startet mit einem Leerzeichen. Ist das so richtig? Am besten absolute Pfade angeben. Statt Pinnummern direkt zu benutzen, definiert man sich normalerweise Konstanten, dann kann man die Pins auch einfach auswechseln. Module schreibt man nach Konvention klein, also gpio, andernfalls macht das `as` beim Import auch keinen Sinn.

Das Programm funktioniert auch so nicht, weil Du solange der Hörer aufgelegt ist, 20s-lang klingeln hörst, bis Du wieder den Hörer prüfst.

Am besten schreibst Du Dir ein paar Funktionen, die Du einzeln testen kannst, ob die einzelnen Komponenten Deiner Idee auch funktionieren:

Code: Alles auswählen

import RPi.GPIO as gpio
import time
import subprocess

SLEEP_TIME = 5 * 60
RING_TIME = 30
PLAY_TIME = 20 * 60

MUSIC_PATH = '/home/pi/Musik/*.mp3'
RECEIVER_PIN = 11
BELL_PIN = 13

def setup():
    gpio.setmode(gpio.BOARD)
    gpio.setup(RECEIVER_PIN,gpio.IN, pull_up_down = gpio.PUD_DOWN)
    gpio.setup(BELL_PIN, gpio.OUT)

def start_ringing():
    gpio.output(BELL_PIN, True)

def stop_ringing():
    gpio.output(BELL_PIN, False)

def wait_for_receiver():
    edge_detect = gpio.wait_for_edge(RECEIVER_PIN, gpio.RAISING, timeout=RING_TIME)
    return edge_detect is not None

def play_music():
    mpg = subprocess.Popen(["mpg321", MUSIC_PATH])
    gpio.wait_for_edge(RECEIVER_PIN, gpio.FALLING, timeout=PLAY_TIME)
    # stop music after hang up
    mpg.kill()

def main():
    try:
        while True:
            time.sleep(SLEEP_TIME)
            start_ringing()
            play = wait_for_receiver():
            stop_ringing()
            if play:
                play_music()
    finally:
        gpio.cleanup()
        
if __name__ == '__main__':
    main()
Steffen21m
User
Beiträge: 3
Registriert: Dienstag 7. Mai 2019, 04:03

Hallo Sirius,
Danke für die superschnelle Antwort. Dein Programm sieht super strukturiert aus. Habe mein Programm abgetippt. Deswegen sind die Formatierungen verloren gegangen. Ich als Python Neuling hatte die Programmierung trotz Google Hilfe nicht geschafft. Aus diesem Grund bin ich sehr dankbar, dass du mir den ganzen Code gepostet hast.
Ich werde alles heute Abend Mal testen ;-)

Danke und noch eine schöne Woche

Gruß Steffen
Steffen21m
User
Beiträge: 3
Registriert: Dienstag 7. Mai 2019, 04:03

Hallo liebes Forum,
ich habe den Code von Sirius getestet und das Telefon zum Laufen gebracht. Ich habe nur noch ein Problem, das ich nicht verstehe:

Es sollen alle mp3 Dateien im Ordner Musik abgespielt werden:
MUSIC_PATH = '/home/pi/Musik/*.mp3'
mpg = subprocess.Popen(["mpg321", MUSIC_PATH])
Es erscheint die Fehlermeldung Path not found

Wenn ich in der shell "mpg321 /home/pi/Musik/*.mp3" eingebe funktioniert es

Wenn ich den Dateinamen direkt angebe funktioniert es in Python auch:
MUSIC_PATH = '/home/pi/Musik/dateiname.mp3'
mpg = subprocess.Popen(["mpg321", MUSIC_PATH])

Hat jemand eine Idee woran es liegen kann?

Vielen Dank für eure Hilfe

Gruß Steffen
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Die Interpretation von * findet in der Shell statt, deswegen funktioniert das, wenn du es händisch eingibst. Wenn du Popen benutzt, wird der externe Prozess direkt gestartet und es gibt (standardmäßig) keine Shell "dazwischen", die das * zu Dateinamen expandieren könnte. Du kannst kannst das stattdessen in Python erledigen, etwa mit dem Modul 'glob'.

(Im Netz kursiert der Vorschlag, den Parameter shell=true zu setzen. Das sorgt dafür, dass eine Shell "dazwischen" geschaltet wird. Das klingt im ersten Moment bequem, hat aber verschiedene Nebeneffekte. Daher sollte man davon im allgemeinen absehen.)
Antworten