Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML Desktop Streaming
Qt 6.11 is out! See what's new in the release blog

QML Desktop Streaming

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 4.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mark.lt
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by GrecKo
      #2

      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.

      M 1 Reply Last reply
      2
      • M Offline
        M Offline
        mark.lt
        wrote on last edited by
        #3

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

        1 Reply Last reply
        0
        • GrecKoG GrecKo

          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.

          M Offline
          M Offline
          mark.lt
          wrote on last edited by mark.lt
          #4

          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

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mark.lt
            wrote on last edited by
            #5

            Nevermind, thanks anyway. I simply solved it by using QScreen::grabWindow inside QQuickImageProvider and with a Timer inside QML I request and show the image every 33ms to have 30 frames per second of the screen.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved