QMediaPlayer not playing from IODevice
-
Hello,
i am trying to read a video/audio file into a QByteArray and then pass it to a QMediaPlayer so it will perform on that stream. I am using the following code-snippet:
QFile file("example.mp4"); file.open(QIODevice::ReadOnly); QByteArray *ba = new QByteArray(); ba->append(file.readAll()); QBuffer *buffer = new QBuffer(ba); qDebug() << "Buffer size:" << buffer->size(); // looks like it loaded the file player->setMedia(QMediaContent(), buffer); player->play();
where player is from type QMediaPlayer.
I'm not sure why it doesn't work. Maybe the problem is in the reading of the file?
Thanks in advance.Edit:
I am able to play the video if i pass it with QUrl::fromLocalFile so i am able to play the video at all, but not from the buffer. -
@onek24
connect to QMediaPlayer's mediaStatusChanged signal and check the reason there. Maybe also check what error() returns, it might already give a clue.Another thing which comes to may head is that you need to open the device (QBuffer) before you set it to the media player instance.
-
I already tried it that way:
QObject::connect(player, &QMediaPlayer::mediaStatusChanged, [=](){ qDebug() << "Media status changed:" << player->mediaStatus(); }); QObject::connect(player, static_cast<void(QMediaPlayer::*)(QMediaPlayer::Error)>(&QMediaPlayer::error), [=](QMediaPlayer::Error error) { qDebug() << "Error occured:" << player->error(); }); QFile file("example.mp4"); file.open(QIODevice::ReadWrite); QByteArray *ba = new QByteArray(); ba->append(file.readAll()); QBuffer *buffer = new QBuffer(ba); qDebug() << "Buffer size:" << buffer->size(); player->setMedia(QMediaContent(), buffer); player->play();
I get the following output:
Buffer size: 85221984 Error occured: QMediaPlayer::ResourceError Media status changed: QMediaPlayer::InvalidMedia Error occured: QMediaPlayer::ResourceError
When i open the buffer before i set it as a media stream, i get the following output:
Buffer size: 85221984 Media status changed: QMediaPlayer::LoadingMedia Media status changed: QMediaPlayer::BufferedMedia
With the open buffer, the output looks exactly like when i have an file which the player managed to play. Altho the player isnt able to play it. Since the media player can play the resource from local file using QUrl, maybe the problem is how i read the file into the buffer?
Edit:
Also tried opening the buffer and writing into the Buffer directly. Also tried it with seek(0) before the write(no reason to do so, but whatever..) and after the write. Also tried it with closing the buffer after i have written into the buffer.
It also seems like the mediaplayer cant get any information for the file. The duration is 0, the resolution is [-1, -1].
-
Aditional Information:
- Windows 7 Professional 64 bit
- Qt 5.6.0
- MSVC 2013, 32 bit
Update:
I also tried this and this doesn't seem to work too. No errors are set but still my duration is 0.
QMediaPlayer* player = new QMediaPlayer(nullptr, QMediaPlayer::StreamPlayback); QFile* file = new QFile("example.mp4"); if (file->open(QFile::ReadOnly)) { player->setMedia(QMediaContent(), file); player->play(); } else { qDebug() << "Unable to open file."; }
-
You need to install a codecs-pack.. e.g. K-Lite .. or other..
-
I don't know, it is just my suggestion... Maybe the reason is that in case of a stream, the QMediaPlayer do not know the format of a video... because it does not read a video header of a file... :)
-
Thanks, but i have already tried creating a QMediaContent from the video file and passing it to my mediaplayer with the buffer. That didn't work either.
Maybe im understanding it wrong. Maybe the stream has to be actual video or audio data instead of a container like mp4 or mkv? And the QMediaContent the actual information for either video or audio data, instead of the full container?
-
Since i was still unable to solve my problem:
Could someone please provide me a working block of code of a QMediaPlayer playing from a buffer or other IODevice? I would like to provide media-data while the QMediaPlayer plays. QTemporaryFile or something similar isn't an option too since it has to be live.
So basically: Playing from an IODevice while the device provides more data during playtime.
Thanks in advance.
-
Hi.
QTemporaryFile can solve your problem
QTemporaryFile is based on QObject, so you can create a pointer to it and set the parent to QApplication:// in main.cpp QTemporaryFile *file = new QTemporaryFile(&app); // use file in application
file will be deleted when app destructor is called. (end of application)
It is better to create a singleton class derived from QObject that wraps temp file IO
use above method for setting its parent as application -
It's no option. I'm trieing to archieve a "straming"-like behaviour.