Qt 6.2:QMediaPlayer 和 QByteArray
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
}
您使用的函数 setSourceDevice() 与您的想法不符?
也许你想要 setSource() 而不是?
Qt 有很棒的文档:
https://doc.qt.io/qt-6/qmediaplayer.html#setSourceDevice
再好不过的例子:
player = new QMediaPlayer;
audioOutput = new QAudioOutput;
player->setAudioOutput(audioOutput);
connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
player->setSource(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
audioOutput->setVolume(50);
player->play();
可能这是变体,但我觉得不好:
QTemporaryFile tfile;
if (!tfile.open())
qDebug() << "TemporaryFile not opened";
else
{
qDebug() << "TemporaryFile writed:" << tfile.write(ba);
if(tfile.size() != ba.size())
qDebug() << "TemporaryFile not complited";
else
player->setSource(QUrl::fromLocalFile(tfile.fileName()));
}
正如文档指出的那样:
void QMediaPlayer::setSourceDevice(QIODevice *device, const QUrl
&sourceUrl = QUrl())
Sets the current source device.
The media data will be read from device. The sourceUrl can be provided
to resolve additional information about the media, mime type etc. The
device must be open and readable.
For macOS the device should also be seek-able.
Note: This function returns immediately after recording the specified
source of the media. It does not wait for the media to finish loading
and does not check for errors. Listen for the mediaStatusChanged() and
error() signals to be notified when the media is loaded, and if an
error occurs during loading.
(强调我的)
QMediaPlayer 不知道如何推断文件格式,因此不会加载它。解决方法是指出是mp3:
player->setSourceDevice(buffer, QUrl("foo.mp3"));
美好的一天。 有没有人已经在 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
}
您使用的函数 setSourceDevice() 与您的想法不符? 也许你想要 setSource() 而不是?
Qt 有很棒的文档: https://doc.qt.io/qt-6/qmediaplayer.html#setSourceDevice
再好不过的例子:
player = new QMediaPlayer;
audioOutput = new QAudioOutput;
player->setAudioOutput(audioOutput);
connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
player->setSource(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
audioOutput->setVolume(50);
player->play();
可能这是变体,但我觉得不好:
QTemporaryFile tfile;
if (!tfile.open())
qDebug() << "TemporaryFile not opened";
else
{
qDebug() << "TemporaryFile writed:" << tfile.write(ba);
if(tfile.size() != ba.size())
qDebug() << "TemporaryFile not complited";
else
player->setSource(QUrl::fromLocalFile(tfile.fileName()));
}
正如文档指出的那样:
void QMediaPlayer::setSourceDevice(QIODevice *device, const QUrl &sourceUrl = QUrl())
Sets the current source device.
The media data will be read from device. The sourceUrl can be provided to resolve additional information about the media, mime type etc. The device must be open and readable.
For macOS the device should also be seek-able.
Note: This function returns immediately after recording the specified source of the media. It does not wait for the media to finish loading and does not check for errors. Listen for the mediaStatusChanged() and error() signals to be notified when the media is loaded, and if an error occurs during loading.
(强调我的)
QMediaPlayer 不知道如何推断文件格式,因此不会加载它。解决方法是指出是mp3:
player->setSourceDevice(buffer, QUrl("foo.mp3"));