|
@@ -24,6 +24,7 @@ var MediaType = require("../../service/RTC/MediaType");
|
24
|
24
|
var VideoType = require("../../service/RTC/VideoType");
|
25
|
25
|
var CameraFacingMode = require("../../service/RTC/CameraFacingMode");
|
26
|
26
|
var GlobalOnErrorHandler = require("../util/GlobalOnErrorHandler");
|
|
27
|
+import Listenable from "../util/Listenable";
|
27
|
28
|
|
28
|
29
|
// XXX Don't require Temasys unless it's to be used because it doesn't run on
|
29
|
30
|
// React Native, for example.
|
|
@@ -419,7 +420,7 @@ function onReady (options, GUM) {
|
419
|
420
|
// Initialize rawEnumerateDevicesWithCallback
|
420
|
421
|
initRawEnumerateDevicesWithCallback();
|
421
|
422
|
|
422
|
|
- if (RTCUtils.isDeviceListAvailable() && rawEnumerateDevicesWithCallback) {
|
|
423
|
+ if (rtcUtils.isDeviceListAvailable() && rawEnumerateDevicesWithCallback) {
|
423
|
424
|
rawEnumerateDevicesWithCallback(function (devices) {
|
424
|
425
|
currentlyAvailableMediaDevices = devices.splice(0);
|
425
|
426
|
|
|
@@ -430,7 +431,7 @@ function onReady (options, GUM) {
|
430
|
431
|
navigator.mediaDevices.addEventListener(
|
431
|
432
|
'devicechange',
|
432
|
433
|
function () {
|
433
|
|
- RTCUtils.enumerateDevices(
|
|
434
|
+ rtcUtils.enumerateDevices(
|
434
|
435
|
onMediaDevicesListChanged);
|
435
|
436
|
});
|
436
|
437
|
} else {
|
|
@@ -557,7 +558,7 @@ function obtainDevices(options) {
|
557
|
558
|
},
|
558
|
559
|
function (error) {
|
559
|
560
|
Object.keys(options.streams).forEach(function(device) {
|
560
|
|
- RTCUtils.stopMediaStream(options.streams[device]);
|
|
561
|
+ rtcUtils.stopMediaStream(options.streams[device]);
|
561
|
562
|
});
|
562
|
563
|
logger.error(
|
563
|
564
|
"failed to obtain " + device + " stream - stop", error);
|
|
@@ -653,15 +654,15 @@ function handleLocalStream(streams, resolution) {
|
653
|
654
|
*/
|
654
|
655
|
function wrapAttachMediaStream(origAttachMediaStream) {
|
655
|
656
|
return function(element, stream) {
|
656
|
|
- var res = origAttachMediaStream.apply(RTCUtils, arguments);
|
|
657
|
+ var res = origAttachMediaStream.apply(rtcUtils, arguments);
|
657
|
658
|
|
658
|
659
|
if (stream
|
659
|
|
- && RTCUtils.isDeviceChangeAvailable('output')
|
|
660
|
+ && rtcUtils.isDeviceChangeAvailable('output')
|
660
|
661
|
&& stream.getAudioTracks
|
661
|
662
|
&& stream.getAudioTracks().length
|
662
|
663
|
// we skip setting audio output if there was no explicit change
|
663
|
664
|
&& audioOutputChanged) {
|
664
|
|
- element.setSinkId(RTCUtils.getAudioOutputDevice())
|
|
665
|
+ element.setSinkId(rtcUtils.getAudioOutputDevice())
|
665
|
666
|
.catch(function (ex) {
|
666
|
667
|
var err = new JitsiTrackError(ex, null, ['audiooutput']);
|
667
|
668
|
|
|
@@ -728,9 +729,12 @@ function defaultSetVideoSrc(element, stream) {
|
728
|
729
|
}
|
729
|
730
|
|
730
|
731
|
//Options parameter is to pass config options. Currently uses only "useIPv6".
|
731
|
|
-var RTCUtils = {
|
732
|
|
- init: function (options) {
|
|
732
|
+class RTCUtils extends Listenable {
|
|
733
|
+ constructor() {
|
|
734
|
+ super(eventEmitter);
|
|
735
|
+ }
|
733
|
736
|
|
|
737
|
+ init(options) {
|
734
|
738
|
if (typeof(options.disableAEC) === "boolean") {
|
735
|
739
|
disableAEC = options.disableAEC;
|
736
|
740
|
logger.info("Disable AEC: " + disableAEC);
|
|
@@ -903,7 +907,8 @@ var RTCUtils = {
|
903
|
907
|
resolve();
|
904
|
908
|
}
|
905
|
909
|
}.bind(this));
|
906
|
|
- },
|
|
910
|
+ }
|
|
911
|
+
|
907
|
912
|
/**
|
908
|
913
|
* @param {string[]} um required user media types
|
909
|
914
|
* @param {function} success_callback
|
|
@@ -916,7 +921,7 @@ var RTCUtils = {
|
916
|
921
|
* @param {string} options.cameraDeviceId
|
917
|
922
|
* @param {string} options.micDeviceId
|
918
|
923
|
**/
|
919
|
|
- getUserMediaWithConstraints: function ( um, success_callback, failure_callback, options) {
|
|
924
|
+ getUserMediaWithConstraints( um, success_callback, failure_callback, options) {
|
920
|
925
|
options = options || {};
|
921
|
926
|
var constraints = getConstraints(um, options);
|
922
|
927
|
|
|
@@ -946,7 +951,7 @@ var RTCUtils = {
|
946
|
951
|
failure_callback(new JitsiTrackError(e, constraints, um));
|
947
|
952
|
}
|
948
|
953
|
}
|
949
|
|
- },
|
|
954
|
+ }
|
950
|
955
|
|
951
|
956
|
/**
|
952
|
957
|
* Creates the local MediaStreams.
|
|
@@ -960,7 +965,7 @@ var RTCUtils = {
|
960
|
965
|
* @param {string} options.micDeviceId
|
961
|
966
|
* @returns {*} Promise object that will receive the new JitsiTracks
|
962
|
967
|
*/
|
963
|
|
- obtainAudioAndVideoPermissions: function (options) {
|
|
968
|
+ obtainAudioAndVideoPermissions (options) {
|
964
|
969
|
var self = this;
|
965
|
970
|
|
966
|
971
|
options = options || {};
|
|
@@ -1109,20 +1114,17 @@ var RTCUtils = {
|
1109
|
1114
|
}
|
1110
|
1115
|
}
|
1111
|
1116
|
}.bind(this));
|
1112
|
|
- },
|
1113
|
|
- addListener: function (eventType, listener) {
|
1114
|
|
- eventEmitter.on(eventType, listener);
|
1115
|
|
- },
|
1116
|
|
- removeListener: function (eventType, listener) {
|
1117
|
|
- eventEmitter.removeListener(eventType, listener);
|
1118
|
|
- },
|
1119
|
|
- getDeviceAvailability: function () {
|
|
1117
|
+ }
|
|
1118
|
+
|
|
1119
|
+ getDeviceAvailability () {
|
1120
|
1120
|
return devices;
|
1121
|
|
- },
|
1122
|
|
- isRTCReady: function () {
|
|
1121
|
+ }
|
|
1122
|
+
|
|
1123
|
+ isRTCReady () {
|
1123
|
1124
|
return rtcReady;
|
1124
|
|
- },
|
1125
|
|
- _isDeviceListAvailable: function () {
|
|
1125
|
+ }
|
|
1126
|
+
|
|
1127
|
+ _isDeviceListAvailable () {
|
1126
|
1128
|
if (!rtcReady)
|
1127
|
1129
|
throw new Error("WebRTC not ready yet");
|
1128
|
1130
|
var isEnumerateDevicesAvailable
|
|
@@ -1132,7 +1134,8 @@ var RTCUtils = {
|
1132
|
1134
|
}
|
1133
|
1135
|
return (typeof MediaStreamTrack !== "undefined" &&
|
1134
|
1136
|
MediaStreamTrack.getSources)? true : false;
|
1135
|
|
- },
|
|
1137
|
+ }
|
|
1138
|
+
|
1136
|
1139
|
/**
|
1137
|
1140
|
* Returns a promise which can be used to make sure that the WebRTC stack
|
1138
|
1141
|
* has been initialized.
|
|
@@ -1141,7 +1144,7 @@ var RTCUtils = {
|
1141
|
1144
|
* Note that currently we do not detect stack initialization failure and
|
1142
|
1145
|
* the promise is never rejected(unless unexpected error occurs).
|
1143
|
1146
|
*/
|
1144
|
|
- onRTCReady: function() {
|
|
1147
|
+ onRTCReady () {
|
1145
|
1148
|
if (rtcReady) {
|
1146
|
1149
|
return Promise.resolve();
|
1147
|
1150
|
} else {
|
|
@@ -1155,7 +1158,8 @@ var RTCUtils = {
|
1155
|
1158
|
// happens
|
1156
|
1159
|
});
|
1157
|
1160
|
}
|
1158
|
|
- },
|
|
1161
|
+ }
|
|
1162
|
+
|
1159
|
1163
|
/**
|
1160
|
1164
|
* Checks if its possible to enumerate available cameras/microphones.
|
1161
|
1165
|
*
|
|
@@ -1163,11 +1167,12 @@ var RTCUtils = {
|
1163
|
1167
|
* the WebRTC stack is ready, either with true if the device listing is
|
1164
|
1168
|
* available available or with false otherwise.
|
1165
|
1169
|
*/
|
1166
|
|
- isDeviceListAvailable: function () {
|
|
1170
|
+ isDeviceListAvailable () {
|
1167
|
1171
|
return this.onRTCReady().then(function() {
|
1168
|
1172
|
return this._isDeviceListAvailable();
|
1169
|
1173
|
}.bind(this));
|
1170
|
|
- },
|
|
1174
|
+ }
|
|
1175
|
+
|
1171
|
1176
|
/**
|
1172
|
1177
|
* Returns true if changing the input (camera / microphone) or output
|
1173
|
1178
|
* (audio) device is supported and false if not.
|
|
@@ -1175,7 +1180,7 @@ var RTCUtils = {
|
1175
|
1180
|
* undefined or 'input', 'output' - for audio output device change.
|
1176
|
1181
|
* @returns {boolean} true if available, false otherwise.
|
1177
|
1182
|
*/
|
1178
|
|
- isDeviceChangeAvailable: function (deviceType) {
|
|
1183
|
+ isDeviceChangeAvailable (deviceType) {
|
1179
|
1184
|
return deviceType === 'output' || deviceType === 'audiooutput'
|
1180
|
1185
|
? isAudioOutputDeviceChangeAvailable
|
1181
|
1186
|
: RTCBrowserType.isChrome() ||
|
|
@@ -1184,13 +1189,13 @@ var RTCUtils = {
|
1184
|
1189
|
RTCBrowserType.isTemasysPluginUsed()||
|
1185
|
1190
|
RTCBrowserType.isNWJS() ||
|
1186
|
1191
|
RTCBrowserType.isElectron();
|
1187
|
|
- },
|
|
1192
|
+ }
|
1188
|
1193
|
/**
|
1189
|
1194
|
* A method to handle stopping of the stream.
|
1190
|
1195
|
* One point to handle the differences in various implementations.
|
1191
|
1196
|
* @param mediaStream MediaStream object to stop.
|
1192
|
1197
|
*/
|
1193
|
|
- stopMediaStream: function (mediaStream) {
|
|
1198
|
+ stopMediaStream (mediaStream) {
|
1194
|
1199
|
mediaStream.getTracks().forEach(function (track) {
|
1195
|
1200
|
// stop() not supported with IE
|
1196
|
1201
|
if (!RTCBrowserType.isTemasysPluginUsed() && track.stop) {
|
|
@@ -1216,14 +1221,16 @@ var RTCUtils = {
|
1216
|
1221
|
delete mediaStream.jitsiObjectURL;
|
1217
|
1222
|
(URL || webkitURL).revokeObjectURL(url);
|
1218
|
1223
|
}
|
1219
|
|
- },
|
|
1224
|
+ }
|
|
1225
|
+
|
1220
|
1226
|
/**
|
1221
|
1227
|
* Returns whether the desktop sharing is enabled or not.
|
1222
|
1228
|
* @returns {boolean}
|
1223
|
1229
|
*/
|
1224
|
|
- isDesktopSharingEnabled: function () {
|
|
1230
|
+ isDesktopSharingEnabled () {
|
1225
|
1231
|
return screenObtainer.isSupported();
|
1226
|
|
- },
|
|
1232
|
+ }
|
|
1233
|
+
|
1227
|
1234
|
/**
|
1228
|
1235
|
* Sets current audio output device.
|
1229
|
1236
|
* @param {string} deviceId - id of 'audiooutput' device from
|
|
@@ -1232,7 +1239,7 @@ var RTCUtils = {
|
1232
|
1239
|
* @returns {Promise} - resolves when audio output is changed, is rejected
|
1233
|
1240
|
* otherwise
|
1234
|
1241
|
*/
|
1235
|
|
- setAudioOutputDevice: function (deviceId) {
|
|
1242
|
+ setAudioOutputDevice (deviceId) {
|
1236
|
1243
|
if (!this.isDeviceChangeAvailable('output')) {
|
1237
|
1244
|
Promise.reject(
|
1238
|
1245
|
new Error('Audio output device change is not supported'));
|
|
@@ -1248,30 +1255,31 @@ var RTCUtils = {
|
1248
|
1255
|
eventEmitter.emit(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,
|
1249
|
1256
|
deviceId);
|
1250
|
1257
|
});
|
1251
|
|
- },
|
|
1258
|
+ }
|
|
1259
|
+
|
1252
|
1260
|
/**
|
1253
|
1261
|
* Returns currently used audio output device id, '' stands for default
|
1254
|
1262
|
* device
|
1255
|
1263
|
* @returns {string}
|
1256
|
1264
|
*/
|
1257
|
|
- getAudioOutputDevice: function () {
|
|
1265
|
+ getAudioOutputDevice () {
|
1258
|
1266
|
return audioOutputDeviceId;
|
1259
|
|
- },
|
|
1267
|
+ }
|
1260
|
1268
|
|
1261
|
1269
|
/**
|
1262
|
1270
|
* Returns list of available media devices if its obtained, otherwise an
|
1263
|
1271
|
* empty array is returned/
|
1264
|
1272
|
* @returns {Array} list of available media devices.
|
1265
|
1273
|
*/
|
1266
|
|
- getCurrentlyAvailableMediaDevices: function () {
|
|
1274
|
+ getCurrentlyAvailableMediaDevices () {
|
1267
|
1275
|
return currentlyAvailableMediaDevices;
|
1268
|
|
- },
|
|
1276
|
+ }
|
1269
|
1277
|
|
1270
|
1278
|
/**
|
1271
|
1279
|
* Returns event data for device to be reported to stats.
|
1272
|
1280
|
* @returns {MediaDeviceInfo} device.
|
1273
|
1281
|
*/
|
1274
|
|
- getEventDataForActiveDevice: function (device) {
|
|
1282
|
+ getEventDataForActiveDevice (device) {
|
1275
|
1283
|
var devices = [];
|
1276
|
1284
|
var deviceData = {
|
1277
|
1285
|
"deviceId": device.deviceId,
|
|
@@ -1282,6 +1290,8 @@ var RTCUtils = {
|
1282
|
1290
|
devices.push(deviceData);
|
1283
|
1291
|
return { deviceList: devices };
|
1284
|
1292
|
}
|
1285
|
|
-};
|
|
1293
|
+}
|
|
1294
|
+
|
|
1295
|
+const rtcUtils = new RTCUtils();
|
1286
|
1296
|
|
1287
|
|
-module.exports = RTCUtils;
|
|
1297
|
+export default rtcUtils;
|