Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowcapture.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 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 <QtMultimedia/qwindowcapture.h>
5
6#include <QtCore/private/qobject_p.h>
7
8#include <QtMultimedia/qmediacapturesession.h>
9#include <QtMultimedia/private/qplatformmediaintegration_p.h>
10#include <QtMultimedia/private/qplatformsurfacecapture_p.h>
11
12QT_BEGIN_NAMESPACE
13
14static QWindowCapture::Error toWindowCaptureError(QPlatformSurfaceCapture::Error error)
15{
16 return static_cast<QWindowCapture::Error>(error);
17}
18
25
26/*!
27 \class QWindowCapture
28 \inmodule QtMultimedia
29 \ingroup multimedia
30 \ingroup multimedia_video
31 \since 6.6
32
33 \brief This class is used for capturing a window.
34
35 The class captures a window. It is managed by
36 the \l QMediaCaptureSession class where the captured window can be displayed
37 in a video preview object or recorded to a file.
38
39 The following snippet shows how to select one of the capturable windows and
40 display the result in a \l QVideoWidget:
41
42 \snippet multimedia-snippets/windowcapturesnippets.cpp Basic setup
43
44 \include qwindowcapture-limitations.qdocinc {content} {Q}
45
46 \sa QMediaCaptureSession, QCapturableWindow
47*/
48/*!
49 \qmltype WindowCapture
50 \nativetype QWindowCapture
51 \inqmlmodule QtMultimedia
52 \ingroup multimedia_qml
53 \ingroup multimedia_video_qml
54 \since 6.6
55
56 \brief This type is used for capturing a window.
57
58 WindowCapture captures a window. It is managed by
59 \l {QtMultimedia::CaptureSession}{CaptureSession} where the
60 captured window can be displayed in a video preview object or
61 recorded to a file.
62
63 The code below shows a simple capture session that captures one of the
64 available windows with WindowCapture and plays it back in a
65 \l {QtMultimedia::VideoOutput}{VideoOutput}.
66
67 \snippet multimedia-snippets/windowcapturesnippets.qml Basic setup
68
69 \include qwindowcapture-limitations.qdocinc {content} {}
70
71 \sa CaptureSession, CapturableWindow
72*/
73
74/*!
75 \enum QWindowCapture::Error
76
77 Enumerates error codes that can be signaled by the QWindowCapture class.
78 errorString() provides detailed information about the error cause.
79
80 \value NoError No error
81 \value InternalError Internal window capturing driver error
82 \value CapturingNotSupported Window capturing is not supported
83 \value CaptureFailed Capturing window failed
84 \value NotFound Selected window not found
85*/
86
87/*!
88 Constructs a new QWindowCapture object with \a parent.
89*/
90QWindowCapture::QWindowCapture(QObject *parent) : QObject(*new QWindowCapturePrivate, parent)
91{
92 Q_D(QWindowCapture);
93
94 qRegisterMetaType<QCapturableWindow>();
95
96 auto platformCapture = QPlatformMediaIntegration::instance()->createWindowCapture(this);
97
98 if (platformCapture) {
99 connect(platformCapture, &QPlatformSurfaceCapture::activeChanged, this,
100 &QWindowCapture::activeChanged);
101 connect(platformCapture, &QPlatformSurfaceCapture::errorChanged, this,
102 &QWindowCapture::errorChanged);
103 connect(platformCapture, &QPlatformSurfaceCapture::errorOccurred, this,
104 [this](QPlatformSurfaceCapture::Error error, const QString &errorString) {
105 emit errorOccurred(toWindowCaptureError(error), errorString);
106 });
107 connect(platformCapture,
108 qOverload<QCapturableWindow>(&QPlatformSurfaceCapture::sourceChanged), this,
109 &QWindowCapture::windowChanged);
110
111 connect(platformCapture, &QPlatformSurfaceCapture::frameRateChanged, this,
112 &QWindowCapture::maximumFrameRateChanged);
113
114 d->platformWindowCapture.reset(platformCapture);
115 }
116}
117
118/*!
119 Destroys the object.
120 */
121QWindowCapture::~QWindowCapture()
122{
123 Q_D(QWindowCapture);
124
125 d->platformWindowCapture.reset();
126
127 if (d->captureSession)
128 d->captureSession->setWindowCapture(nullptr);
129}
130
131/*!
132 \qmlmethod list<CapturableWindow> QtMultimedia::WindowCapture::capturableWindows()
133
134 Returns a list of \l{QtMultimedia::CapturableWindow}{CapturableWindow}
135 objects that are currently available for capturing.
136
137 \note On macOS, invoking this method will trigger the "Screen Recording" permission
138 dialog. If permissions have not yet been granted, this method will return an empty list.
139 Invoking it multiple times will bring this dialog to the foreground.
140*/
141/*!
142 \fn QList<QCapturableWindow> QWindowCapture::capturableWindows()
143
144 Returns a list of \l QCapturableWindow objects that are currently
145 available for capturing.
146
147 \note On macOS, invoking this method will trigger the "Screen Recording" permission
148 dialog. If permissions have not yet been granted, this method will return an empty list.
149 Invoking it multiple times will bring this dialog to the foreground.
150 */
151QList<QCapturableWindow> QWindowCapture::capturableWindows()
152{
153 return QPlatformMediaIntegration::instance()->capturableWindowsList();
154}
155
156/*!
157 Returns the capture session this QWindowCapture is connected to.
158
159 Use \l QMediaCaptureSession::setWindowCapture() to connect the window capture
160 to a session.
161*/
162QMediaCaptureSession *QWindowCapture::captureSession() const
163{
164 Q_D(const QWindowCapture);
165
166 return d->captureSession;
167}
168
169/*!
170 \qmlproperty Window QtMultimedia::WindowCapture::window
171 Describes the window for capturing.
172
173 Setting this property to an invalid window on an active
174 WindowCapture will cause it to go inactive and emit
175 an error.
176
177 \sa capturableWindows
178*/
179
180/*!
181 \property QWindowCapture::window
182 \brief the window for capturing.
183
184 Setting this property to an invalid window on an active
185 QWindowCapture will cause it to go inactive and emit
186 an error.
187
188 \sa QWindowCapture::capturableWindows
189*/
190QCapturableWindow QWindowCapture::window() const
191{
192 Q_D(const QWindowCapture);
193
194 return d->platformWindowCapture ? d->platformWindowCapture->source<QCapturableWindow>()
195 : QCapturableWindow();
196}
197
198void QWindowCapture::setWindow(QCapturableWindow window)
199{
200 Q_D(QWindowCapture);
201
202 if (d->platformWindowCapture)
203 d->platformWindowCapture->setSource(window);
204}
205
206/*!
207 \qmlproperty bool QtMultimedia::WindowCapture::active
208 Describes whether the capturing is currently active.
209
210 \sa start(), stop()
211*/
212
213/*!
214 \property QWindowCapture::active
215 \brief whether the capturing is currently active.
216
217 \sa start(), stop()
218*/
219bool QWindowCapture::isActive() const
220{
221 Q_D(const QWindowCapture);
222
223 return d->platformWindowCapture && d->platformWindowCapture->isActive();
224}
225
226void QWindowCapture::setActive(bool active)
227{
228 Q_D(QWindowCapture);
229
230 if (d->platformWindowCapture)
231 d->platformWindowCapture->setActive(active);
232}
233
234/*!
235 \since 6.12
236 \property QWindowCapture::maximumFrameRate
237 \brief The window capture frame rate upper limit.
238
239 This can be set to override the capture frame rate used by default based on
240 e.g. display refresh rate, but only as an upper limit since window capture
241 produces frames at a variable rate. Setting this higher than the display
242 refresh rate is not recommended and can cause errors.
243
244 Any changes to this property are applied the next time the QWindowCapture
245 goes active.
246*/
247void QWindowCapture::setMaximumFrameRate(std::optional<qreal> frameRate)
248{
249 Q_D(QWindowCapture);
250
251 if (d->platformWindowCapture)
252 d->platformWindowCapture->setFrameRate(frameRate);
253}
254
255std::optional<qreal> QWindowCapture::maximumFrameRate() const
256{
257 Q_D(const QWindowCapture);
258
259 return d->platformWindowCapture ? d->platformWindowCapture->frameRate() : std::nullopt;
260}
261
262void QWindowCapture::resetMaximumFrameRate()
263{
264 setMaximumFrameRate(std::nullopt);
265}
266
267/*!
268 \qmlmethod void QtMultimedia::WindowCapture::start()
269
270 Starts capturing the \l window.
271
272 This is equivalent to setting the \l active property to \c true.
273*/
274
275/*!
276 \fn void QWindowCapture::start()
277
278 Starts capturing the \l window.
279
280 This is equivalent to setting the \l active property to true.
281*/
282
283/*!
284 \qmlmethod void QtMultimedia::WindowCapture::stop()
285
286 Stops capturing.
287
288 This is equivalent to setting the \l active property to \c false.
289*/
290
291/*!
292 \fn void QWindowCapture::stop()
293
294 Stops capturing.
295
296 This is equivalent to setting the \l active property to false.
297*/
298
299/*!
300 \qmlsignal QtMultimedia::WindowCapture::errorChanged()
301
302 This signal is emitted when the \l{error} or \l{errorString} properties are changed.
303
304 This signal is not emitted whenever multiple identical errors are raised. To track such
305 errors, use the signal \l errorOccurred.
306*/
307
308/*!
309 \fn void QWindowCapture::errorChanged()
310
311 This signal is emitted when the \l{error} or \l{errorString} properties are changed.
312
313 This signal is not emitted whenever multiple identical errors are raised. To track such
314 errors, use the signal \l errorOccurred.
315*/
316
317/*!
318 \qmlproperty enumeration QtMultimedia::WindowCapture::error
319 Returns a code of the last error.
320
321 \qmlenumeratorsfrom QWindowCapture::Error
322*/
323
324/*!
325 \property QWindowCapture::error
326 \brief the code of the last error.
327*/
328QWindowCapture::Error QWindowCapture::error() const
329{
330 Q_D(const QWindowCapture);
331
332 return d->platformWindowCapture ? toWindowCaptureError(d->platformWindowCapture->error())
333 : CapturingNotSupported;
334}
335
336/*!
337 \qmlsignal QtMultimedia::WindowCapture::errorOccurred(int error, string errorString)
338
339 Signals when an \a error occurs, along with the \a errorString.
340
341 For the error parameter, see the enumeration table in
342 \l {QtMultimedia::WindowCapture::error}{error} for what values may
343 be passed.
344
345 \sa {QtMultimedia::WindowCapture::error}{error}
346*/
347/*!
348 \fn void QWindowCapture::errorOccurred(QWindowCapture::Error error, const QString &errorString)
349
350 Signals when an \a error occurs, along with the \a errorString.
351*/
352/*!
353 \qmlproperty string QtMultimedia::WindowCapture::errorString
354 Returns a human readable string describing the cause of error.
355*/
356
357/*!
358 \property QWindowCapture::errorString
359 \brief a human readable string describing the cause of error.
360*/
361QString QWindowCapture::errorString() const
362{
363 Q_D(const QWindowCapture);
364
365 return d->platformWindowCapture
366 ? d->platformWindowCapture->errorString()
367 : QLatin1StringView("Capturing is not supported on this platform");
368}
369
370void QWindowCapture::setCaptureSession(QMediaCaptureSession *captureSession)
371{
372 Q_D(QWindowCapture);
373
374 d->captureSession = captureSession;
375}
376
377QPlatformSurfaceCapture *QWindowCapture::platformWindowCapture() const
378{
379 Q_D(const QWindowCapture);
380
381 return d->platformWindowCapture.get();
382}
383
384QT_END_NAMESPACE
385
386#include "moc_qwindowcapture.cpp"
QMediaCaptureSession * captureSession
std::unique_ptr< QPlatformSurfaceCapture > platformWindowCapture