qtgstreamerudpclient

How to display stream video frames in Qt app using Gstreamer receive from UDP socket


I would like to use Qt Multimedia to display a video stream. I have run

@server: $gst-launch-1.0 -v videotestsrc  pattern=ball ! video/x-raw,width=1280,height=720 ! jpegenc ! rtpjpegpay ! udpsink name=sink host=localhost port=34400 sync=false async=false         

@client: $gst-launch-1.0 udpsrc port=34400 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG, payload=(int)26" ! rtpjpegdepay ! jpegdec ! filesink location=a.mp4

Its working fine. now I want to server command on one terminal and Qt app should play the part of client so it will play video. I have tried one app but its not working.

main.cpp:

#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 << "udpsrc" << "port=34400" << "caps=application/x-rtp, media=(string)video, 
    clock-rate=(int)90000, encoding-name=(string)JPEG, payload=(int)26" << "!" << "rtpjpegdepay" 
    << "!" << "jpegdec" << "!" << "filesink location=a.mp4" ;
    
    process->setReadChannel(QProcess::StandardError);
    process->start(program, arguments);

    while (!process->waitForReadyRead()) {}

    player->setMedia(QMediaContent(), process);
    player->play();

    return a.exec();

project.pro:

QT       += core gui multimedia multimediawidgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = video_play_file
TEMPLATE = app


SOURCES += main.cpp\
        dialog.cpp

HEADERS  += dialog.h

FORMS    += dialog.ui

Solution

  • Since Qt 5.12.2, you can pass GStreamer pipelines to QMediaPlayer::setMedia() if the GStreamer backend is used. In your case the code for setMedia() should look something like this (untested):

    ...
    player->setMedia(QUrl("gst-pipeline: udpsrc port=34400 caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG, payload=(int)26\" ! rtpjpegdepay ! jpegdec ! videoconvert ! xvimagesink name=\"qtvideosink\""));
    ...
    

    Take a look at the documentation for more information.