1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qscreencapture.h"
5#include "qmediacapturesession.h"
6#include <private/qplatformmediaintegration_p.h>
7#include <private/qplatformsurfacecapture_p.h>
8#include <private/qobject_p.h>
9
10QT_BEGIN_NAMESPACE
11
12static QScreenCapture::Error toScreenCaptureError(QPlatformSurfaceCapture::Error error)
13{
14 return static_cast<QScreenCapture::Error>(error);
15}
16
17class QScreenCapturePrivate : public QObjectPrivate
18{
19public:
20 QMediaCaptureSession *captureSession = nullptr;
21 std::unique_ptr<QPlatformSurfaceCapture> platformScreenCapture;
22};
23
24/*!
25 \class QScreenCapture
26 \inmodule QtMultimedia
27 \ingroup multimedia
28 \ingroup multimedia_video
29 \since 6.5
30
31 \brief This class is used for capturing a screen.
32
33 The class captures a screen. It is managed by
34 the QMediaCaptureSession class where the captured screen can be displayed
35 in a video preview object or recorded to a file.
36
37 \snippet multimedia-snippets/media.cpp Media recorder
38*/
39/*!
40 \qmltype ScreenCapture
41 \instantiates QScreenCapture
42 \brief This type is used for capturing a screen.
43
44 \inqmlmodule QtMultimedia
45 \ingroup multimedia_qml
46 \ingroup multimedia_video_qml
47
48 ScreenCapture captures a screen. It is managed by
49 MediaCaptureSession where the captured screen can be displayed
50 in a video preview object or recorded to a file.
51
52 \since 6.5
53 The code below shows a simple capture session with ScreenCapture playing
54 back the captured primary screen view in VideoOutput.
55
56\qml
57 CaptureSession {
58 id: captureSession
59 screenCapture: ScreenCapture {
60 id: screenCapture
61 active: true
62 }
63 videoOutput: VideoOutput {
64 id: videoOutput
65 }
66 }
67\endqml
68
69 \sa ScreenCapture, CaptureSession
70*/
71
72QScreenCapture::QScreenCapture(QObject *parent)
73 : QObject(*new QScreenCapturePrivate, parent)
74{
75 Q_D(QScreenCapture);
76
77 auto platformCapture = QPlatformMediaIntegration::instance()->createScreenCapture(this);
78 if (platformCapture) {
79 connect(sender: platformCapture, signal: &QPlatformSurfaceCapture::activeChanged, context: this,
80 slot: &QScreenCapture::activeChanged);
81 connect(sender: platformCapture, signal: &QPlatformSurfaceCapture::errorChanged, context: this,
82 slot: &QScreenCapture::errorChanged);
83 connect(sender: platformCapture, signal: &QPlatformSurfaceCapture::errorOccurred, context: this,
84 slot: [this](QPlatformSurfaceCapture::Error error, QString errorString) {
85 emit errorOccurred(error: toScreenCaptureError(error), errorString);
86 });
87
88 connect(sender: platformCapture,
89 signal: qOverload<QPlatformSurfaceCapture::ScreenSource>(
90 &QPlatformSurfaceCapture::sourceChanged),
91 context: this, slot: &QScreenCapture::screenChanged);
92
93 d->platformScreenCapture.reset(p: platformCapture);
94 }
95}
96
97QScreenCapture::~QScreenCapture()
98{
99 Q_D(QScreenCapture);
100
101 // Reset platformScreenCapture in the destructor to avoid having broken ref in the object.
102 d->platformScreenCapture.reset();
103
104 if (d->captureSession)
105 d->captureSession->setScreenCapture(nullptr);
106}
107
108/*!
109 \enum QScreenCapture::Error
110
111 Enumerates error codes that can be signaled by the QScreenCapture class.
112 errorString() provides detailed information about the error cause.
113
114 \value NoError No error
115 \value InternalError Internal screen capturing driver error
116 \value CapturingNotSupported Capturing is not supported
117 \value CaptureFailed Capturing screen failed
118 \value NotFound Selected screen not found
119*/
120
121/*!
122 Returns the capture session this QScreenCapture is connected to.
123
124 Use QMediaCaptureSession::setScreenCapture() to connect the camera to
125 a session.
126*/
127QMediaCaptureSession *QScreenCapture::captureSession() const
128{
129 Q_D(const QScreenCapture);
130
131 return d->captureSession;
132}
133
134/*!
135 \qmlproperty bool QtMultimedia::ScreenCapture::active
136 Describes whether the capturing is currently active.
137*/
138
139/*!
140 \property QScreenCapture::active
141 \brief whether the capturing is currently active.
142*/
143void QScreenCapture::setActive(bool active)
144{
145 Q_D(QScreenCapture);
146
147 if (d->platformScreenCapture)
148 d->platformScreenCapture->setActive(active);
149}
150
151bool QScreenCapture::isActive() const
152{
153 Q_D(const QScreenCapture);
154
155 return d->platformScreenCapture && d->platformScreenCapture->isActive();
156}
157
158/*!
159 \qmlproperty Screen QtMultimedia::ScreenCapture::screen
160 Describes the screen for capturing.
161*/
162
163/*!
164 \property QScreenCapture::screen
165 \brief the screen for capturing.
166*/
167
168void QScreenCapture::setScreen(QScreen *screen)
169{
170 Q_D(QScreenCapture);
171
172 if (d->platformScreenCapture)
173 d->platformScreenCapture->setSource(QPlatformSurfaceCapture::ScreenSource(screen));
174}
175
176QScreen *QScreenCapture::screen() const
177{
178 Q_D(const QScreenCapture);
179
180 return d->platformScreenCapture
181 ? d->platformScreenCapture->source<QPlatformSurfaceCapture::ScreenSource>()
182 : nullptr;
183}
184
185/*!
186 \qmlproperty string QtMultimedia::ScreenCapture::error
187 Returns a code of the last error.
188*/
189
190/*!
191 \property QScreenCapture::error
192 \brief the code of the last error.
193*/
194QScreenCapture::Error QScreenCapture::error() const
195{
196 Q_D(const QScreenCapture);
197
198 return d->platformScreenCapture ? toScreenCaptureError(error: d->platformScreenCapture->error())
199 : CapturingNotSupported;
200}
201
202/*!
203 \fn void QScreenCapture::errorOccurred(QScreenCapture::Error error, const QString &errorString)
204
205 Signals when an \a error occurs, along with the \a errorString.
206*/
207/*!
208 \qmlproperty string QtMultimedia::ScreenCapture::errorString
209 Returns a human readable string describing the cause of error.
210*/
211
212/*!
213 \property QScreenCapture::errorString
214 \brief a human readable string describing the cause of error.
215*/
216QString QScreenCapture::errorString() const
217{
218 Q_D(const QScreenCapture);
219
220 return d->platformScreenCapture ? d->platformScreenCapture->errorString()
221 : QLatin1StringView("Capturing is not support on this platform");
222}
223/*!
224 \fn void QScreenCapture::start()
225
226 Starts screen capture.
227*/
228/*!
229 \fn void QScreenCapture::stop()
230
231 Stops screen capture.
232*/
233/*!
234 \internal
235*/
236void QScreenCapture::setCaptureSession(QMediaCaptureSession *captureSession)
237{
238 Q_D(QScreenCapture);
239
240 d->captureSession = captureSession;
241}
242
243/*!
244 \internal
245*/
246class QPlatformSurfaceCapture *QScreenCapture::platformScreenCapture() const
247{
248 Q_D(const QScreenCapture);
249
250 return d->platformScreenCapture.get();
251}
252
253QT_END_NAMESPACE
254
255#include "moc_qscreencapture.cpp"
256

source code of qtmultimedia/src/multimedia/recording/qscreencapture.cpp