【问题标题】:QMediaPlayer - play a sound loaded into memoryQMediaPlayer - 播放加载到内存中的声音
【发布时间】:2017-06-29 07:50:36
【问题描述】:

案例 1. 我设法用 QMediaPlayer 播放声音,如下所示:

QMediaPlayer* media = new QMediaPlayer();
media->setMedia("sound.mp3");
media->play();

案例 2. 如果我将声音加载到内存中并像这样播放,一切都很好:

QFile file("sound.mp3");
file.open(QIODevice::ReadOnly);
QByteArray* arr = new QByteArray(file.readAll());
file.close();
QBuffer* buffer = new QBuffer(arr);
buffer->open(QIODevice::ReadOnly);
buffer->seek(0);
QMediaPlayer* media = new QMediaPlayer();
media->setMedia(QMediaContent(), buffer);
media->play();

问题是当我尝试播放像file.txt 这样的不是真实声音的文件时。 在第一种情况下,玩家立即停止。 在第二种情况下,玩家保持状态PlayingState (QMediaPlayer::BufferedMedia, QMediaPlayer::NoError)

文档:

void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream = Q_NULLPTR)

设置当前媒体源。

如果提供了流;将从中读取媒体数据,而不是 解析媒体源。在这种情况下,媒体源可能仍然是 用于解析有关媒体的其他信息,例如 mime 类型。流必须是开放且可读的。

将媒体设置为空 QMediaContent 将导致播放器 丢弃与当前媒体源相关的所有信息,并 停止与该媒体相关的所有 I/O 操作。

因此,如果我使用media->setMedia(QMediaContent(), buffer);,则由于 QMediaContent 为空,媒体播放器将从内存中读取数据而无需附加信息作为 mime 类型。由于缺少 mime 类型,可能 mediaplayer 仍处于 PlayingState,试图播放加载到内存中的文本文件。

所以我尝试将有效的 QMediaContent 与加载的数据结合使用......结果相同:媒体播放器保持在 PlayingState 中而没有任何错误。 media->setMedia(QMediaContent(QUrl::fromLocalFile(QFileInfo(s).absoluteFilePath())), buffer);

如何使用 QMediaPlayer 播放加载到内存中的声音以避免此问题?

【问题讨论】:

    标签: c++ qt qmediaplayer


    【解决方案1】:

    我知道这是一个旧线程,但我遇到了同样的问题,并找到了一种通过设置 wav 标头来解决问题的方法,如下所示:

    QMediaPlayer player;
    QBuffer* buffer = new QBuffer();
    buffer->open(QIODevice::ReadWrite);
    buffer->seek(0);
    
    qint8    RIFF[4];        // RIFF Header Magic header
    qint32   wavfilesize;
    qint8    WAVE[4];        // WAVE Header
    qint8    fmt[4];         // FMT header
    qint32   ChunkSize;      // RIFF Chunk Size (length of above = 16)
    qint16   AudioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw,     257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
    qint16   NCh;      // Number of channels 1=Mono 2=Sterio
    qint32   SamplesPerSec;  // Sampling Frequency in Hz
    qint32   bytesPerSec;    // bytes per second
    qint16   blockAlign;     // 2=16-bit mono, 4=16-bit stereo
    qint16   bitsPerSample;  // Number of bits per sample
    qint8    Subchunk2ID[4]; // "data"  string
    qint32   Subchunk2Size;  // Sampled data length
    QVector<qint16> wavDataL;
    QVector<qint16> wavDataR;
    
    QDataStream out(buffer);
    out.setVersion(QDataStream::Qt_4_8);
    out.setByteOrder(QDataStream::LittleEndian);
    out.setFloatingPointPrecision(QDataStream::SinglePrecision);
    out << RIFF[0] << RIFF[1] << RIFF[2] << RIFF[3]; //4
    out << wavfilesize; // 4
    out << WAVE[0] << WAVE[1] << WAVE[2] << WAVE[3]; // 4
    out << fmt[0] << fmt[1] << fmt[2] << fmt[3]; // 4
    out << ChunkSize; // 4
    out << AudioFormat ; // 2
    out << NCh; // 2
    out << SamplesPerSec; // 4
    out << bytesPerSec; // 4
    out << blockAlign ; // 2
    out << bitsPerSample; // 2
    out << Subchunk2ID[0] << Subchunk2ID[1] << Subchunk2ID[2] << Subchunk2ID[3]; // 4
    out << Subchunk2Size; // 4
    if (NCh == 1){
        for(int ii=0; ii<wavDataL.size(); ii++){
            out << wavDataL[ii]; // 2
        }
    } else if (NCh == 2){
        for(int ii=0; ii<wavDataL.size(); ii++){
            out << wavDataL[ii];
            out << wavDataR[ii];
        }
    }
    buffer->seek(0);
    player.setMedia(QMediaContent(), buffer);
    player.play(); // though I actually played after the media is loaded QObject::connect(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(playClicked()));
    

    我希望这对一些读者有所帮助。

    【讨论】:

      【解决方案2】:
      static QMediaPlayer player;
      player.setMedia(QUrl::fromLocalFile("sound.mp3"));
      player.play();  
      

      【讨论】:

      • 您能解释一下为什么该代码可以解决问题吗?
      • 虽然此代码 sn-p 可能是解决方案,但包含解释确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因
      • 我的经验有限,可以播放文件,如果播放D盘下面的文件,可以换成“D:\\sound.Mp3”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多