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