如何在不将其保存到文件的情况下在 Qt 中播放一个 numpy 数组?
How to play a numpy array in Qt without saving it to a file?
QMediaPlayer
可以用来播放*.wav、*.mp3等音乐文件,但是我可以用它来播放记录在数组中的波形吗?
从官方文档中,我发现QMediaPlayer::setMedia
有一个参数stream
。我想这个 API 可以用来播放数组中的音乐,但是,文档没有提供有关流格式或如何从波形数组构造流的更多详细信息。
(我们可以假设这个数组包含范围从 -1 到 1 的浮点值,并且采样率是一个已知变量。)
逻辑是将数组转换为一组字节,这些字节具有 QtMultimedia 支持的某种格式,例如 wav、mp3 等,然后使用 QBuffer 作为这些字节的容器。
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()
QMediaPlayer
可以用来播放*.wav、*.mp3等音乐文件,但是我可以用它来播放记录在数组中的波形吗?
从官方文档中,我发现QMediaPlayer::setMedia
有一个参数stream
。我想这个 API 可以用来播放数组中的音乐,但是,文档没有提供有关流格式或如何从波形数组构造流的更多详细信息。
(我们可以假设这个数组包含范围从 -1 到 1 的浮点值,并且采样率是一个已知变量。)
逻辑是将数组转换为一组字节,这些字节具有 QtMultimedia 支持的某种格式,例如 wav、mp3 等,然后使用 QBuffer 作为这些字节的容器。
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()