[mirotalksfu] - Fix audio recording, refactoring, update dep

هذا الالتزام موجود في:
Miroslav Pejic
2024-04-21 10:48:43 +02:00
الأصل 50be52b184
التزام 8c561a5656
4 ملفات معدلة مع 100 إضافات و60 حذوفات

عرض الملف

@@ -41,7 +41,7 @@ dependencies: {
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.4.20 * @version 1.4.21
* *
*/ */

عرض الملف

@@ -1,6 +1,6 @@
{ {
"name": "mirotalksfu", "name": "mirotalksfu",
"version": "1.4.20", "version": "1.4.21",
"description": "WebRTC SFU browser-based video calls", "description": "WebRTC SFU browser-based video calls",
"main": "Server.js", "main": "Server.js",
"scripts": { "scripts": {
@@ -41,8 +41,8 @@
"node": ">=18" "node": ">=18"
}, },
"dependencies": { "dependencies": {
"@sentry/integrations": "7.110.1", "@sentry/integrations": "7.111.0",
"@sentry/node": "7.110.1", "@sentry/node": "7.111.0",
"axios": "^1.6.8", "axios": "^1.6.8",
"body-parser": "1.20.2", "body-parser": "1.20.2",
"colors": "1.4.0", "colors": "1.4.0",
@@ -56,7 +56,7 @@
"mediasoup-client": "3.7.7", "mediasoup-client": "3.7.7",
"ngrok": "^5.0.0-beta.2", "ngrok": "^5.0.0-beta.2",
"nodemailer": "^6.9.13", "nodemailer": "^6.9.13",
"openai": "^4.37.0", "openai": "^4.38.2",
"qs": "6.12.1", "qs": "6.12.1",
"socket.io": "4.7.5", "socket.io": "4.7.5",
"swagger-ui-express": "5.0.0", "swagger-ui-express": "5.0.0",

عرض الملف

@@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.4.20 * @version 1.4.21
* *
*/ */
@@ -1521,9 +1521,6 @@ function handleButtons() {
isRecording ? stopRecButton.click() : startRecButton.click(); isRecording ? stopRecButton.click() : startRecButton.click();
}; };
startRecButton.onclick = () => { startRecButton.onclick = () => {
if (participantsCount == 1 && !rc.peer_info.peer_audio) {
return userLog('warning', '🔴 Recording requires your audio to be enabled', 'top-end', 6000);
}
rc.startRecording(); rc.startRecording();
}; };
stopRecButton.onclick = () => { stopRecButton.onclick = () => {
@@ -1553,16 +1550,28 @@ function handleButtons() {
if (isPushToTalkActive) return; if (isPushToTalkActive) return;
setAudioButtonsDisabled(true); setAudioButtonsDisabled(true);
if (!isEnumerateAudioDevices) await initEnumerateAudioDevices(); if (!isEnumerateAudioDevices) await initEnumerateAudioDevices();
rc.produce(RoomClient.mediaType.audio, microphoneSelect.value);
const producerExist = rc.producerExist(RoomClient.mediaType.audio);
console.log('START AUDIO producerExist --->', producerExist);
producerExist
? await rc.resumeProducer(RoomClient.mediaType.audio)
: await rc.produce(RoomClient.mediaType.audio, microphoneSelect.value);
rc.updatePeerInfo(peer_name, socket.id, 'audio', true); rc.updatePeerInfo(peer_name, socket.id, 'audio', true);
// rc.resumeProducer(RoomClient.mediaType.audio);
}; };
stopAudioButton.onclick = () => { stopAudioButton.onclick = async () => {
if (isPushToTalkActive) return; if (isPushToTalkActive) return;
setAudioButtonsDisabled(true); setAudioButtonsDisabled(true);
rc.closeProducer(RoomClient.mediaType.audio);
const producerExist = rc.producerExist(RoomClient.mediaType.audio);
console.log('START STOP producerExist --->', producerExist);
producerExist
? await rc.pauseProducer(RoomClient.mediaType.audio)
: await rc.closeProducer(RoomClient.mediaType.audio);
rc.updatePeerInfo(peer_name, socket.id, 'audio', false); rc.updatePeerInfo(peer_name, socket.id, 'audio', false);
// rc.pauseProducer(RoomClient.mediaType.audio);
}; };
startVideoButton.onclick = async () => { startVideoButton.onclick = async () => {
const moderator = rc.getModerator(); const moderator = rc.getModerator();
@@ -1571,20 +1580,20 @@ function handleButtons() {
} }
setVideoButtonsDisabled(true); setVideoButtonsDisabled(true);
if (!isEnumerateVideoDevices) await initEnumerateVideoDevices(); if (!isEnumerateVideoDevices) await initEnumerateVideoDevices();
rc.produce(RoomClient.mediaType.video, videoSelect.value); await rc.produce(RoomClient.mediaType.video, videoSelect.value);
// rc.resumeProducer(RoomClient.mediaType.video); // await rc.resumeProducer(RoomClient.mediaType.video);
}; };
stopVideoButton.onclick = () => { stopVideoButton.onclick = () => {
setVideoButtonsDisabled(true); setVideoButtonsDisabled(true);
rc.closeProducer(RoomClient.mediaType.video); rc.closeProducer(RoomClient.mediaType.video);
// rc.pauseProducer(RoomClient.mediaType.video); // await rc.pauseProducer(RoomClient.mediaType.video);
}; };
startScreenButton.onclick = () => { startScreenButton.onclick = async () => {
const moderator = rc.getModerator(); const moderator = rc.getModerator();
if (moderator.screen_cant_share) { if (moderator.screen_cant_share) {
return userLog('warning', 'The moderator does not allow you to share the screen', 'top-end', 6000); return userLog('warning', 'The moderator does not allow you to share the screen', 'top-end', 6000);
} }
rc.produce(RoomClient.mediaType.screen); await rc.produce(RoomClient.mediaType.screen);
}; };
stopScreenButton.onclick = () => { stopScreenButton.onclick = () => {
rc.closeProducer(RoomClient.mediaType.screen); rc.closeProducer(RoomClient.mediaType.screen);
@@ -1986,42 +1995,42 @@ function handleSelects() {
rc.changeAudioDestination(); rc.changeAudioDestination();
refreshLsDevices(); refreshLsDevices();
}; };
switchPushToTalk.onchange = (e) => { switchPushToTalk.onchange = async (e) => {
const producerExist = rc.producerExist(RoomClient.mediaType.audio); const producerExist = rc.producerExist(RoomClient.mediaType.audio);
if (!producerExist && !isPushToTalkActive) { if (!producerExist && !isPushToTalkActive) {
console.log('Push-to-talk: start audio producer'); console.log('Push-to-talk: start audio producer');
setAudioButtonsDisabled(true); setAudioButtonsDisabled(true);
if (!isEnumerateAudioDevices) initEnumerateAudioDevices(); if (!isEnumerateAudioDevices) initEnumerateAudioDevices();
rc.produce(RoomClient.mediaType.audio, microphoneSelect.value); await rc.produce(RoomClient.mediaType.audio, microphoneSelect.value);
setTimeout(function () { setTimeout(async function () {
rc.pauseProducer(RoomClient.mediaType.audio); await rc.pauseProducer(RoomClient.mediaType.audio);
rc.updatePeerInfo(peer_name, socket.id, 'audio', false); rc.updatePeerInfo(peer_name, socket.id, 'audio', false);
}, 1000); }, 1000);
} }
isPushToTalkActive = !isPushToTalkActive; isPushToTalkActive = !isPushToTalkActive;
if (producerExist && !isPushToTalkActive) { if (producerExist && !isPushToTalkActive) {
console.log('Push-to-talk: resume audio producer'); console.log('Push-to-talk: resume audio producer');
rc.resumeProducer(RoomClient.mediaType.audio); await rc.resumeProducer(RoomClient.mediaType.audio);
rc.updatePeerInfo(peer_name, socket.id, 'audio', true); rc.updatePeerInfo(peer_name, socket.id, 'audio', true);
} }
e.target.blur(); // Removes focus from the element e.target.blur(); // Removes focus from the element
rc.roomMessage('ptt', isPushToTalkActive); rc.roomMessage('ptt', isPushToTalkActive);
console.log(`Push-to-talk enabled: ${isPushToTalkActive}`); console.log(`Push-to-talk enabled: ${isPushToTalkActive}`);
}; };
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', async (e) => {
if (!isPushToTalkActive) return; if (!isPushToTalkActive) return;
if (e.code === 'Space') { if (e.code === 'Space') {
if (isSpaceDown) return; if (isSpaceDown) return;
rc.resumeProducer(RoomClient.mediaType.audio); await rc.resumeProducer(RoomClient.mediaType.audio);
rc.updatePeerInfo(peer_name, socket.id, 'audio', true); rc.updatePeerInfo(peer_name, socket.id, 'audio', true);
isSpaceDown = true; isSpaceDown = true;
console.log('Push-to-talk: audio resumed'); console.log('Push-to-talk: audio resumed');
} }
}); });
document.addEventListener('keyup', (e) => { document.addEventListener('keyup', async (e) => {
if (!isPushToTalkActive) return; if (!isPushToTalkActive) return;
if (e.code === 'Space') { if (e.code === 'Space') {
rc.pauseProducer(RoomClient.mediaType.audio); await rc.pauseProducer(RoomClient.mediaType.audio);
rc.updatePeerInfo(peer_name, socket.id, 'audio', false); rc.updatePeerInfo(peer_name, socket.id, 'audio', false);
isSpaceDown = false; isSpaceDown = false;
console.log('Push-to-talk: audio paused'); console.log('Push-to-talk: audio paused');
@@ -2531,11 +2540,14 @@ function handleRoomClientEvents() {
console.log('Room event: Client pause audio'); console.log('Room event: Client pause audio');
hide(stopAudioButton); hide(stopAudioButton);
show(startAudioButton); show(startAudioButton);
setColor(startAudioButton, 'red');
setAudioButtonsDisabled(false);
}); });
rc.on(RoomClient.EVENTS.resumeAudio, () => { rc.on(RoomClient.EVENTS.resumeAudio, () => {
console.log('Room event: Client resume audio'); console.log('Room event: Client resume audio');
hide(startAudioButton); hide(startAudioButton);
show(stopAudioButton); show(stopAudioButton);
setAudioButtonsDisabled(false);
}); });
rc.on(RoomClient.EVENTS.stopAudio, () => { rc.on(RoomClient.EVENTS.stopAudio, () => {
console.log('Room event: Client stop audio'); console.log('Room event: Client stop audio');
@@ -2556,11 +2568,15 @@ function handleRoomClientEvents() {
console.log('Room event: Client pause video'); console.log('Room event: Client pause video');
hide(stopVideoButton); hide(stopVideoButton);
show(startVideoButton); show(startVideoButton);
setColor(startVideoButton, 'red');
setVideoButtonsDisabled(false);
}); });
rc.on(RoomClient.EVENTS.resumeVideo, () => { rc.on(RoomClient.EVENTS.resumeVideo, () => {
console.log('Room event: Client resume video'); console.log('Room event: Client resume video');
hide(startVideoButton); hide(startVideoButton);
show(stopVideoButton); show(stopVideoButton);
setVideoButtonsDisabled(false);
isVideoPrivacyActive = false;
}); });
rc.on(RoomClient.EVENTS.stopVideo, () => { rc.on(RoomClient.EVENTS.stopVideo, () => {
console.log('Room event: Client stop video'); console.log('Room event: Client stop video');
@@ -2578,9 +2594,13 @@ function handleRoomClientEvents() {
}); });
rc.on(RoomClient.EVENTS.pauseScreen, () => { rc.on(RoomClient.EVENTS.pauseScreen, () => {
console.log('Room event: Client pause screen'); console.log('Room event: Client pause screen');
hide(startScreenButton);
show(stopScreenButton);
}); });
rc.on(RoomClient.EVENTS.resumeScreen, () => { rc.on(RoomClient.EVENTS.resumeScreen, () => {
console.log('Room event: Client resume screen'); console.log('Room event: Client resume screen');
hide(stopScreenButton);
show(startScreenButton);
}); });
rc.on(RoomClient.EVENTS.stopScreen, () => { rc.on(RoomClient.EVENTS.stopScreen, () => {
console.log('Room event: Client stop screen'); console.log('Room event: Client stop screen');

عرض الملف

@@ -9,7 +9,7 @@
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.4.20 * @version 1.4.21
* *
*/ */
@@ -404,12 +404,14 @@ class RoomClient {
this.device = await this.loadDevice(routerRtpCapabilities); this.device = await this.loadDevice(routerRtpCapabilities);
console.log('07.3 ----> Get Router Rtp Capabilities codecs: ', this.device.rtpCapabilities.codecs); console.log('07.3 ----> Get Router Rtp Capabilities codecs: ', this.device.rtpCapabilities.codecs);
await this.initTransports(this.device); await this.initTransports(this.device);
if (isBroadcastingEnabled) { // ###################################
isPresenter ? this.startLocalMedia() : this.handleRoomBroadcasting();
} else {
this.startLocalMedia();
}
this.socket.emit('getProducers'); this.socket.emit('getProducers');
// ###################################
if (isBroadcastingEnabled) {
isPresenter ? await this.startLocalMedia() : this.handleRoomBroadcasting();
} else {
await this.startLocalMedia();
}
} }
handleRoomInfo(room) { handleRoomInfo(room) {
@@ -1063,32 +1065,47 @@ class RoomClient {
// START LOCAL AUDIO VIDEO MEDIA // START LOCAL AUDIO VIDEO MEDIA
// #################################################### // ####################################################
startLocalMedia() { async startLocalMedia() {
console.log('08 ----> Start local media'); console.log('08 ----> START LOCAL MEDIA...');
if (this.isAudioAllowed && !this._moderator.audio_start_muted) { if (this.isAudioAllowed) {
console.log('09 ----> Start audio media'); if (!this.producerExist(mediaType.audio)) {
this.produce(mediaType.audio, microphoneSelect.value); await this.produce(mediaType.audio, microphoneSelect.value);
console.log('09 ----> START AUDIO MEDIA');
}
} else { } else {
console.log('09 ----> Audio is off'); if (isEnumerateAudioDevices) {
if (!this.producerExist(mediaType.audio)) {
await this.produce(mediaType.audio, microphoneSelect.value);
console.log('09 ----> START AUDIO MEDIA');
await this.pauseProducer(mediaType.audio);
console.log('09 ----> PAUSE AUDIO MEDIA');
}
}
}
if (this._moderator.audio_start_muted) {
setColor(startAudioButton, 'red'); setColor(startAudioButton, 'red');
this.setIsAudio(this.peer_id, false); this.setIsAudio(this.peer_id, false);
if (BUTTONS.main.startAudioButton) this.event(_EVENTS.stopAudio); if (BUTTONS.main.startAudioButton) this.event(_EVENTS.stopAudio);
await this.pauseProducer(mediaType.audio);
this.updatePeerInfo(this.peer_name, this.peer_id, 'audio', false); this.updatePeerInfo(this.peer_name, this.peer_id, 'audio', false);
console.log('09 ----> AUDIO IS OFF');
} }
if (this.isVideoAllowed && !this._moderator.video_start_hidden) { if (this.isVideoAllowed && !this._moderator.video_start_hidden) {
console.log('10 ----> Start video media'); await this.produce(mediaType.video, videoSelect.value);
this.produce(mediaType.video, videoSelect.value); console.log('10 ----> START VIDEO MEDIA');
} else { } else {
console.log('10 ----> Video is off');
setColor(startVideoButton, 'red'); setColor(startVideoButton, 'red');
this.setVideoOff(this.peer_info, false); this.setVideoOff(this.peer_info, false);
this.sendVideoOff(); this.sendVideoOff();
if (BUTTONS.main.startVideoButton) this.event(_EVENTS.stopVideo); if (BUTTONS.main.startVideoButton) this.event(_EVENTS.stopVideo);
this.updatePeerInfo(this.peer_name, this.peer_id, 'video', false); this.updatePeerInfo(this.peer_name, this.peer_id, 'video', false);
console.log('10 ----> VIDEO IS OFF');
} }
if (this.joinRoomWithScreen && !this._moderator.screen_cant_share) { if (this.joinRoomWithScreen && !this._moderator.screen_cant_share) {
console.log('08 ----> Start Screen media'); await this.produce(mediaType.screen, null, false, true);
this.produce(mediaType.screen, null, false, true); console.log('11 ----> START SCREEN MEDIA');
} }
// if (this.isScreenAllowed) { // if (this.isScreenAllowed) {
// this.shareScreen(); // this.shareScreen();
@@ -1128,7 +1145,7 @@ class RoomClient {
return console.error('Cannot produce video'); return console.error('Cannot produce video');
} }
if (this.producerLabel.has(type)) { if (this.producerLabel.has(type)) {
return console.log('Producer already exists for this type ' + type); return console.warn('Producer already exists for this type ' + type);
} }
const videoPrivacyBtn = this.getId(this.peer_id + '__vp'); const videoPrivacyBtn = this.getId(this.peer_id + '__vp');
@@ -1206,6 +1223,7 @@ class RoomClient {
console.log('PRODUCER', producer); console.log('PRODUCER', producer);
this.producers.set(producer.id, producer); this.producers.set(producer.id, producer);
this.producerLabel.set(type, producer.id);
// if screen sharing produce the tab audio + microphone // if screen sharing produce the tab audio + microphone
if (screen && stream.getAudioTracks()[0]) { if (screen && stream.getAudioTracks()[0]) {
@@ -1280,8 +1298,6 @@ class RoomClient {
this.producers.delete(producer.id); this.producers.delete(producer.id);
}); });
this.producerLabel.set(type, producer.id);
switch (type) { switch (type) {
case mediaType.audio: case mediaType.audio:
this.setIsAudio(this.peer_id, true); this.setIsAudio(this.peer_id, true);
@@ -1299,6 +1315,7 @@ class RoomClient {
break; break;
} }
this.sound('joined'); this.sound('joined');
return producer;
} catch (err) { } catch (err) {
console.error('Produce error:', err); console.error('Produce error:', err);
@@ -1676,8 +1693,8 @@ class RoomClient {
closeThenProduce(type, deviceId = null, swapCamera = false) { closeThenProduce(type, deviceId = null, swapCamera = false) {
this.closeProducer(type); this.closeProducer(type);
setTimeout(function () { setTimeout(async function () {
rc.produce(type, deviceId, swapCamera); await rc.produce(type, deviceId, swapCamera);
}, 1000); }, 1000);
} }
@@ -1795,7 +1812,7 @@ class RoomClient {
async pauseProducer(type) { async pauseProducer(type) {
if (!this.producerLabel.has(type)) { if (!this.producerLabel.has(type)) {
return console.log('There is no producer for this type ' + type); return console.warn('There is no producer for this type ' + type);
} }
const producer_id = this.producerLabel.get(type); const producer_id = this.producerLabel.get(type);
@@ -1811,6 +1828,7 @@ class RoomClient {
switch (type) { switch (type) {
case mediaType.audio: case mediaType.audio:
this.event(_EVENTS.pauseAudio); this.event(_EVENTS.pauseAudio);
this.setIsAudio(this.peer_id, false);
break; break;
case mediaType.video: case mediaType.video:
this.event(_EVENTS.pauseVideo); this.event(_EVENTS.pauseVideo);
@@ -1825,7 +1843,7 @@ class RoomClient {
async resumeProducer(type) { async resumeProducer(type) {
if (!this.producerLabel.has(type)) { if (!this.producerLabel.has(type)) {
return console.log('There is no producer for this type ' + type); return console.warn('There is no producer for this type ' + type);
} }
const producer_id = this.producerLabel.get(type); const producer_id = this.producerLabel.get(type);
@@ -1841,6 +1859,7 @@ class RoomClient {
switch (type) { switch (type) {
case mediaType.audio: case mediaType.audio:
this.event(_EVENTS.resumeAudio); this.event(_EVENTS.resumeAudio);
this.setIsAudio(this.peer_id, true);
break; break;
case mediaType.video: case mediaType.video:
this.event(_EVENTS.resumeVideo); this.event(_EVENTS.resumeVideo);
@@ -1855,7 +1874,7 @@ class RoomClient {
closeProducer(type) { closeProducer(type) {
if (!this.producerLabel.has(type)) { if (!this.producerLabel.has(type)) {
return console.log('There is no producer for this type ' + type); return console.warn('There is no producer for this type ' + type);
} }
const producer_id = this.producerLabel.get(type); const producer_id = this.producerLabel.get(type);
@@ -1928,7 +1947,7 @@ class RoomClient {
async produceScreenAudio(stream) { async produceScreenAudio(stream) {
try { try {
if (this.producerLabel.has(mediaType.audioTab)) { if (this.producerLabel.has(mediaType.audioTab)) {
return console.log('Producer already exists for this type ' + mediaType.audioTab); return console.warn('Producer already exists for this type ' + mediaType.audioTab);
} }
const track = stream.getAudioTracks()[0]; const track = stream.getAudioTracks()[0];
@@ -1944,6 +1963,7 @@ class RoomClient {
console.log('PRODUCER SCREEN AUDIO', producerSa); console.log('PRODUCER SCREEN AUDIO', producerSa);
this.producers.set(producerSa.id, producerSa); this.producers.set(producerSa.id, producerSa);
this.producerLabel.set(mediaType.audioTab, producerSa.id);
const sa = await this.handleProducer(producerSa.id, mediaType.audio, stream); const sa = await this.handleProducer(producerSa.id, mediaType.audio, stream);
@@ -1971,8 +1991,6 @@ class RoomClient {
console.log('[closingProducer] audio-element-count', this.localAudioEl.childElementCount); console.log('[closingProducer] audio-element-count', this.localAudioEl.childElementCount);
this.producers.delete(producerSa.id); this.producers.delete(producerSa.id);
}); });
this.producerLabel.set(mediaType.audioTab, producerSa.id);
} catch (err) { } catch (err) {
console.error('Produce error:', err); console.error('Produce error:', err);
} }
@@ -5995,18 +6013,20 @@ class RoomClient {
denyButtonText: `No`, denyButtonText: `No`,
showClass: { popup: 'animate__animated animate__fadeInDown' }, showClass: { popup: 'animate__animated animate__fadeInDown' },
hideClass: { popup: 'animate__animated animate__fadeOutUp' }, hideClass: { popup: 'animate__animated animate__fadeOutUp' },
}).then((result) => { }).then(async (result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
switch (type) { switch (type) {
case mediaType.audio: case mediaType.audio:
this.produce(mediaType.audio, microphoneSelect.value); !this.producerLabel.get(RoomClient.mediaType.audio)
? await this.produce(mediaType.audio, microphoneSelect.value)
: await this.resumeProducer(mediaType.audio);
this.updatePeerInfo(this.peer_name, this.peer_id, 'audio', true); this.updatePeerInfo(this.peer_name, this.peer_id, 'audio', true);
break; break;
case mediaType.video: case mediaType.video:
this.produce(mediaType.video, videoSelect.value); await this.produce(mediaType.video, videoSelect.value);
break; break;
case mediaType.screen: case mediaType.screen:
this.produce(mediaType.screen); await this.produce(mediaType.screen);
break; break;
default: default:
break; break;