Unable to playback a custom stream with QMediaPlayer
-
Hi all,
I searched thoroughly to find an answer to my problem but no other post has been helpful so far.
I am developing an application in Qt where I need to playback a video stream which is received through a custom protocol. I found myself trying in every possible way to feed these packets in QMediaPlayer with no success. My idea was to write incoming packets in a QBuffer and then read them from QMediaPlayer. Follows my trial:/// VideoPlayer.h class VideoPlayer : public QWidget { public slots: void play(); void handlePacket(QByteArray); [...] private: QMediaPlayer mediaPlayer; QBuffer buffer; }; /// VideoPlayer.cpp VideoPlayer::VideoPlayer(QWidget *parent) : QWidget(parent) , mediaPlayer(0, (QMediaPlayer::StreamPlayback)) { buffer.open(QBuffer::ReadWrite); } void VideoPlayer::handlePacket(QByteArray packet) { buffer.buffer().append(packet); } void VideoPlayer::play() { mediaPlayer.setMedia(QMediaContent(), &buffer); mediaPlayer.play(); }
With the above QMediaPlayer plays back data in the buffer at the moment of calling
mediaPlayer.setMedia(QMediaContent(), &buffer)
but seems to ignore that new packets were appended to the buffer. May it be because I am accessing the internal QByteArray directly (I checked that QIODevice::readyRead signal is emitted and it is)? I found no way to make QMediaPlayer play new incoming data other than calling setMedia again. Is there a way to notify QMediaPlayer that media length has changed?Is there an easier way to make this? I thought about writing my own QIODevice or somehow integrate my packet receiver in the Qt framework to provide my custom stream as a QMediaContent?
Are there any other libraries or methods which would allow me to accomplish this task?
I am using Qt 5.4.
Thanks in advance for your help. -
I've faced the same problem during creating a POC of playing the video stream with QT/QML. It did not work with QBuffer for me as well. I tried to append the chunks of the video file to the buffer from another thread during playing. QMediaPlayer played only first chunk and stopped. I assume that this is not correct way to emulate the stream. I've just managed to play stream in QML VideoOutput with C++ QMediaPlayer using the
setMedia(QUrl("http://127.0.0.1:8080"));
The stream was created by VLC media player using the HTTP to the 8080 port. I've also succeeded in playing the stream created by VLC media player to local file by passing it to QMediaPlayer viasetMedia(QMediaContent(), &localFile);
. Both approaches work well for me. -
I think it is because QByteArray is seekable and not sequential. You need to make own QIODevice with override this functions:
void close() override; qint64 bytesAvailable() const override; bool isSequential () const override { return true; } qint64 size() const override { return bytesAvailable(); } qint64 readData(char *data, qint64 maxSize) override; qint64 writeData(const char *data, qint64 maxSize) override; bool atEnd() const override { return false; } qint64 pos() const override { return 0; } virtual bool open(QIODevice::OpenMode mode) override; signals: void readyRead();