如何停止播放来自 playsound 模块的声音

How to stop playing a sound from playsound module

我正在制作一个计时器程序,我希望它在计时器结束时播放一首歌曲,但我也想在按下按钮时停止声音。

我看到其他帖子使用多处理模块 () 来停止音频,但我已经在使用线程模块,所以我想知道是否可以使用它来停止音频相反。

编辑:Matiis 提供的解决方案与我正在寻找的不同,但它仍然可以完美运行。 glory9211也给出了我后面要找的解决方案

from tkinter import *
from time import sleep
from threading import Thread
from threading import Event

import playsound

class App(Tk):

    def __init__(self):
        super().__init__()
        self.title("Clock")
        self.t_evt = Event()

        self.frame2 = Frame(self)

        self.timerStart = Button(self.frame2, text="Start", command=self.tt_Start)
        self.timerStart.config(height=2, width=5)
        self.timerStart.grid(row=1)

        self.timerEnd = Button(self.frame2, text="End", command=self.timer_End)
        self.timerEnd.config(height=2, width=5)
        self.timerEnd.grid(row=2)


    def tt_Start(self):
        t = Thread(target=self.timer_Start)
        t.setDaemon(True)
        t.start()

    def timer_Start(self):
        self.t_evt.clear()
        timer_seconds = int(self.timerS_Entry.get())
        timer_minutes = int(self.timerM_Entry.get())
        if timer_seconds > 59:
            timer_seconds -= 60
            timer_minutes += 1
        while not self.t_evt.is_set():
            print(f"Minutes: {timer_minutes}, Seconds: {timer_seconds}")
            self.timerSeconds.config(text=timer_seconds)
            self.timerMinutes.config(text=timer_minutes)
            self.update()
            time = (timer_minutes * 60) + timer_seconds
            timer_seconds -= 1
            sleep(1)
            if time == 0:
                break
            if timer_seconds < 0:
                timer_seconds = 59
                timer_minutes -= 1

        playsound.playsound('C:\Users\nonon\mp3\song.wav')
        print("TIMER UP")
        return

    def timer_End(self):
        self.t_evt.set()

这里有一些代码供您使用,如果您需要更多,请告诉我。

同样,我希望能够在按下结束按钮时停止 playsound.playsound('C:\Users\nonon\mp3\song.wav')

简答

您可以使用线程 Events 而不是线程。或者切换到多处理并使用 p.terminate()

长答案

您无法使用提供的任何功能停止 python threading.Thread。人们使用标志实现这一目标。 好读物: Is there any way to kill a Thread?


def thread_func():
    while flag:
        print("I'm running")

def run_button():
    flag = True
    t = threading.Thread(target=thread_func)
    t.start()

def stop_button():
    flag = False
    # This will make the function exit

但在您的情况下,playsound 函数不是循环函数,您可以在其中隐藏一个标志来停止该函数。你可以想象它是无限期的休眠功能,即

def play_sound():
    time.sleep(1000000) # Replacing with playsound.playsound

所以使用 threading.Events() 我们可以用这个示例代码实现这个

import random
import signal
import threading
import time

exit_event = threading.Event()


def bg_thread():
    for i in range(1, 30):
        print(f'{i} of 30 iterations...')
        if exit_event.wait(timeout=random.random()):
            break

    print(f'{i} iterations completed before exiting.')


def signal_handler(signum, frame):
    exit_event.set() # same as setting the flag False


signal.signal(signal.SIGINT, signal_handler)
th = threading.Thread(target=bg_thread)
th.start()
th.join()

此解决方案有效地为您提供了“可中断”睡眠,因为如果在线程卡在对 wait() 的调用中间时设置了事件,那么等待将立即 return。

在此处阅读详细示例:https://blog.miguelgrinberg.com/post/how-to-kill-a-python-thread