0
votes

Case 1. I managed to play a sound with QMediaPlayer like this:

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

Case 2. Everything is ok also if I load the sound into memory and play it like this:

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();

The problem is when I try to play a file that is not a real sound like file.txt. In first case the player stops immediately. In the second case the player remains in state PlayingState (QMediaPlayer::BufferedMedia, QMediaPlayer::NoError)

Documentation:

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

Sets the current media source.

If a stream is supplied; media data will be read from it instead of resolving the media source. In this case the media source may still be used to resolve additional information about the media such as mime type. The stream must be open and readable.

Setting the media to a null QMediaContent will cause the player to discard all information relating to the current media source and to cease all I/O operations related to that media.

So, if I use media->setMedia(QMediaContent(), buffer); then the mediaplayer will read data from memory without additional information as mime type because of null QMediaContent. Maybe mediaplayer remain in PlayingState because of lack of mime type, trying to play a text file loaded in memory.

So I try to use a valid QMediaContent in conjunction with the loaded data... the same result: mediaplayer remain in PlayingState without any error. media->setMedia(QMediaContent(QUrl::fromLocalFile(QFileInfo(s).absoluteFilePath())), buffer);

How can I play a sound loaded into memory with QMediaPlayer avoiding this issue?

2

2 Answers

0
votes

I know this is an old thread, but I came across the same issue and found a way to work around by setting a wav header just like as follows:

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()));

I hope this helps some readers.

-2
votes
static QMediaPlayer player;
player.setMedia(QUrl::fromLocalFile("sound.mp3"));
player.play();