@udo100: Und wie siehst Du oder woran machst Du fest, dass das ”funktioniert” und nur keinen Ton ausgibt? Gibt es denn im aktuellen Arbeitsverzeichnis des Prozesses denn eine Datei mit dem Namen ``1.mp3``? Denn das ist ja das einzige was dieses Programm abspielt. Die „open extern mp3 file“-Schaltfläche funktioniert ja nicht sinnvoll. Da kann man was auswählen, aber das hat keinen weiteren Einfluss auf das Programm.
Globale Variablen sind ja schon schlecht, weil sie Programme schwerer durchschaubar machen und damit die Fehlersuche erschweren. Dazu dann noch Threads macht es noch mal unübersichtlicher. ``global`` hat in einem ordentlichen Programm nichts zu suchen. Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Keine Variablen. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Alles was eine Funktion oder Methode ausser Konstanten benötigt, wird als Argument(e) beim Aufruf übergeben. Ergebnisse an den Aufrufer als Rückgabewerte zurück gegeben.
Wenn man sich Zustand über Aufrufe hinweg merken muss, kommt man um objektorientierte Programmierung (OOP) nicht sinnvoll herum. Also eigene Klassen schreiben.
Das globale `playtime` wird auch nirgends verwendet und das globale `file_path` wird nur in einer einzigen Funktion verwendet, warum ist das dann überhaupt global?
Die Fenstergrösse ergibt sich aus dem Fensterinhalt. Wenn man die selber hart in Pixeln vorgibt, kann das Fenster komisch aussehen weil zu viel oder zu wenig Platz für den Inhalt da ist, oder sogar unbedienbar werden, wenn deutlich zu wenig Platz für den Inhalt da ist und Bedienteile gar nicht mehr sichtbar sind.
`fadeoff()` sollte besser `fade_out()` heissen. Wobei die beiden Funktionen `fade_in()` und `fade_out()` so ähnlich sind, dass man da im Grunde *eine* draus machen kann.
Bei Namen mit mehreren Worten, sollte man die Reihenfolge ”normal” wählen. Ein `button_stop` ist etwas anderes als ein `stop_button`.
Die ``while``-Schleife in `run()` spielt erst zuende ab, das heisst ein Druck auf STOP hält das abspielen nicht sofort an.
Es macht keinen Sinn, dass beide Schaltflächen, START und STOP, gleichzeitig aktiv sind. Bei STOP ist das kein hartes Problem, weil da nichts passiert was bei bei bereits gestoppten Player nicht noch mal machen dürfte, aber das man START auch drücken kann während der Player läuft, ist ein Fehler. Im Grunde würde auch eine Schaltfläche zum starten/stoppen ausreichen.
Zwischenstand (ungetestet):
Code: Alles auswählen
# Programm Random MP3-Player by Udo100
import random
import threading
import time
import tkinter as tk
from enum import auto, Enum
from functools import partial
from tkinter import filedialog
import vlc
class Fade(Enum):
IN = auto()
OUT = auto()
def on_open_button():
file_path = filedialog.askopenfilename(
filetypes=[("Musik", "*.mp3"), ("Alle Dateien", "*.*")]
)
print(file_path)
if file_path:
#
# BUG This doesn't have an effect on the program.
#
player = vlc.MediaPlayer(file_path)
def fade(player, in_or_out):
values = range(0, 100)
if in_or_out is Fade.OUT:
values = reversed(values)
elif in_or_out is not Fade.IN:
raise ValueError(f"Unexpeted fade value {in_or_out!r}")
for value in values:
player.audio_set_volume(value)
time.sleep(0.05)
def run(player, event):
player.play()
#
# XXX This does not stop as soon as the event is set, but waits until the
# `playtime` is up. Bug?
#
while not event.is_set():
playtime = random.random() * 60
print(playtime)
player.set_position(random.random())
fade(player, Fade.IN)
time.sleep(playtime)
fade(player, Fade.OUT)
def on_start_button(player, event):
print("Button start clicked!")
event.clear()
threading.Thread(target=run, args=[player, event], daemon=True).start()
def on_stop_button(player, event):
print("Button stop clicked!")
event.set()
player.stop()
def main():
player = vlc.MediaPlayer("1.mp3")
event = threading.Event()
window = tk.Tk()
window.title("RMP3 V0.1")
label = tk.Label(
window, text="For Start/End click the button below:"
).pack()
tk.Button(
window, text="open extern mp3 file", command=on_open_button
).pack()
#
# BUG Start/Stop shouldn't be active at the same time.
#
start_button = tk.Button(
window, text="START", command=partial(on_start_button, player, event)
)
start_button.pack()
stop_button = tk.Button(
window, text="STOP", command=partial(on_stop_button, player, event)
)
stop_button.pack()
window.mainloop()
if __name__ == "__main__":
main()
`threading` könnte man auch in Frage stellen, denn so ein Player würde sich auch mit `after()` und ein bisschen Zustandsverwaltung in einer Klasse umsetzen lassen.