4

QMediaPlayer can be used to play a music file i.e., *.wav, *.mp3, etc. But can I use it to play a wave recorded in an array?

From the official documentation, I found QMediaPlayer::setMedia has a parameter stream. I guess this API can be used to play music in an array, however, the documentation doesn't give more details about the stream format or how to construct a stream from a wave array.

(We can assume this array contains float values ranging from -1 to 1 and the sampling rate is a known variable.)

Scientific.RAT
  • 134
  • 1
  • 1
  • 9

1 Answers1

4

The logic is to convert the array into a set of bytes that has some format that is supported by QtMultimedia such as wav, mp3, etc, and then use a QBuffer as a container for those bytes.

import io
import os

import librosa
from scipy.io import wavfile
from PyQt5 import QtCore, QtMultimedia

CURRENT_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)))


def main():
    app = QtCore.QCoreApplication([])

    filename = os.path.join(CURRENT_DIR, "sound.mp3")
    data, fs = librosa.load(filename)

    # convert arrat to bytes
    f = io.BytesIO()
    wavfile.write(f, fs, data)

    # copy the bytes to a QBuffer
    buf = QtCore.QBuffer()
    buf.setData(f.getvalue())
    buf.open(QtCore.QIODevice.ReadOnly)

    player = QtMultimedia.QMediaPlayer()
    player.setMedia(QtMultimedia.QMediaContent(), buf)

    def handle_state_changed(state):
        if state == QtMultimedia.QMediaPlayer.StoppedState:
            QtCore.QCoreApplication.quit()

    player.stateChanged.connect(handle_state_changed)
    player.play()

    app.exec_()


if __name__ == "__main__":
    main()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241