Displaying video stream using Qt Multimedia and GStreamer process
-
Hello here.
I would like to display a video resulting from a "complex" GStreamer pipeline within a Qt GUI.
Although Qt seems to have GStreamer backends and libraries, it appears easier to use the Qt Multimedia module and rely on the QMediaPlayer.setMedia() method. Particularly, as this function accepts any QIODevice stream, I thought I could use a QProcess to call the
gstreamer
command, redirect the output tostdout
and let Qt take care of the rest.This is working pretty well using this video sample.
#include <QApplication> #include <QMediaPlayer> #include <QWidget> #include <QVideoWidget> #include <QBoxLayout> #include <QProcess> #include <QDebug> int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget *window = new QWidget; QVideoWidget *videoWidget = new QVideoWidget; QBoxLayout *layout = new QVBoxLayout; QMediaPlayer *player = new QMediaPlayer; QProcess *process = new QProcess; layout->addWidget(videoWidget); window->setLayout(layout); window->show(); player->setVideoOutput(videoWidget); QString program = "gst-launch-1.0"; QStringList arguments; arguments << "-v" << "filesrc" << "location=/home/adgb/Desktop/video.mp4" << "!" << "filesink" << "location=/dev/stdout"; process->start(program, arguments); process->waitForReadyRead(); player->setMedia(QMediaContent(), process); player->play(); return a.exec(); }
However, I have trouble as soon as I try to replace the file source with
videotestsrc
.arguments << "-v" << "videotestsrc" << "!" << "video/x-raw,width=1280,height=720" << "!" << "filesink" << "location=/dev/stdout";
I tried with several different pipelines, but it always results in an error like "Stream doesn't contain enough data" or "Could not determine type of stream".
I wanted to use the
videotestsrc
as a first step, before implementing my whole pipeline implying live-streaming of remote camera, but I struggle to make even a simple command like this to work.Could anyone help me please? I am stuck on this issue since too many hours. :/
-
Hi and welcome to devnet,
Since you have a custom GStreamer pipeline, you could consider using the QtGStreamer module.
-
Hi and welcome to devnet,
Since you have a custom GStreamer pipeline, you could consider using the QtGStreamer module.
@SGaist Thanks for your answer.
I am aware of QtGstreamer, unfortunately the installation procedure is difficult, requiring
cmake
andboost
while we try hard to avoid such dependencies.As I managed to make
gstreamer
work a little usingQProcess
andQMediaPlayer
, I was hoping there was a way to fix the problem for different video sources likevideotestsrc
and others.mp4
files (I realized the one I linked in my post worked fine, but error appears for others videos samples, worths investigating). -
Quick update about the issue I had to display
.mp4
video samples.This was because of mixed content on the
/dev/stdout
, I guess GStreamer outputs sometime decoding information (figured out using thegst-launch-1.0
command line in a terminal) so Qt could not understand what type of data it received, and sometimes failed with an error "This appears to be a text file".As a workaround, just use
stderr
instead:arguments << "-v" << "filesrc" << "location=/home/adgb/Desktop/sample.mp4" << "!" << "filesink" << "location=/dev/stderr"; process->setReadChannel(QProcess::StandardError);
But this does not seem to fix the
videotestsrc
though. -
Finally figured out how to display the
videotestsrc
stream!arguments << "-v" << "videotestsrc" << "!" << "video/x-raw,width=1280,height=720" << "!" << "x264enc" << "!" << "filesink" << "location=/dev/stderr";
The
QMediaPlayer
seems to expect binary and encoded input. It makes plain sense actually as the first purpose of this class is to display video files. I guess it failed because I tried to feed decoded data. -
Finally figured out how to display the
videotestsrc
stream!arguments << "-v" << "videotestsrc" << "!" << "video/x-raw,width=1280,height=720" << "!" << "x264enc" << "!" << "filesink" << "location=/dev/stderr";
The
QMediaPlayer
seems to expect binary and encoded input. It makes plain sense actually as the first purpose of this class is to display video files. I guess it failed because I tried to feed decoded data.@ADGB great your issue seems solved. If so, please don't forget to mark your post as such. Thanks.
-
Finally figured out how to display the
videotestsrc
stream!arguments << "-v" << "videotestsrc" << "!" << "video/x-raw,width=1280,height=720" << "!" << "x264enc" << "!" << "filesink" << "location=/dev/stderr";
The
QMediaPlayer
seems to expect binary and encoded input. It makes plain sense actually as the first purpose of this class is to display video files. I guess it failed because I tried to feed decoded data.@ADGB ,
I have tried your example.
What I have observed is while running you example application it is opening two output widgets. One test and other for for the pipeline.
Did you observed the same issue?
If yes, how you resolved the issue? -
@ADGB ,
I have tried your example.
What I have observed is while running you example application it is opening two output widgets. One test and other for for the pipeline.
Did you observed the same issue?
If yes, how you resolved the issue?