Как правильно открыть и закрыть музыкальный файл для Pygame Mixer без зависания / зависания Python?

Я разрабатываю музыкальный проигрыватель в Python 2.7, и у меня есть проблема, которую я не могу решить.

Иногда необходимо отключить SD-карту, с которой я играю. Поскольку pygame по-прежнему сохраняет последний воспроизводимый файл открытым после команд pygame.mixer.stop() и pygame.mixer.quit(), размонтировать карту было невозможно.

Поэтому я изменил свой код, чтобы использовать команды открытия и закрытия файла, чтобы можно было правильно закрыть воспроизводимый файл перед размонтированием. Таким образом, размонтирование работает нормально.

Моя проблема в том, что Python всегда зависает во время воспроизведения первой музыки. Нет никаких исключений или сообщений об ошибках, воспроизведение просто останавливается, и программа не отвечает ни на какой пользовательский ввод, даже Ctrl+C не работает, чтобы завершить выполнение из оболочки.

Это зависание всегда происходит в случайное время, где-то между 1 и 40 секундами после начала игры. Если я открою файл напрямую с помощью команды pygame.mixer.music.load(myfile), не используя решение открытия / закрытия, у меня никогда не будет зависаний, программа воспроизводится правильно даже в течение нескольких часов.

Какое решение я должен использовать, чтобы правильно закрыть воспроизводимый файл (чтобы отключить карту памяти), а также избежать зависания программы?

Вот соответствующая часть моего кода. Он закрывает предыдущий сеанс воспроизведения и начинает воспроизведение нового файла.

FailedMusicLoad = 0
pygame.mixer.music.stop()
pygame.mixer.stop()
pygame.mixer.quit()
try:
        PlayedMp3File.close()
except AttributeError:
        pass

try:                        # test if selected music file can be loaded
        PlayedMp3File = open(Selectedmp3)
except IOError:
        FailedMusicLoad = 1

if FailedMusicLoad <> 1:
    pygame.mixer.init(frequency=musicforlength.info.sample_rate)
    pygame.mixer.music.set_volume(MainVolume)
    pygame.mixer.music.load(PlayedMp3File)
    pygame.mixer.music.play()

2 ответа

Вы можете сначала попытаться загрузить весь файл в память, используя отображенный в памяти файл:

import mmap

...

with open(Selectedmp3) as f: 
    PlayedMp3File = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) 

pygame.mixer.music.load(PlayedMp3File) 
pygame.mixer.music.play()

Таким образом, вы только касаетесь файла, загружая его в память и используя with гарантирует, что он будет правильно закрыт.

Я нашел простой способ обойти SD-карту.

Перед размонтированием я открываю фиктивный mp3-файл не с SD-карты, а из локальной файловой системы с помощью команды pygame.mixer.music.load(). Я не начинаю проигрывать этот фиктивный файл, просто откройте его. После этого нет никаких проблем, SD-карта, кажется, правильно выпущена Pygame, и я могу размонтировать ее.

Другие вопросы по тегам