2025, Dec 24 12:03
Цикл зависает при simpleaudio.play в Python 3.12/3.13: причина и решение с 312compat
Цикл зависает при simpleaudio.play в Python 3.12.8/3.13.1 из‑за simpleaudio 1.0.4. Решение: пакет 312compat 1.0.4 и wait_done — исправляет сбой play/wait_done
Когда плотный цикл внезапно замирает сразу после запуска воспроизведения звука, это выглядит как ошибка логики. Но здесь дело не в ней. Цикл прерывается только при наличии вызова play; уберите эту единственную строку — и он дорабатывает до конца. Первопричина — специфическое взаимодействие интерпретатора Python с версией аудиобиблиотеки.
Минимальный пример, при котором цикл как будто «зависает»
Поведение воспроизводится на небольшом цикле, который на каждой итерации вызывает .play() и делает короткую паузу между срабатываниями.
import simpleaudio, time, math
counter = 0
pulse = simpleaudio.WaveObject.from_wave_file('metronome2.wav')
while counter < 20:
pulse.play()
time.sleep(0.5)
counter = counter + 1
print(counter)
С вызовом play цикл перестает продвигаться. Уберите его — и цикл завершится как ожидается. Удаление вызова sleep тоже может изменить исход, что дополнительно указывает не на чисто логическую ошибку управления, а на аудиослой.
Что на самом деле вызывает сбой
Сбой вызван сочетанием Python 3.12.8 или 3.13.1 с simpleaudio 1.0.4. В такой связке выполнение кода, который воспроизводит WAV и синхронизируется по завершении, падает с нарушением доступа на вызове wait_done. Поэтому цикл выглядит так, будто он завершается или зависает, как только замешано аудиовоспроизведение.
Рабочее решение
Используйте simpleaudio-312compat версии 1.0.4 вместо обычного пакета simpleaudio. Строка импорта не меняется: модуль по‑прежнему импортируется как simpleaudio. С этим совместимым пакетом та же логика работает исправно.
import simpleaudio
clip = simpleaudio.WaveObject.from_wave_file('hal2.wav')
turn = 0
while turn < 20:
turn += 1
handle = clip.play()
handle.wait_done()
print("turn:", turn)
Это подтверждает, что проблема не в самом цикле или счетчиках, а в связке библиотека/рантайм. Совместимая сборка устраняет падение, позволяя использовать тот же путь импорта и тот же API.
Почему стоит держать это в поле зрения
В задачах с жесткими требованиями к таймингу звук часто запускается из циклов, поэтому стабильность .play() в таком контексте критична. Несовпадение версий библиотеки и интерпретатора может маскироваться под ошибки управления потоком и уводить диагностику не туда. Зная, что Python 3.12.8 или 3.13.1 в сочетании с simpleaudio 1.0.4 может привести к нарушению доступа, легче избежать неверных выводов и сразу перейти к известному обходному решению.
Выводы
Если цикл замирает только при вызове simpleaudio.play(), сперва проверьте окружение. На Python 3.12.8 или 3.13.1 с simpleaudio 1.0.4 переключитесь на simpleaudio-312compat 1.0.4, не меняя импорт. Если вам важна синхронизация воспроизведения, после установки совместимого пакета можно безопасно вызывать wait_done на возвращаемом объекте. Внимание к точным версиям интерпретатора и пакетов экономит время и спасает от охоты за призрачными «ошибками логики».