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
Forum Updated to NodeBB v4.3 + New Features

QML Desktop Streaming

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 3.2k 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