Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 to stdout 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. :/


  • Lifetime Qt Champion

    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 and boost while we try hard to avoid such dependencies.

    As I managed to make gstreamer work a little using QProcess and QMediaPlayer, I was hoping there was a way to fix the problem for different video sources like videotestsrc 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 the gst-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.



  • @ADGB great your issue seems solved. If so, please don't forget to mark your post as such. Thanks.


Log in to reply