如何使用从 UDP 套接字接收的 Gstreamer 在 Qt 应用程序中显示流视频帧

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

我想使用 Qt Multimedia 来显示视频流。 我有 运行

@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

它工作正常。 现在我想在一个终端上执行服务器命令,Qt 应用程序应该扮演客户端的角色,以便播放视频。 我试过一个应用程序,但它不起作用。

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

自 Qt 5.12.2 起,如果使用 GStreamer 后端,您可以将 GStreamer 管道传递给 QMediaPlayer::setMedia()。在您的情况下,setMedia() 的代码应如下所示(未经测试):

...
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\""));
...

查看 documentation 了解更多信息。