如何阻止Simpleaudio同时播放两次文件?

时间:2019-10-25 21:41:50

标签: python audio simpleaudioengine

我在基于文本的冒险游戏中使用simpleaudio。我正在使用Python3。在我的主循环中,我想要实现这一点:播放一个简短的音频剪辑,完成后,再次开始播放相同的音频剪辑。我的问题是,我无法弄清楚如何使Simpleaudio做到这一点。

我没有阅读所有的API文档。关于循环,我尝试了许多不同的方法,但没有一个起作用。

import simpleaudio as sa

def audio(audiofile):
    filename = "/Users/*********/Desktop/Programming/Python Files/Adventure Game/Audio Files/" + audiofile
    wave_obj = sa.WaveObject.from_wave_file(filename)
    play_obj = wave_obj.play()

A = True
while True:
audio("openingtune.wav")
clear_screen()
firstinput = input("> ")
user_input1(firstinput)

# I didn't include the other functions because they're not relevant to this. 

注意:“ while true”循环经常刷新一次(在获取输入并给出输出之后)。我不知道该怎么做:一旦歌曲播放完一次,就应该从同一点开始。

2 个答案:

答案 0 :(得分:0)

您当前的方法不起作用,因为您在主线程上播放音频。它会按照预期的那样开始播放音频,但是audio之后会有一系列动作,即所有用户输入。同时,audio可能会停止播放,并且直到循环的下一遍才执行。

解决方案:在单独的线程上开始音频。

代码:

import simpleaudio as sa
from threading import Thread

def audio(audiofile):
    filename = "/Users/*********/Desktop/Programming/Python Files/Adventure Game/Audio Files/" + audiofile
    wave_obj = sa.WaveObject.from_wave_file(filename)
    while(True):
        play_obj = wave_obj.play()

# Let's play the music on a separate thread
audio_thread = Thread(target=audio, args=("openingtune.wav",))
audio_thread.start()

# And now the main game loop
A = True
while True:
    clear_screen()
    firstinput = input("> ")
    user_input1(firstinput)

可能您会希望引入一些控件来停止播放音频。

答案 1 :(得分:0)

与建议相反,simpleaudio 不在主线程上播放音频。根据文档..

<块引用>

该模块实现了一个异步接口,这意味着程序在音频播放开始后立即继续执行,其余的由后台线程处理。这使得将音频播放合并到需要保持响应的 GUI 驱动应用程序中变得容易。

while 循环应该简单地检查线程是否已完成,如果已完成,则再次播放音频。

import simpleaudio as sa


class AudioPlayer:
    def __init__(self):
        self.play_obj = None

    def play(audiofile):
        filename = "/Users/*********/Desktop/Programming/Python 
                    Files/Adventure Game/Audio Files/" + audiofile
        wave_obj = sa.WaveObject.from_wave_file(filename)
        self.play_obj = wave_obj.play()
    
    def is_done():
        if self.play_obj:
            return not self.play_obj.is_playing()
        return True

player = AudioPlayer()
while True:
    clear_screen()
    if player.is_done():
        player.play("openingtune.wav")
    ...

如果您连续播放同一个文件,您可能需要考虑将文件字符串一劳永逸地传递给构造函数。字符串是不可变的,因此 player.play() 调用中的字符串是在循环的每次迭代中创建并通过副本传递的,如果它总是相同的字符串,那就太疯狂了。