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