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
qwasmmediacapturesession.cpp
Go to the documentation of this file.
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
5#include "mediacapture/qwasmimagecapture_p.h"
6#include "private/qcapturablewindow_p.h"
7#include <QUuid>
8#include "private/qplatformcapturablewindows_p.h"
9
10#include "qwasmcamera_p.h"
13
14#include <private/qplatformmediaintegration_p.h>
15#include <private/qwasmmediadevices_p.h>
16
17
18Q_LOGGING_CATEGORY(qWasmMediaCaptureSession, "qt.multimedia.wasm.capturesession")
19
20QWasmMediaCaptureSession::QWasmMediaCaptureSession() :
21 QPlatformMediaCaptureSession()
22{
23 QWasmMediaDevices::instance()->initDevices();
24}
25
27
29{
30 return m_camera;
31}
32
33void QWasmMediaCaptureSession::setCamera(QPlatformCamera *camera)
34{
35 if (!camera) {
36 if (m_camera == nullptr)
37 return;
38 m_camera->setActive(false);
39 m_camera = nullptr;
40 } else {
41 QWasmCamera *wasmCamera = static_cast<QWasmCamera *>(camera);
42 if (m_camera == wasmCamera)
43 return;
44 m_camera = wasmCamera;
45 m_camera->setCaptureSession(this);
46 }
47 emit cameraChanged();
48}
49
51{
52 return m_imageCapture;
53}
54
55void QWasmMediaCaptureSession::setImageCapture(QPlatformImageCapture *imageCapture)
56{
57 if (m_imageCapture == imageCapture)
58 return;
59
60 if (m_imageCapture)
61 m_imageCapture->setCaptureSession(nullptr);
62
63 m_imageCapture = static_cast<QWasmImageCapture *>(imageCapture);
64
65 if (m_imageCapture) {
66 m_imageCapture->setCaptureSession(this);
67
68 emit imageCaptureChanged();
69 }
70}
71
73{
74 return m_mediaRecorder;
75}
76
77void QWasmMediaCaptureSession::setMediaRecorder(QPlatformMediaRecorder *mediaRecorder)
78{
79 if (m_mediaRecorder == mediaRecorder)
80 return;
81
82 if (m_mediaRecorder)
83 m_mediaRecorder->setCaptureSession(nullptr);
84
85 m_mediaRecorder = static_cast<QWasmMediaRecorder *>(mediaRecorder);
86
87 if (m_mediaRecorder)
88 m_mediaRecorder->setCaptureSession(this);
89}
90
91void QWasmMediaCaptureSession::setAudioInput(QPlatformAudioInput *input)
92{
93 if (m_audioInput == input)
94 return;
95
96 m_needsAudio = (bool)input;
97 m_audioInput = input;
98}
99
101{
102 return m_needsAudio;
103}
104
106{
107 if (!sink || m_wasmSink == sink)
108 return;
109 m_wasmSink = sink;
110}
111
112void QWasmMediaCaptureSession::setAudioOutput(QPlatformAudioOutput *output)
113{
114 if (m_audioOutput == output)
115 return;
116 m_audioOutput = output;
117}
118
120{
121 if (m_imageCapture)
122 m_imageCapture->setReadyForCapture(ready);
123}
124
126{
127 return m_screenCapture;
128}
129
130void QWasmMediaCaptureSession::setScreenCapture(QPlatformSurfaceCapture *surfaceCapture)
131{
132 m_screenCapture = surfaceCapture;
133 if (surfaceCapture == nullptr) {
134 // clear stuff
135 m_displaySurface = "";
136 if (m_videoOutput && !m_videoOutput->currentVideoElement().isUndefined()) {
137 m_videoOutput->stop();
138 }
139 } else {
140 m_displaySurface = "browser";
141 QWasmScreenCapture *wasmScreenCapture =
142 static_cast<QWasmScreenCapture *>(m_screenCapture);
143 wasmScreenCapture->setCaptureSession(this);
144 }
145}
146
148{
149 return m_windowCapture;
150}
151
152void QWasmMediaCaptureSession::setWindowCapture(QPlatformSurfaceCapture *surfaceCapture)
153{
154 m_windowCapture = surfaceCapture;
155
156 if (surfaceCapture == nullptr) {
157 // clear stuff
158 m_displaySurface = "";
159 if (m_videoOutput && !m_videoOutput->currentVideoElement().isUndefined()) {
160 m_videoOutput->stop();
161 m_videoOutput->removeCurrentVideoElement();
162 }
163 return;
164 } else {
165 // is window capture window or monitor ?
166 m_displaySurface = "window";
167 QWasmWindowCapture *wasmWindowCapture =
168 static_cast<QWasmWindowCapture *>(m_windowCapture);
169 wasmWindowCapture->setCaptureSession(this);
170 }
171}
172
173void QWasmMediaCaptureSession::setVideoSource(std::string surfacetype)
174{
175 m_displaySurface = surfacetype;
176 if (surfacetype.empty()) {
177 // Jane, stop this crazy thing!
178 if (m_videoOutput && !m_videoOutput->currentVideoElement().isUndefined()) {
179 m_videoOutput->stop();
180 m_videoOutput->removeCurrentVideoElement();
181 }
182 return;
183 }
184 emscripten::val navigator = emscripten::val::global("navigator");
185 emscripten::val mediaDevices = navigator["mediaDevices"];
186
187 if (mediaDevices.isNull() || mediaDevices.isUndefined()) {
188 qWarning() << "No media devices found";
189 return;
190 }
191
192 m_videoOutput = std::make_unique<QWasmVideoOutput>();
193 m_videoOutput->setVideoMode(QWasmVideoOutput::SurfaceCapture);
194
195 m_videoOutput->setSurface(m_wasmSink);
196
197 emscripten::val constraints = emscripten::val::object();
198 emscripten::val videoConstraint = emscripten::val::object();
199 emscripten::val audioConstraint = emscripten::val::object();
200
201 videoConstraint.set("displaySurface", m_displaySurface);
202 videoConstraint.set("resizeMode", std::string("crop-and-scale"));
203
204 constraints.set("monitorTypeSurfaces", surfacetype == "window" ?
205 std::string("exclude") : std::string("include")); // whole monitor
206
207 constraints.set("surfaceSwitching", std::string("exclude"));
208 constraints.set("selfBrowserSurface", "include"); // mirror effect
209
210 constraints.set("logicalSurface", true);
211
212 audioConstraint.set("systemAudio", true);
213
214 constraints.set("video", videoConstraint);
215 constraints.set("audio", audioConstraint);
216
217 // will ask for permissions!
218 qstdweb::PromiseCallbacks getDisplayMediaCallback{
219 // default
220 .thenFunc =
221 [this](emscripten::val stream) {
222 qCDebug(qWasmMediaCaptureSession) << "getDisplayMediaSuccess"
223 << m_displaySurface;
224 if (stream.isUndefined() || stream.isNull()) {
225 qWarning() << "No media stream found error";
226 return;
227 }
228 m_mediaCaptureStream = stream;
229
230 // new Video element
231 constexpr QSize initialSize(0, 0);
232 constexpr QRect initialRect(QPoint(0, 0), initialSize);
233 QUuid videoElementId = QUuid::createUuid();
234
235 m_videoOutput->createVideoElement(m_displaySurface + "_capture_"
236 + videoElementId.toString(QUuid::WithoutBraces).toStdString()); // videoElementId
237 m_videoOutput->doElementCallbacks();
238 m_videoOutput->createOffscreenElement(initialSize);
239 m_videoOutput->updateVideoElementGeometry(initialRect);
240
241 // set video element src to this
242 if (m_displaySurface == "window") {
243
244 QWasmWindowCapture *wasmWindowCapture =
245 static_cast<QWasmWindowCapture *>(m_windowCapture);
246 wasmWindowCapture->setVideoOutput(m_videoOutput.get());
247
248 QUuid uid(QString::fromStdString(stream["id"].as<std::string>()));
249
250 m_capuredWindows.push_back(QCapturableWindowPrivate::create(
251 static_cast<QCapturableWindowPrivate::Id>(uid.toByteArray().toLong()),
252 QString::fromStdString(stream["id"].as<std::string>())));
253
254 wasmWindowCapture->setVideoStream(stream);
255 emit windowCaptureChanged();
256 } else {
257
258 QWasmScreenCapture *wasmScreenCapture =
259 static_cast<QWasmScreenCapture *>(m_screenCapture);
260 wasmScreenCapture->setVideoOutput(m_videoOutput.get());
261
262 wasmScreenCapture->setVideoStream(stream);
263 emit screenCaptureChanged();
264 }
265 },
266 .catchFunc =
267 [](emscripten::val error) {
268 qCDebug(qWasmMediaCaptureSession)
269 << "getDisplayMedia fail"
270 << QString::fromStdString(error["name"].as<std::string>())
271 << QString::fromStdString(error["message"].as<std::string>());
272
273 // permission denied or error
274 // "NotAllowedError "Permission Denied"
275 }
276 };
277
278 qstdweb::Promise::make(mediaDevices, QStringLiteral("getDisplayMedia"),
279 std::move(getDisplayMediaCallback), constraints);
280}
void setActive(bool active) override
void setReadyForCapture(bool isReady)
void setMediaRecorder(QPlatformMediaRecorder *recorder) override
void setAudioInput(QPlatformAudioInput *input) override
void setScreenCapture(QPlatformSurfaceCapture *) override
QPlatformSurfaceCapture * screenCapture() override
void setAudioOutput(QPlatformAudioOutput *output) override
QPlatformImageCapture * imageCapture() override
QPlatformMediaRecorder * mediaRecorder() override
QPlatformSurfaceCapture * windowCapture() override
void setImageCapture(QPlatformImageCapture *imageCapture) override
void setWindowCapture(QPlatformSurfaceCapture *) override
void setCamera(QPlatformCamera *camera) override
~QWasmMediaCaptureSession() override
void setVideoPreview(QVideoSink *sink) override
QPlatformCamera * camera() override
void setVideoSource(std::string surfacetype)
QWasmMediaRecorder(QMediaRecorder *parent)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")