Как воспроизводить разные звуки последовательно и асинхронно в python? - PullRequest
0 голосов
/ 14 апреля 2020

Чтобы указать c, мне нужно немного воспроизвести звук l oop, который быстро исполняется. И аудио нужно воспроизводить отдельно. Я пробовал различные функции / библиотеки: playsound, winsound, vl c. Но никто из них не отвечает моему требованию.

Либо звуки перекрываются, либо мне нужно дождаться окончания звука sh, чтобы продолжить следующую строку кода, которая блокирует весь процесс, заставляя программу работать с невыносимыми лагами.

Имеет значение в playsound, winsound, vl c: playsound: имеет опцию блока, но блокирует процесс (с блоком = True) или перекрывает звук (block = False).

winsound: с SND_ASYN C опция, скажем, у меня есть аудио A и аудио B (которые должны воспроизводиться после аудио A), если воспроизводится аудио B, аудио A немедленно остановится.

vl c: [000001ba245794d0] Ошибка вывода звука mmdevice: не удалось инициализировать COM (ошибка 0x80010106), что довольно странно, и в Google не было найдено ничего полезного. И этот метод кажется не лучшим вариантом для меня и других. Я использую это просто для функции is_playing () и могу поместить следующий звук в очередь.

Итак, какой совет? Спасибо!

1 Ответ

1 голос
/ 14 апреля 2020

Если вы просто после воспроизведения звука и его прерывания играете раньше, 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()

В этом примере открывается окно, и каждый раз, когда вы нажимаете клавишу, он воспроизводит звук немедленно, не прерывая предыдущие звуки. Программа заканчивается сразу после закрытия окна.

...