Playing sound with Qt in Python: Error decoding source

2022-07-11

The correct way for playing sound with PySide6 and fixing the "error decoding source".

 

Qt is a widely adopted GUI framework, but its documentation is quite awful, especially when working in Python. And it's likely that you get the error

QSoundEffect(qaudio): Error decoding source /path/to/the/file
text

when trying to play some sound effects with Qt. This error message is quite misleading. Apart from the obvious circumstance that the audio file is broken, there might be some other causes.

Cause 1: You are trying to play an MP3 file #

MP3 files are not supported. You can convert the MP3 file to a WAV file:

ffmpeg -i ding.mp3 ding.wav
sh

Cause 2: You are passing the path, not URL #

QSoundEffect.setSource is expecting an URL, not a Path or str. So any one of these works:

self.soundEffect.setSource(
    QtCore.QUrl.fromLocalFile(Path(__file__).parent / "ding.wav")
)
self.soundEffect.setSource(QtCore.QUrl.fromLocalFile("./ding.wav"))
self.soundEffect.setSource("file:./ding.wav")
python

But none of these works:

self.soundEffect.setSource("ding.wav")
self.soundEffect.setSource(str(Path(__file__).parent / "ding.wav"))
python

Appendix: Full code #

import sys
from pathlib import Path

from PySide6 import QtCore, QtMultimedia, QtWidgets


class MyWidget(QtWidgets.QWidget):
    def __init__(self, parent=None) -> None:
        super().__init__(parent)

        mainLayout = QtWidgets.QVBoxLayout(self)
        self.soundButton = QtWidgets.QPushButton(text="Play")
        mainLayout.addWidget(self.soundButton)

        self.soundEffect = QtMultimedia.QSoundEffect()
        self.soundEffect.setSource("file:./ding.wav")
        self.soundEffect.setLoopCount(3)

        self.soundButton.clicked.connect(self.soundEffect.play)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    widget = MyWidget()
    widget.resize(200, 100)
    widget.show()
    sys.exit(app.exec())
python
Leave your comments and reactions on GitHub