|
|
@@ -11,6 +11,7 @@ import * as RemoteControlEvents
|
|
11
|
11
|
from './service/remotecontrol/RemoteControlEvents';
|
|
12
|
12
|
import UIEvents from './service/UI/UIEvents';
|
|
13
|
13
|
import UIUtil from './modules/UI/util/UIUtil';
|
|
|
14
|
+import { createTaskQueue } from './modules/util/helpers';
|
|
14
|
15
|
import * as JitsiMeetConferenceEvents from './ConferenceEvents';
|
|
15
|
16
|
|
|
16
|
17
|
import {
|
|
|
@@ -274,6 +275,27 @@ function redirectToStaticPage(pathname) {
|
|
274
|
275
|
windowLocation.pathname = newPathname;
|
|
275
|
276
|
}
|
|
276
|
277
|
|
|
|
278
|
+/**
|
|
|
279
|
+ * A queue for the async replaceLocalTrack action so that multiple audio
|
|
|
280
|
+ * replacements cannot happen simultaneously. This solves the issue where
|
|
|
281
|
+ * replaceLocalTrack is called multiple times with an oldTrack of null, causing
|
|
|
282
|
+ * multiple local tracks of the same type to be used.
|
|
|
283
|
+ *
|
|
|
284
|
+ * @private
|
|
|
285
|
+ * @type {Object}
|
|
|
286
|
+ */
|
|
|
287
|
+const _replaceLocalAudioTrackQueue = createTaskQueue();
|
|
|
288
|
+
|
|
|
289
|
+/**
|
|
|
290
|
+ * A task queue for replacement local video tracks. This separate queue exists
|
|
|
291
|
+ * so video replacement is not blocked by audio replacement tasks in the queue
|
|
|
292
|
+ * {@link _replaceLocalAudioTrackQueue}.
|
|
|
293
|
+ *
|
|
|
294
|
+ * @private
|
|
|
295
|
+ * @type {Object}
|
|
|
296
|
+ */
|
|
|
297
|
+const _replaceLocalVideoTrackQueue = createTaskQueue();
|
|
|
298
|
+
|
|
277
|
299
|
/**
|
|
278
|
300
|
*
|
|
279
|
301
|
*/
|
|
|
@@ -856,9 +878,6 @@ export default {
|
|
856
|
878
|
return;
|
|
857
|
879
|
}
|
|
858
|
880
|
|
|
859
|
|
- // FIXME it is possible to queue this task twice, but it's not causing
|
|
860
|
|
- // any issues. Specifically this can happen when the previous
|
|
861
|
|
- // get user media call is blocked on "ask user for permissions" dialog.
|
|
862
|
881
|
if (!this.localVideo && !mute) {
|
|
863
|
882
|
const maybeShowErrorDialog = error => {
|
|
864
|
883
|
showUI && APP.UI.showCameraErrorNotification(error);
|
|
|
@@ -1261,16 +1280,23 @@ export default {
|
|
1261
|
1280
|
* @returns {Promise}
|
|
1262
|
1281
|
*/
|
|
1263
|
1282
|
useVideoStream(newStream) {
|
|
1264
|
|
- return APP.store.dispatch(
|
|
1265
|
|
- replaceLocalTrack(this.localVideo, newStream, room))
|
|
1266
|
|
- .then(() => {
|
|
1267
|
|
- this.localVideo = newStream;
|
|
1268
|
|
- this._setSharingScreen(newStream);
|
|
1269
|
|
- if (newStream) {
|
|
1270
|
|
- APP.UI.addLocalStream(newStream);
|
|
1271
|
|
- }
|
|
1272
|
|
- this.setVideoMuteStatus(this.isLocalVideoMuted());
|
|
|
1283
|
+ return new Promise((resolve, reject) => {
|
|
|
1284
|
+ _replaceLocalVideoTrackQueue.enqueue(onFinish => {
|
|
|
1285
|
+ APP.store.dispatch(
|
|
|
1286
|
+ replaceLocalTrack(this.localVideo, newStream, room))
|
|
|
1287
|
+ .then(() => {
|
|
|
1288
|
+ this.localVideo = newStream;
|
|
|
1289
|
+ this._setSharingScreen(newStream);
|
|
|
1290
|
+ if (newStream) {
|
|
|
1291
|
+ APP.UI.addLocalStream(newStream);
|
|
|
1292
|
+ }
|
|
|
1293
|
+ this.setVideoMuteStatus(this.isLocalVideoMuted());
|
|
|
1294
|
+ })
|
|
|
1295
|
+ .then(resolve)
|
|
|
1296
|
+ .catch(reject)
|
|
|
1297
|
+ .then(onFinish);
|
|
1273
|
1298
|
});
|
|
|
1299
|
+ });
|
|
1274
|
1300
|
},
|
|
1275
|
1301
|
|
|
1276
|
1302
|
/**
|
|
|
@@ -1300,15 +1326,22 @@ export default {
|
|
1300
|
1326
|
* @returns {Promise}
|
|
1301
|
1327
|
*/
|
|
1302
|
1328
|
useAudioStream(newStream) {
|
|
1303
|
|
- return APP.store.dispatch(
|
|
1304
|
|
- replaceLocalTrack(this.localAudio, newStream, room))
|
|
1305
|
|
- .then(() => {
|
|
1306
|
|
- this.localAudio = newStream;
|
|
1307
|
|
- if (newStream) {
|
|
1308
|
|
- APP.UI.addLocalStream(newStream);
|
|
1309
|
|
- }
|
|
1310
|
|
- this.setAudioMuteStatus(this.isLocalAudioMuted());
|
|
|
1329
|
+ return new Promise((resolve, reject) => {
|
|
|
1330
|
+ _replaceLocalAudioTrackQueue.enqueue(onFinish => {
|
|
|
1331
|
+ APP.store.dispatch(
|
|
|
1332
|
+ replaceLocalTrack(this.localAudio, newStream, room))
|
|
|
1333
|
+ .then(() => {
|
|
|
1334
|
+ this.localAudio = newStream;
|
|
|
1335
|
+ if (newStream) {
|
|
|
1336
|
+ APP.UI.addLocalStream(newStream);
|
|
|
1337
|
+ }
|
|
|
1338
|
+ this.setAudioMuteStatus(this.isLocalAudioMuted());
|
|
|
1339
|
+ })
|
|
|
1340
|
+ .then(resolve)
|
|
|
1341
|
+ .catch(reject)
|
|
|
1342
|
+ .then(onFinish);
|
|
1311
|
1343
|
});
|
|
|
1344
|
+ });
|
|
1312
|
1345
|
},
|
|
1313
|
1346
|
|
|
1314
|
1347
|
/**
|