c++ - Qt 6.2:QMediaPlayer 和 QByteArray
问题描述
再会。有人在 Qt 6.2 中尝试过 QMediaPlayer 吗?我正在尝试此代码,但媒体状态始终保持为“NoMedia”并且没有任何声音:)。完整测试项目:https ://github.com/avttrue/MediaPlayerTest
#include "mainwindow.h"
#include <QDebug>
#include <QBuffer>
#include <QFile>
#include <QAudioOutput>
#include <QMediaPlayer>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QFile file("../test/Bankrobber.mp3");
if(!file.open(QIODevice::ReadOnly))
qDebug() << "File not opened";
qDebug() << "File size:" << file.size(); // File size: 11181085
QByteArray ba = file.readAll();
qDebug() << "ByteArray size:" << ba.size(); // ByteArray size: 11181085
QBuffer* buffer = new QBuffer(this);
buffer->setData(ba);
if(!buffer->open(QIODevice::ReadOnly))
qDebug() << "Buffer not opened";
qDebug() << "Buffer size:" << buffer->size(); // Buffer size: 11181085
buffer->seek(qint64(0));
auto audioOutput = new QAudioOutput(this);
auto player = new QMediaPlayer(this);
player->setAudioOutput(audioOutput);
audioOutput->setVolume(50);
player->setSourceDevice(buffer);
qDebug() << "Device:" << player->sourceDevice(); // Device: QBuffer(0x563180493020)
QObject::connect(player, &QMediaPlayer::mediaStatusChanged,
[=](QMediaPlayer::MediaStatus status)
{ qDebug() << "MediaStatus:" << player->mediaStatus() << "|" << status; });
QObject::connect(player, &QMediaPlayer::errorOccurred,
[=](QMediaPlayer::Error error)
{ qDebug() << "Error:" << player->errorString() << "|" << error; });
QObject::connect(player, &QMediaPlayer::playbackStateChanged,
[=](QMediaPlayer::PlaybackState state)
{ qDebug() << "PlaybackState:" << player->playbackState() << "|" << state; });
player->play();
qDebug() << "MediaStatus:" << player->mediaStatus(); // MediaStatus: QMediaPlayer::NoMedia
}
解决方案
正如文档指出的那样:
无效 QMediaPlayer::setSourceDevice(QIODevice *device, const QUrl &sourceUrl = QUrl())
设置当前源设备。
媒体数据将从设备中读取。可以提供 sourceUrl 来解析有关媒体、mime 类型等的附加信息。设备必须是开放且可读的。
对于 macOS,该设备也应该是可搜索的。
注意:该函数在录制完指定的媒体源后立即返回。它不等待媒体完成加载,也不检查错误。监听 mediaStatusChanged() 和 error() 信号,以便在加载媒体时通知,以及加载过程中是否发生错误。
(强调我的)
QMediaPlayer 不知道如何推断文件格式,因此它不会加载它。解决办法是指出它是一个mp3:
player->setSourceDevice(buffer, QUrl("foo.mp3"));
推荐阅读
- visual-studio - 使用 Visual Studio 调试器调试使用 bazel 构建的 windows exe 的发布版本
- nginx - SSL_do_handshake() 在 cloudflare 后面使用 nginx-proxy 失败
- fpga - HLS:如何分离 AXI4 信号
- javascript - 如何使用自定义错误消息捕获“TypeError:无法读取未定义的属性(读取'0')”?
- spring - Kotlin Spring:未解决的参考方法
- python - 获取重复行和文件的其余部分[大文件50G]
- javascript - 如何动态导入 NextJs 页面数据(数组)而不是整个组件
- html - 如何垂直居中搜索栏?
- javascript - 如何摆脱“错误:Windows 上的 SPAWN ls ENONET”?
- symfony - Symfony 5.3 Mailer 设置环境变量无法正确读取