QML Desktop Streaming



  • Hi, I have the following problem: I need to capture part of the desktop, specifically of the second monitor, given an x, an y, the width and the height. My question is: is it possible to stream a part of desktop and show it inside a box in a qml project.
    My first thought is to somehow find a c++ function that allows to do screenshot of my second monitor and after importing it inside qml I would call it like every 0.2 seconds with Timer to do screenshot and show it in a box in QML.

    Thank you.



  • You can use QScreen::grabWindow for that.

    To use that in QML, you could feed this in a VideoOutput.

    To do that you would have to put your QObject derived class instance as the source of the VideoOutput : http://doc.qt.io/qt-5/qml-qtmultimedia-videooutput.html#source-prop
    Your class needs to have a Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY videoSurfaceChange)

    In your setVideoSurface method, you need to call the start method of QAbstractVideoSurface with a correct format (your size and the pixelformat, pixelformat should be QVideoFrame::Format_ARGB32 for desktop I guess).

    And then when you want to update the VideoOutput (via a QTimer for example), you call the present method of QAbstractVideoSurface with a QVideoFrame you constructed from the QPixmap you got in QScreen::grabWindow.



  • Thank you for the instructions, I'm new to all of this so I hope to get to the bottom of this :D



  • Hi, I need some help. I really don't have idea how to do it. This is what I have done so far:
    videostream.h

    #ifndef VIDEOSTREAM_H
    #define VIDEOSTREAM_H
    #include <QObject>
    #include <QAbstractVideoSurface>
    
    class videoStream: public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY videoSurfaceChange)
    
    public:
    
        explicit videoStream(QObject *parent = nullptr);
        QAbstractVideoSurface* videoSurface();
        void setVideoSurface(const QAbstractVideoSurface &videoSurface);
        void updateScreen();
    
    signals:
        void videoSurfaceChange();
    
    private:
        QAbstractVideoSurface* m_videoSurface;
    };
    
    #endif // VIDEOSTREAM_H
    
    

    videoStream.cpp

    #include "videostream.h"
    #include <QVideoSurfaceFormat>
    #include <QSize>
    #include <QGuiApplication>
    #include <QWidget>
    #include <QWindow>
    
    videoStream::videoStream(QObject *parent):
        QObject(parent)
    {
    
    }
    QAbstractVideoSurface* videoStream::videoSurface()
    {
        return m_videoSurface;
    }
    
    void videoStream::setVideoSurface(const QAbstractVideoSurface &videoSurface)
    {
        QVideoSurfaceFormat* qvideosurfaceformat;
        qvideosurfaceformat=new QVideoSurfaceFormat(QSize(800,600),QVideoFrame::Format_ARGB32);
    
        videoSurface.start(&qvideosurfaceformat);
    
    }
    
    void videoStream::updateScreen(){
        QScreen *screen = QGuiApplication::primaryScreen();
        if (QWindow *window = QWidget::windowHandle())
            screen = window->QWindow::screen();
        if (!screen)
            return;
    
        m_videoSurface->present(screen->grabWindow(0));
    }
    
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include "videostream.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<BackEnd>("videostream", 1, 0, "VideoStream");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    
    

    main.qml

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtMultimedia 5.9
    import videostream 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        VideoStream{
            id:video_stream
        }
    
        Rectangle {
            width: 800
            height: 600
    
            VideoOutput {
                id: videoOutput
                source: video_stream.videoStream
                anchors.fill: parent
            }
        }
    Timer {
            interval: 500; running: true; repeat: true
            onTriggered: video_stream.updateScreen
      }
    }
    
    

    A part from errors with these lines

    videoSurface.start(&qvideosurfaceformat);
    
    if (QWindow *window = QWidget::windowHandle())
    
    m_videoSurface->present(screen->grabWindow(0));
    

    I have no idea what should I do


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.