首页 > 解决方案 > 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
} 

标签: c++qt

解决方案


正如文档指出的那样:

无效 QMediaPlayer::setSourceDevice(QIODevice *device, const QUrl &sourceUrl = QUrl())

设置当前源设备。

媒体数据将从设备中读取。可以提供 sourceUrl 来解析有关媒体、mime 类型等的附加信息。设备必须是开放且可读的。

对于 macOS,该设备也应该是可搜索的。

注意:该函数在录制完指定的媒体源后立即返回。它不等待媒体完成加载,也不检查错误。监听 mediaStatusChanged() 和 error() 信号,以便在加载媒体时通知,以及加载过程中是否发生错误。

(强调我的)

QMediaPlayer 不知道如何推断文件格式,因此它不会加载它。解决办法是指出它是一个mp3:

player->setSourceDevice(buffer, QUrl("foo.mp3"));

推荐阅读