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 | /*! |
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 | |
72 | QScreenCapture::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 | |
97 | QScreenCapture::~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 | */ |
127 | QMediaCaptureSession *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 | */ |
143 | void QScreenCapture::setActive(bool active) |
144 | { |
145 | Q_D(QScreenCapture); |
146 | |
147 | if (d->platformScreenCapture) |
148 | d->platformScreenCapture->setActive(active); |
149 | } |
150 | |
151 | bool 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 | |
168 | void QScreenCapture::setScreen(QScreen *screen) |
169 | { |
170 | Q_D(QScreenCapture); |
171 | |
172 | if (d->platformScreenCapture) |
173 | d->platformScreenCapture->setSource(QPlatformSurfaceCapture::ScreenSource(screen)); |
174 | } |
175 | |
176 | QScreen *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 | */ |
194 | QScreenCapture::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 | */ |
216 | QString 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 | */ |
236 | void QScreenCapture::setCaptureSession(QMediaCaptureSession *captureSession) |
237 | { |
238 | Q_D(QScreenCapture); |
239 | |
240 | d->captureSession = captureSession; |
241 | } |
242 | |
243 | /*! |
244 | \internal |
245 | */ |
246 | class QPlatformSurfaceCapture *QScreenCapture::platformScreenCapture() const |
247 | { |
248 | Q_D(const QScreenCapture); |
249 | |
250 | return d->platformScreenCapture.get(); |
251 | } |
252 | |
253 | QT_END_NAMESPACE |
254 | |
255 | #include "moc_qscreencapture.cpp" |
256 | |