Having sounds complete before the next, in python?

2019-03-03 10:27发布

In Python/pygame, I desire to repeat a certain wav file (read by pygame.mixer.Sound("foo.wav").play() in a loop, and have them play one after another, preferably after last has completed or by a default delay (1500ms works)

So far, paraphrasing, I have this:

    for x in range(0, 5):
        pygame.mixer.Sound("foo.wav").play()

When it plays, however, it plays all at once.

Using pygame.time for a delay hangs the window, as does tkinter .after(1500), and I cannot seem to find a straight-forward means to do this with either libraries or python or even an example of something playing a few tones with delay as I intend. I could substitute pygame with a more 'standard' audio drop-in for Python, or potentially use threading if it comes to it for the button presses, if it requires hackery to do such a thing with the pygame mixer alone.

Some handy references if needed: http://www.pygame.org/docs/ref/music.html https://docs.python.org/2/library/tkinter.html

1条回答
仙女界的扛把子
2楼-- · 2019-03-03 11:05

The most straightforward way to do this seems to be to get the length of each sound and play the next one after the given time has elapsed, via Tkinter's after method.

self.sound_queue = [pygame.mixer.Sound(s) for s in ('foo.wav', 'bar.ogg', 'baz.mp3')]

def play_queue(self, q, num=0)
    sound = q[num]
    duration = int(sound.get_length() * 1000)
    sound.play()
    if num < len(q)-1:
        self.root.after(duration, self.play_queue, q, num+1)

self.play_queue(self.sound_queue)

You could also look at pygame.mixer.Channel.queue() and pygame.mixer.Channel.set_endevent, as those are probably the intended way to do this sort of thing.

查看更多
登录 后发表回答