Search code examples
pythonpython-multithreading

Stop thread flow (audio) by condition in Python


There are streams: music - plays music, run - asks to enter something. I want that if "r" is entered, the music stream is interrupted by this condition. I understand that the flag with the condition does not work. Please help me fix the code for this case.

import pygame
from threading import Event
import threading
import time


def f_music(finish: Event):
    pygame.init()
    pygame.mixer.music.load("kukla-poet.mp3")
    pygame.mixer.music.play()

    while pygame.mixer.music.get_busy():
        pygame.event.poll()
    
    if finish.is_set():
        print('Finish')
        break

def f_run():
    while True:
        run = input("Vvedi deistvie")
        deistvie.append(run)
        print(run)


if __name__ == "__main__":

    finish = Event()
    deistvie = []

    music = threading.Thread(target=f_music, args=(finish, ))
    run = threading.Thread(target=f_run, args=())
    music.start()
    run.start()

    while True:
        if deistvie[-1] == "r":
            finish.set()
            break

Solution

  • The code in your question contains a syntax error. You cannot have break outside of a loop.

    pygame.init() needs to be called from the main thread.

    It looks like you want one thread to load and run an MP3 until such time as it ends of its own accord or if there's an input of the string "r".

    That being the case, you could do this:

    import pygame
    from threading import Event, Thread
    
    MP3 = "kukla-poet.mp3"
    
    def f_music(event: Event) -> None:
        pygame.mixer.music.load(MP3)
        pygame.mixer.music.play()
    
        while pygame.mixer.music.get_busy():
            if event.wait(1):
                pygame.mixer.music.stop()
                break
        pygame.mixer.music.unload()
    
    def f_run(event: Event) -> None:
        while input("Vvedi deistvie: ") != "r":
            pass
        event.set()
    
    if __name__ == "__main__":
        pygame.init()
        event = Event()
    
        (music := Thread(target=f_music, args=(event,))).start()
        (run := Thread(target=f_run, args=(event,))).start()
    
        music.join()
        run.join()