如何连续和异步播放不同的声音?

How to play different sound consecutively and asynchronously?

具体来说,我需要在执行速度快的 while 循环中播放声音。并且音频需要单独播放。我尝试了各种 functions/libraries:playsound、winsound、vlc。但是none个满足了我的需求

要么声音重叠,要么我需要等声音结束才能继续下一行代码,这会阻塞整个过程,导致程序运行无法忍受的延迟。

playsound、winsound、vlc中的事项:

有什么建议吗?

如果您只是在播放声音之后让它打断之前正在播放的任何内容,winsound 就是这样做的:

import winsound
from time import sleep

winsound.PlaySound("sound.wav", winsound.SND_ASYNC | winsound.SND_FILENAME)
sleep(1)
winsound.PlaySound("sound.wav", winsound.SND_ASYNC | winsound.SND_FILENAME)
sleep(3)

在这个例子中(假设sound.wav超过一秒),声音将开始播放,1秒后中断并重新开始播放。第二个 sleep 是为了避免脚本在声音停止之前结束(停止脚本会停止声音)。

如果你想排队播放一个接一个的声音,而你的代码保持 运行:

import threading
import queue
import winsound
from time import sleep

q = queue.Queue()


def thread_function():
    while True:
        sound = q.get()
        if sound is None:
            break
        winsound.PlaySound(sound, winsound.SND_FILENAME)


if __name__ == "__main__":
    t = threading.Thread(target=thread_function)
    t.start()
    q.put("sound.wav")
    print('One...')
    sleep(1)
    q.put("sound.wav")
    print('Two...')
    sleep(1)
    q.put("sound.wav")
    print('Three...')
    q.put(None)
    t.join()

这个简单的示例将线程开始播放的声音排队,然后在播放时将下一个声音排队,稍后再播放第三个。您会注意到声音一个接一个地播放,并且程序仅在声音播放完毕时停止(并且线程由于队列末尾的 None 而停止)。

如果你想在另一种声音之上播放一种声音并让它们混合,使用 winsound 是行不通的,但你可以使用像 pyglet.

这样的库

例如:

import pyglet


window = pyglet.window.Window()
effect = pyglet.resource.media('sound.wav', streaming=False)


@window.event
def on_key_press(symbol, modifiers):
    effect.play()


@window.event
def on_draw():
    window.clear()


if __name__ == "__main__":
    pyglet.app.run()

这个例子打开了一个window,每按一个键,它就会立即播放声音,而不会中断之前的声音。当您关闭 window.

时程序立即结束

这可以通过 playsound 轻松完成。

playsound.playsound('alert.mp3', False)

将第二个参数设置为 False 会使函数 运行 异步。