如何连续和异步播放不同的声音?
How to play different sound consecutively and asynchronously?
具体来说,我需要在执行速度快的 while 循环中播放声音。并且音频需要单独播放。我尝试了各种 functions/libraries:playsound、winsound、vlc。但是none个满足了我的需求
要么声音重叠,要么我需要等声音结束才能继续下一行代码,这会阻塞整个过程,导致程序运行无法忍受的延迟。
playsound、winsound、vlc中的事项:
playsound:有阻止选项,但会阻止进程(block=True
)或重叠声音(block=False
)。
winsound: 带SND_ASYNC
选项,假设我有音频A和音频B(需要在音频A之后播放),如果播放音频B,音频A会立即停止.
vlc: [000001ba245794d0] mmdevice 音频输出错误:无法初始化 COM(错误 0x80010106),这有点奇怪,在 Google 上找不到有用的东西。而且这种方法对我和其他人来说似乎不是一个好的选择。我使用它只是为了它的 is_playing()
功能,我可以将下一个声音放入队列。
有什么建议吗?
如果您只是在播放声音之后让它打断之前正在播放的任何内容,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
会使函数 运行 异步。
具体来说,我需要在执行速度快的 while 循环中播放声音。并且音频需要单独播放。我尝试了各种 functions/libraries:playsound、winsound、vlc。但是none个满足了我的需求
要么声音重叠,要么我需要等声音结束才能继续下一行代码,这会阻塞整个过程,导致程序运行无法忍受的延迟。
playsound、winsound、vlc中的事项:
playsound:有阻止选项,但会阻止进程(
block=True
)或重叠声音(block=False
)。winsound: 带
SND_ASYNC
选项,假设我有音频A和音频B(需要在音频A之后播放),如果播放音频B,音频A会立即停止.vlc: [000001ba245794d0] mmdevice 音频输出错误:无法初始化 COM(错误 0x80010106),这有点奇怪,在 Google 上找不到有用的东西。而且这种方法对我和其他人来说似乎不是一个好的选择。我使用它只是为了它的
is_playing()
功能,我可以将下一个声音放入队列。
有什么建议吗?
如果您只是在播放声音之后让它打断之前正在播放的任何内容,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
会使函数 运行 异步。