Is there a way in Qt to force QMediaPlayer to buff

2019-04-06 19:38发布

问题:

When you load a file into a QMediaPlayer instance, it does not automatically buffer the file. The MediaStatus remains NoMedia until you play the file using play(), only after which it will end up as BufferedMedia. I can't find any way in the documentation to force the player to buffer the file without playing it - is there any way to do this?

Right now I'm planning on muting it, playing the file, then stopping it again and unmuting it, but it makes me feel dirty. Surely there is a better way to do this?

This is necessary, by the way, because I can't retrieve the duration until the file has been buffered, and I need the duration to select a position in the track to start playing from.

Thanks

回答1:

The MediaStatus remains NoMedia until you play the file using play()

Not in Qt 5, and its not the reason you can't know 'duration' and set 'position'. When you set the media with setMedia it does not wait for the media to finish loading (and does not check for errors). a signal mediaStatusChanged() is emitted when media is loaded, so listen to that signal and error() signal to be notified when the media loading is finished.

connect(player, &QMediaPlayer::mediaStatusChanged, this, [=]() {
    qDebug() << "Media Status:" << player->mediaStatus();

I need the duration to select a position in the track to start playing from.

Once the media file is loaded and before play, you can check the duration and you can set the player to desired position, but this is best to do once the duration changes from 0 to the media duration after loading, so connect to signal durationChanged():

connect(player, &QMediaPlayer::durationChanged, this, [&](qint64 duration) {
    qDebug() << "Media duration = " << duration;
    player->setPosition(duration/2);
    qDebug() << "Set position:" << player->position();
});

I can't find any way in the documentation to force the player to buffer the file without playing it - is there any way to do this?

Yes, create a buffer from file then set mediacontent to your buffer (but this is not required to do the above, it just provides a faster way to seek in media):

QString fileName=QFileDialog::getOpenFileName(this,"Select:","","( *.mp3)");
QFile mediafile(fileName);
mediafile.open(QIODevice::ReadOnly);
QByteArray *ba = new QByteArray();
ba->append(mediafile.readAll());
QBuffer *buffer = new QBuffer(ba);
buffer->open(QIODevice::ReadOnly);
buffer->reset(); //seek 0
player->setMedia(QMediaContent(), buffer);