【问题标题】:Program is crashing while using playsound module使用 playsound 模块时程序崩溃
【发布时间】:2021-07-13 16:53:46
【问题描述】:

是的,我只是在制作一个播放我最喜欢的游戏音乐的程序。现在的问题是,当我调用playsound(module) 的playsound 函数时,我的程序滞后并最终崩溃。这是我的代码:

import tkinter as tk
from playsound import playsound
import multiprocessing
class dynastyMusicer(tk.Tk):
    def __init__(self, screenName=None, baseName=None, className='Tk',
                 useTk=True, sync=False, use=None):
        super().__init__(screenName=screenName, baseName=baseName, className=className, useTk=useTk, sync=sync, use=use) 
        self.title("Dynasty Musicer")
        self.geometry("250x100")
        self.config(background="white")
        chooseL = tk.Label(self, text="Which music to play?", background="white")
        chooseL.place(x=50, y=0)
        ops = ["Dynasty Dojo", "Dynasty Dojo Fight"]
        self.stvar = tk.StringVar(self)
        self.stvar.set("Music")
        self.option = tk.OptionMenu(self, self.stvar, *ops)
        self.option.place(y=30)
        btn = tk.Button(self, text="Play", width=10, command=self.play)
        btn.place(y=70)
        stop = tk.Button(self, text="Stop", width=10, command=self.stop)
        stop.place(x=160,y=70)
    def stop(self):
        multiprocessing.Process(target=playsound, args=(self.stvar.get()+".mp3"))
    def play(self):
        if self.stvar.get() == "Dynasty Dojo":
                playsound(r"path")
        elif self.stvar.get() == "Dynasty Dojo Fight":
            playsound(r"path")
                
dm = dynastyMusicer()
dm.mainloop()

也因此我无法测试我的stop 功能是否正常工作,因为当您单击播放按钮时,是的,您猜对了,它会崩溃。如果你想下载我使用的两个音乐文件,这里是链接:

Dynasty Dojo

Dynasty dojo fight

【问题讨论】:

  • 使用:playsound(r"path",block=True)。关注:stackoverflow.com/a/56678592/13382000
  • 不,点击播放后仍然滞后并一次又一次地崩溃。感谢您的回答
  • 等一下,我的意思是,block=False :/

标签: python module


【解决方案1】:

您的代码有很多需要注意的地方。与:

  • tkinter 是单线程的,从单独的线程运行它会导致问题,但您可以使用 multiprocessing,如果您可以确保 tk 对象不会进入其他进程/线程。

  • 但是在这种情况下这种痛苦并不是不必要的,在这里你不需要使用任何这个,因为playsound 可以在不阻塞线程的情况下运行,例如:playsound(..., block=False)

  • 在这里我还注意到一个停止按钮,你不能用playsound 停止一个开始的声音,所以现在你必须开始寻找其他线程声音库,pygame 是我能找到的最好的。虽然它在文件方面存在一些支持问题,但在大多数情况下应该没问题。

以下是使用pygame 并修改当前设置的更好代码:

import tkinter as tk
import pygame # pip install pygame

class DynastyMusicer(tk.Tk): # Using Pascal Case notation for class names
    def __init__(self, *args, **kwargs): # Shorten all the optional arguments
        super().__init__(*args, **kwargs) # or tk.Tk.__init__(....)
        self.title("Dynasty Musicer")
        self.geometry("250x100")
        self.config(background="white")
        
        pygame.init() # Initialize pygame

        chooseL = tk.Label(self, text="Which music to play?", background="white")
        chooseL.place(x=50, y=0)
        
        self.ops = ["Dynasty Dojo", "Dynasty Dojo Fight"]
        self.stvar = tk.StringVar(self)
        self.stvar.set("Music")
        
        self.option = tk.OptionMenu(self, self.stvar, *self.ops)
        self.option.place(y=30)
        
        btn = tk.Button(self, text="Play", width=10, command=self.play)
        btn.place(y=70)
        
        stop = tk.Button(self, text="Stop", width=10, command=self.stop)
        stop.place(x=160,y=70)
    
    def stop(self):
        pygame.mixer.music.stop() # Stop the music being played

    def play(self):
        if self.stvar.get() != 'Music': # If not the default value, then
            pygame.mixer.music.load(rf"{self.stvar.get()}.mp3") # Load the song
            pygame.mixer.music.play() # Play the song
                
dm = DynastyMusicer()
dm.mainloop()

在这里,您的if 语句被修改为缩短,因为您遵循whitelisting,它禁止任何无效 输入进入(“音乐”除外)。

【讨论】:

  • 好吧,我自己没有添加 __init__ 函数参数,它只是 vscode 的愚蠢 sn-p 之一。我很懒,所以我想谁会为我清理它,你还是做了,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多