Звуковой файл не воспроизводится в приложении PySide после PyInstaller

В моем приложении PySide я использую следующий фрагмент кода для воспроизведения файла WAV:

media = Phonon.MediaObject()
audio = Phonon.AudioOutput(Phonon.MusicCategory)
Phonon.createPath(media, audio)
alarm_file = 'alarm_beep.wav'
f = QtCore.QFile(alarm_file)
if f.exists():
    source = Phonon.MediaSource(alarm_file)
    if source.type() != -1:              # -1 stands for invalid file
        media.setCurrentSource(source)
        media.play()
else:
    logger.debug('Alert media missing: %s' % alarm_file)

Это прекрасно работает в Ubuntu, когда я запускаю скрипт Python, но когда я компилирую приложение в исполняемый файл с Pyinstaller для Windows, звук не воспроизводится.

Я использую следующую команду pyinstaller

pyinstaller  --onefile --add-data "alarm_beep.wav;." main.py

попытаться добавить медиа-файл, но безрезультатно.

Исключением в консоли является

WARNING: bool __cdecl Phonon::FactoryPrivate::createBackend(void) phonon backend plugin could not be loaded
             WARNING: bool __cdecl Phonon::FactoryPrivate::createBackend(void) phonon backend plugin could not be loaded
             WARNING: bool __cdecl Phonon::FactoryPrivate::createBackend(void) phonon backend plugin could not be loaded
             WARNING: bool __cdecl Phonon::FactoryPrivate::createBackend(void) phonon backend plugin could not be loaded
             WARNING: Phonon::createPath: Cannot connect  MediaObject ( no objectName ) to  AudioOutput ( no objectName ).

Alert media missing: alarm_beep.wav

Очевидно, что "alarm_beep.wav" не существует.

Не уверен, почему add-data команда не заботится об этом?

1 ответ

Как только приложение в комплекте, внешние файлы будут сохранены во временном каталоге, на который вам нужно будет ссылаться. Смотрите этот пост для обсуждения ссылки на эти внешние файлы. Короче говоря, вам нужно будет обновить путь к файлу ресурса, прежде чем ссылаться на него:

#resource_path is the relative path to the resource file, which changes when built for an executable
def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath('.')
    return os.path.join(base_path, relative_path)

и в теле вашего кода:

alarm_file = resource_path('alarm_beep.wav')
Другие вопросы по тегам