@flashphoner/websdk 2.0.244 → 2.0.246
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docTemplate/README.md +1 -1
- package/examples/demo/streaming/hls-js-player/hls-js-player.js +79 -1
- package/examples/demo/streaming/hls-player/hls-player.js +135 -12
- package/examples/demo/streaming/hls-player/player-page.html +27 -12
- package/examples/demo/streaming/hls-player/videojs7/videojs-contrib-quality-levels.js +308 -0
- package/flashphoner-no-flash.js +606 -136
- package/flashphoner-no-flash.min.js +2 -2
- package/flashphoner-no-webrtc.js +554 -130
- package/flashphoner-no-webrtc.min.js +2 -2
- package/flashphoner-no-wsplayer.js +605 -135
- package/flashphoner-no-wsplayer.min.js +2 -2
- package/flashphoner-room-api.js +366 -18
- package/flashphoner-room-api.min.js +2 -2
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +555 -131
- package/flashphoner-temasys-flash-websocket.js +554 -130
- package/flashphoner-temasys-flash-websocket.min.js +1 -1
- package/flashphoner-webrtc-only.js +604 -134
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +606 -136
- package/flashphoner.min.js +2 -2
- package/package.json +1 -1
- package/src/client-info.js +237 -0
- package/src/flashphoner-core.js +83 -5
- package/src/webrtc-media-provider.js +37 -5
package/package.json
CHANGED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function getClientHints(navigator) {
|
|
4
|
+
let {userAgent} = navigator;
|
|
5
|
+
let mobile, platform = '', platformVersion = '', architecture = '', bitness = '', model = '', uaFullVersion = '', fullVersionList = [];
|
|
6
|
+
let platformInfo = userAgent;
|
|
7
|
+
let found = false;
|
|
8
|
+
let versionInfo = userAgent.replace(/\(([^)]+)\)?/g, ($0, $1) => {
|
|
9
|
+
if (!found) {
|
|
10
|
+
platformInfo = $1;
|
|
11
|
+
found = true;
|
|
12
|
+
}
|
|
13
|
+
return '';
|
|
14
|
+
});
|
|
15
|
+
let items = versionInfo.match(/(\S+)\/(\S+)/g);
|
|
16
|
+
let webview = false;
|
|
17
|
+
// detect mobile
|
|
18
|
+
mobile = userAgent.indexOf('Mobile') !== -1;
|
|
19
|
+
let m;
|
|
20
|
+
let m2;
|
|
21
|
+
// detect platform
|
|
22
|
+
if ((m = /Windows NT (\d+(\.\d+)*)/.exec(platformInfo)) !== null) {
|
|
23
|
+
platform = 'Windows';
|
|
24
|
+
// see https://docs.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11
|
|
25
|
+
let nt2win = {
|
|
26
|
+
'6.1': '0.1', // win-7
|
|
27
|
+
'6.2': '0.2', // win-8
|
|
28
|
+
'6.3': '0.3', // win-8.1
|
|
29
|
+
'10.0': '10.0', // win-10
|
|
30
|
+
'11.0': '13.0', // win-11
|
|
31
|
+
};
|
|
32
|
+
let ver = nt2win[m[1]];
|
|
33
|
+
if (ver)
|
|
34
|
+
platformVersion = padVersion(ver, 3);
|
|
35
|
+
if ((m2 = /\b(WOW64|Win64|x64)\b/.exec(platformInfo)) !== null) {
|
|
36
|
+
architecture = 'x86';
|
|
37
|
+
bitness = '64';
|
|
38
|
+
}
|
|
39
|
+
} else if ((m = /Android (\d+(\.\d+)*)/.exec(platformInfo)) !== null) {
|
|
40
|
+
platform = 'Android';
|
|
41
|
+
platformVersion = padVersion(m[1]);
|
|
42
|
+
if ((m2 = /Linux (\w+)/.exec(navigator.platform)) !== null) {
|
|
43
|
+
if (m2[1]) {
|
|
44
|
+
m2 = parseArch(m2[1]);
|
|
45
|
+
architecture = m2[0];
|
|
46
|
+
bitness = m2[1];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} else if ((m = /(iPhone|iPod touch); CPU iPhone OS (\d+(_\d+)*)/.exec(platformInfo)) !== null) {
|
|
50
|
+
// see special notes at https://www.whatismybrowser.com/guides/the-latest-user-agent/safari
|
|
51
|
+
platform = 'iOS';
|
|
52
|
+
platformVersion = padVersion(m[2].replace(/_/g, '.'));
|
|
53
|
+
} else if ((m = /(iPad); CPU OS (\d+(_\d+)*)/.exec(platformInfo)) !== null) {
|
|
54
|
+
platform = 'iOS';
|
|
55
|
+
platformVersion = padVersion(m[2].replace(/_/g, '.'));
|
|
56
|
+
} else if ((m = /Macintosh; (Intel|\w+) Mac OS X (\d+([_.]\d+)*)/.exec(platformInfo)) !== null) {
|
|
57
|
+
platform = 'macOS';
|
|
58
|
+
platformVersion = padVersion(m[2].replace(/_/g, '.'));
|
|
59
|
+
} else if ((m = /Linux/.exec(platformInfo)) !== null) {
|
|
60
|
+
platform = 'Linux';
|
|
61
|
+
platformVersion = '';
|
|
62
|
+
// TODO
|
|
63
|
+
} else if ((m = /CrOS (\w+) (\d+(\.\d+)*)/.exec(platformInfo)) !== null) {
|
|
64
|
+
platform = 'Chrome OS';
|
|
65
|
+
platformVersion = padVersion(m[2]);
|
|
66
|
+
m2 = parseArch(m[1]);
|
|
67
|
+
architecture = m2[0];
|
|
68
|
+
bitness = m2[1];
|
|
69
|
+
}
|
|
70
|
+
if (!platform) {
|
|
71
|
+
platform = 'Unknown';
|
|
72
|
+
}
|
|
73
|
+
// detect fullVersionList / brands
|
|
74
|
+
let notABrand = {brand: ' Not;A Brand', version: '99.0.0.0'};
|
|
75
|
+
if ((m = /Chrome\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null && navigator.vendor === 'Google Inc.') {
|
|
76
|
+
fullVersionList.push({brand: 'Chromium', version: padVersion(m[1], 4)});
|
|
77
|
+
if ((m2 = /(Edge?)\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null) {
|
|
78
|
+
let identBrandMap = {
|
|
79
|
+
'Edge': 'Microsoft Edge',
|
|
80
|
+
'Edg': 'Microsoft Edge',
|
|
81
|
+
};
|
|
82
|
+
let brand = identBrandMap[m[1]];
|
|
83
|
+
fullVersionList.push({brand: brand, version: padVersion(m2[2], 4)});
|
|
84
|
+
} else {
|
|
85
|
+
fullVersionList.push({brand: 'Google Chrome', version: padVersion(m[1], 4)});
|
|
86
|
+
}
|
|
87
|
+
if (/\bwv\b/.exec(platformInfo)) {
|
|
88
|
+
webview = true;
|
|
89
|
+
}
|
|
90
|
+
} else if ((m = /AppleWebKit\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null && navigator.vendor === 'Apple Computer, Inc.') {
|
|
91
|
+
fullVersionList.push({brand: 'WebKit', version: padVersion(m[1])});
|
|
92
|
+
if (platform === 'iOS' && (m2 = /(CriOS|EdgiOS|FxiOS|Version)\/(\d+(\.\d+)*)/.exec(versionInfo)) != null) {
|
|
93
|
+
let identBrandMap = { // no
|
|
94
|
+
'CriOS': 'Google Chrome',
|
|
95
|
+
'EdgiOS': 'Microsoft Edge',
|
|
96
|
+
'FxiOS': 'Mozilla Firefox',
|
|
97
|
+
'Version': 'Apple Safari',
|
|
98
|
+
};
|
|
99
|
+
let brand = identBrandMap[m2[1]];
|
|
100
|
+
fullVersionList.push({brand, version: padVersion(m2[2])});
|
|
101
|
+
if (items.findIndex((s) => s.startsWith('Safari/')) === -1) {
|
|
102
|
+
webview = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} else if ((m = /Firefox\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null) {
|
|
106
|
+
fullVersionList.push({brand: 'Firefox', version: padVersion(m[1])});
|
|
107
|
+
} else {
|
|
108
|
+
fullVersionList.push(notABrand);
|
|
109
|
+
}
|
|
110
|
+
uaFullVersion = fullVersionList.length > 0 ? fullVersionList[fullVersionList.length - 1] : '';
|
|
111
|
+
let brands = fullVersionList.map((b) => {
|
|
112
|
+
let pos = b.version.indexOf('.');
|
|
113
|
+
let version = pos === -1 ? b.version : b.version.slice(0, pos);
|
|
114
|
+
return {brand: b.brand, version};
|
|
115
|
+
});
|
|
116
|
+
// TODO detect architecture, bitness and model
|
|
117
|
+
return {
|
|
118
|
+
mobile,
|
|
119
|
+
platform,
|
|
120
|
+
brands,
|
|
121
|
+
platformVersion,
|
|
122
|
+
architecture,
|
|
123
|
+
bitness,
|
|
124
|
+
model,
|
|
125
|
+
uaFullVersion,
|
|
126
|
+
fullVersionList,
|
|
127
|
+
webview
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function parseArch(arch) {
|
|
132
|
+
switch (arch) {
|
|
133
|
+
case 'x86_64':
|
|
134
|
+
case 'x64':
|
|
135
|
+
return ['x86', '64'];
|
|
136
|
+
case 'x86_32':
|
|
137
|
+
case 'x86':
|
|
138
|
+
return ['x86', ''];
|
|
139
|
+
case 'armv6l':
|
|
140
|
+
case 'armv7l':
|
|
141
|
+
case 'armv8l':
|
|
142
|
+
return [arch, ''];
|
|
143
|
+
case 'aarch64':
|
|
144
|
+
return ['arm', '64'];
|
|
145
|
+
default:
|
|
146
|
+
return ['', ''];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function padVersion(ver, minSegs = 3) {
|
|
150
|
+
let parts = ver.split('.');
|
|
151
|
+
let len = parts.length;
|
|
152
|
+
if (len < minSegs) {
|
|
153
|
+
for (let i = 0, lenToPad = minSegs - len; i < lenToPad; i += 1) {
|
|
154
|
+
parts.push('0');
|
|
155
|
+
}
|
|
156
|
+
return parts.join('.');
|
|
157
|
+
}
|
|
158
|
+
return ver;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
class NavigatorUAData {
|
|
162
|
+
constructor(navigator) {
|
|
163
|
+
this._ch = getClientHints(navigator);
|
|
164
|
+
Object.defineProperties(this, {
|
|
165
|
+
_ch: {enumerable: false},
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
get mobile() {
|
|
169
|
+
return this._ch.mobile;
|
|
170
|
+
}
|
|
171
|
+
get platform() {
|
|
172
|
+
return this._ch.platform;
|
|
173
|
+
}
|
|
174
|
+
get brands() {
|
|
175
|
+
return this._ch.brands;
|
|
176
|
+
}
|
|
177
|
+
getHighEntropyValues(hints) {
|
|
178
|
+
return new Promise((resolve, reject) => {
|
|
179
|
+
if (!Array.isArray(hints)) {
|
|
180
|
+
throw new TypeError('argument hints is not an array');
|
|
181
|
+
}
|
|
182
|
+
let hintSet = new Set(hints);
|
|
183
|
+
let data = this._ch;
|
|
184
|
+
let obj = {
|
|
185
|
+
mobile: data.mobile,
|
|
186
|
+
platform: data.platform,
|
|
187
|
+
brands: data.brands,
|
|
188
|
+
};
|
|
189
|
+
if (hintSet.has('architecture'))
|
|
190
|
+
obj.architecture = data.architecture;
|
|
191
|
+
if (hintSet.has('bitness'))
|
|
192
|
+
obj.bitness = data.bitness;
|
|
193
|
+
if (hintSet.has('model'))
|
|
194
|
+
obj.model = data.model;
|
|
195
|
+
if (hintSet.has('platformVersion'))
|
|
196
|
+
obj.platformVersion = data.platformVersion;
|
|
197
|
+
if (hintSet.has('uaFullVersion'))
|
|
198
|
+
obj.uaFullVersion = data.uaFullVersion;
|
|
199
|
+
if (hintSet.has('fullVersionList'))
|
|
200
|
+
obj.fullVersionList = data.fullVersionList;
|
|
201
|
+
resolve(obj);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
toJSON() {
|
|
205
|
+
let data = this._ch;
|
|
206
|
+
return {
|
|
207
|
+
mobile: data.mobile,
|
|
208
|
+
brands: data.brands,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
Object.defineProperty(NavigatorUAData.prototype, Symbol.toStringTag, {
|
|
213
|
+
enumerable: false,
|
|
214
|
+
configurable: true,
|
|
215
|
+
writable: false,
|
|
216
|
+
value: 'NavigatorUAData'
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
async function getClientInfo(navigator, keys) {
|
|
220
|
+
let info = {};
|
|
221
|
+
if (location.protocol === 'https:') {
|
|
222
|
+
if (!keys) {
|
|
223
|
+
keys = ['brands', 'mobile', 'platform', 'platformVersion', 'architecture', 'bitness', 'model', 'fullVersionList'];
|
|
224
|
+
}
|
|
225
|
+
if (!navigator.userAgentData) {
|
|
226
|
+
let customUAData = new NavigatorUAData(navigator);
|
|
227
|
+
info = await customUAData.getHighEntropyValues(keys);
|
|
228
|
+
} else {
|
|
229
|
+
info = await navigator.userAgentData.getHighEntropyValues(keys);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return info;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = {
|
|
236
|
+
getClientInfo
|
|
237
|
+
};
|
package/src/flashphoner-core.js
CHANGED
|
@@ -4,6 +4,7 @@ const { v1: uuid_v1 } = require('uuid');
|
|
|
4
4
|
const constants = require("./constants");
|
|
5
5
|
const util = require('./util');
|
|
6
6
|
const LoggerObject = require('./util').logger;
|
|
7
|
+
const clientInfo = require('./client-info');
|
|
7
8
|
const Promise = require('promise-polyfill');
|
|
8
9
|
const KalmanFilter = require('kalmanjs');
|
|
9
10
|
const browserDetails = require('webrtc-adapter').default.browserDetails;
|
|
@@ -11,6 +12,7 @@ const LOG_PREFIX = "core";
|
|
|
11
12
|
var coreLogger;
|
|
12
13
|
var loggerConf = {push: false, severity: "INFO"};
|
|
13
14
|
var isUsingTemasysPlugin = false;
|
|
15
|
+
var clientUAData;
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* @namespace Flashphoner
|
|
@@ -62,7 +64,7 @@ var disableConnectionQualityCalculation;
|
|
|
62
64
|
* @throws {Error} Error if none of MediaProviders available
|
|
63
65
|
* @memberof Flashphoner
|
|
64
66
|
*/
|
|
65
|
-
var init = function (options) {
|
|
67
|
+
var init = async function (options) {
|
|
66
68
|
if (!initialized) {
|
|
67
69
|
if (!options) {
|
|
68
70
|
options = {};
|
|
@@ -190,8 +192,12 @@ var init = function (options) {
|
|
|
190
192
|
if (!waitingTemasys && options.mediaProvidersReadyCallback) {
|
|
191
193
|
options.mediaProvidersReadyCallback(Object.keys(MediaProvider));
|
|
192
194
|
}
|
|
195
|
+
|
|
193
196
|
coreLogger.info(LOG_PREFIX, "Initialized");
|
|
194
197
|
initialized = true;
|
|
198
|
+
|
|
199
|
+
clientUAData = await clientInfo.getClientInfo(window.navigator);
|
|
200
|
+
coreLogger.info(LOG_PREFIX, "Client system data: " + JSON.stringify(clientUAData));
|
|
195
201
|
}
|
|
196
202
|
};
|
|
197
203
|
|
|
@@ -572,13 +578,16 @@ var createSession = function (options) {
|
|
|
572
578
|
appKey: appKey,
|
|
573
579
|
mediaProviders: Object.keys(MediaProvider),
|
|
574
580
|
keepAlive: keepAlive,
|
|
575
|
-
authToken:authToken,
|
|
581
|
+
authToken: authToken,
|
|
576
582
|
clientVersion: "2.0",
|
|
577
583
|
clientOSVersion: window.navigator.appVersion,
|
|
578
584
|
clientBrowserVersion: window.navigator.userAgent,
|
|
579
585
|
msePacketizationVersion: 2,
|
|
580
586
|
custom: options.custom
|
|
581
587
|
};
|
|
588
|
+
if (clientUAData) {
|
|
589
|
+
cConfig.clientInfo = clientUAData;
|
|
590
|
+
}
|
|
582
591
|
if (sipConfig) {
|
|
583
592
|
util.copyObjectPropsToAnotherObject(sipConfig, cConfig);
|
|
584
593
|
}
|
|
@@ -1009,6 +1018,8 @@ var createSession = function (options) {
|
|
|
1009
1018
|
stripCodecs: stripCodecs
|
|
1010
1019
|
});
|
|
1011
1020
|
}).then(function (offer) {
|
|
1021
|
+
// Get local media info to send in publishStream message
|
|
1022
|
+
let localMediaInfo = collectLocalMediaInfo(MediaProvider[mediaProvider], localDisplay);
|
|
1012
1023
|
send("call", {
|
|
1013
1024
|
callId: id_,
|
|
1014
1025
|
incoming: false,
|
|
@@ -1021,7 +1032,8 @@ var createSession = function (options) {
|
|
|
1021
1032
|
caller: login,
|
|
1022
1033
|
callee: callee_,
|
|
1023
1034
|
custom: options.custom,
|
|
1024
|
-
visibleName: visibleName_
|
|
1035
|
+
visibleName: visibleName_,
|
|
1036
|
+
localMediaInfo: localMediaInfo
|
|
1025
1037
|
});
|
|
1026
1038
|
});
|
|
1027
1039
|
}).catch(function (error) {
|
|
@@ -1155,6 +1167,8 @@ var createSession = function (options) {
|
|
|
1155
1167
|
});
|
|
1156
1168
|
}).then(function (sdp) {
|
|
1157
1169
|
if (status_ != CALL_STATUS.FINISH && status_ != CALL_STATUS.FAILED) {
|
|
1170
|
+
// Get local media info to send in publishStream message
|
|
1171
|
+
let localMediaInfo = collectLocalMediaInfo(MediaProvider[mediaProvider], localDisplay);
|
|
1158
1172
|
send("answer", {
|
|
1159
1173
|
callId: id_,
|
|
1160
1174
|
incoming: true,
|
|
@@ -1166,7 +1180,8 @@ var createSession = function (options) {
|
|
|
1166
1180
|
sipSDP: sipSDP,
|
|
1167
1181
|
caller: cConfig.login,
|
|
1168
1182
|
callee: callee_,
|
|
1169
|
-
custom: options.custom
|
|
1183
|
+
custom: options.custom,
|
|
1184
|
+
localMediaInfo: localMediaInfo
|
|
1170
1185
|
});
|
|
1171
1186
|
} else {
|
|
1172
1187
|
hangup();
|
|
@@ -2006,6 +2021,7 @@ var createSession = function (options) {
|
|
|
2006
2021
|
}
|
|
2007
2022
|
return;
|
|
2008
2023
|
}
|
|
2024
|
+
|
|
2009
2025
|
//create mediaProvider connection
|
|
2010
2026
|
MediaProvider[mediaProvider].createConnection({
|
|
2011
2027
|
id: id_,
|
|
@@ -2028,6 +2044,8 @@ var createSession = function (options) {
|
|
|
2028
2044
|
});
|
|
2029
2045
|
}).then(function (offer) {
|
|
2030
2046
|
logger.debug(LOG_PREFIX, "Offer SDP:\n" + offer.sdp);
|
|
2047
|
+
// Get local media info to send in publishStream message
|
|
2048
|
+
let localMediaInfo = collectLocalMediaInfo(MediaProvider[mediaProvider], display);
|
|
2031
2049
|
//publish stream with offer sdp to server
|
|
2032
2050
|
send("publishStream", {
|
|
2033
2051
|
mediaSessionId: id_,
|
|
@@ -2046,7 +2064,8 @@ var createSession = function (options) {
|
|
|
2046
2064
|
rtmpUrl: rtmpUrl,
|
|
2047
2065
|
constraints: constraints,
|
|
2048
2066
|
transport: transportType,
|
|
2049
|
-
cvoExtension: cvoExtension
|
|
2067
|
+
cvoExtension: cvoExtension,
|
|
2068
|
+
localMediaInfo: localMediaInfo
|
|
2050
2069
|
});
|
|
2051
2070
|
});
|
|
2052
2071
|
}).catch(function (error) {
|
|
@@ -2856,6 +2875,65 @@ var createSession = function (options) {
|
|
|
2856
2875
|
return sessionLogger;
|
|
2857
2876
|
};
|
|
2858
2877
|
|
|
2878
|
+
const collectLocalMediaInfo = function (mediaProvider, display) {
|
|
2879
|
+
// Get devices available
|
|
2880
|
+
let videoCams = mediaProvider.videoCams || [];
|
|
2881
|
+
let mics = mediaProvider.mics || [];
|
|
2882
|
+
|
|
2883
|
+
if (videoCams.length) {
|
|
2884
|
+
logger.info(LOG_PREFIX, "Video inputs available: " + JSON.stringify(videoCams));
|
|
2885
|
+
}
|
|
2886
|
+
if (mics.length) {
|
|
2887
|
+
logger.info(LOG_PREFIX, "Audio inputs available: " + JSON.stringify(mics));
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2890
|
+
// Get track labels to identify publishing device
|
|
2891
|
+
let audioTracks = [];
|
|
2892
|
+
let videoTracks = [];
|
|
2893
|
+
let localVideo;
|
|
2894
|
+
if (mediaProvider.getCacheInstance) {
|
|
2895
|
+
localVideo = mediaProvider.getCacheInstance(display);
|
|
2896
|
+
}
|
|
2897
|
+
if (!localVideo && mediaProvider.getVideoElement) {
|
|
2898
|
+
localVideo = mediaProvider.getVideoElement(display);
|
|
2899
|
+
}
|
|
2900
|
+
if (localVideo) {
|
|
2901
|
+
localVideo.srcObject.getAudioTracks().forEach((track) => {
|
|
2902
|
+
let device = track.label;
|
|
2903
|
+
if (device === "MediaStreamAudioDestinationNode" && mediaProvider.getAudioSourceDevice) {
|
|
2904
|
+
device = mediaProvider.getAudioSourceDevice();
|
|
2905
|
+
}
|
|
2906
|
+
audioTracks.push({
|
|
2907
|
+
trackId: track.id,
|
|
2908
|
+
device: device
|
|
2909
|
+
});
|
|
2910
|
+
});
|
|
2911
|
+
localVideo.srcObject.getVideoTracks().forEach((track) => {
|
|
2912
|
+
videoTracks.push({
|
|
2913
|
+
trackId: track.id,
|
|
2914
|
+
device: track.label
|
|
2915
|
+
});
|
|
2916
|
+
});
|
|
2917
|
+
}
|
|
2918
|
+
if (videoTracks.length) {
|
|
2919
|
+
logger.info(LOG_PREFIX, "Video tracks captured: " + JSON.stringify(videoTracks));
|
|
2920
|
+
}
|
|
2921
|
+
if (audioTracks.length) {
|
|
2922
|
+
logger.info(LOG_PREFIX, "Audio tracks captured: " + JSON.stringify(audioTracks));
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
return {
|
|
2926
|
+
devices: {
|
|
2927
|
+
video: videoCams,
|
|
2928
|
+
audio: mics
|
|
2929
|
+
},
|
|
2930
|
+
tracks: {
|
|
2931
|
+
video: videoTracks,
|
|
2932
|
+
audio: audioTracks
|
|
2933
|
+
}
|
|
2934
|
+
};
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2859
2937
|
//export Session
|
|
2860
2938
|
session.id = id;
|
|
2861
2939
|
session.status = status;
|
|
@@ -19,6 +19,8 @@ var validBrowsers = ["firefox", "chrome", "safari"];
|
|
|
19
19
|
var videoCams = [];
|
|
20
20
|
// list of presented audio input devices
|
|
21
21
|
var mics = [];
|
|
22
|
+
// current audio source device label
|
|
23
|
+
let audioSourceDevice = "";
|
|
22
24
|
|
|
23
25
|
var createConnection = function (options) {
|
|
24
26
|
return new Promise(function (resolve, reject) {
|
|
@@ -955,10 +957,14 @@ var getMediaAccess = function (constraints, display, disableConstraintsNormaliza
|
|
|
955
957
|
// WCS-2933, fix mobile streaming issues, gather info about available devices before streaming, but not during
|
|
956
958
|
listDevices(false).then((devices) => {
|
|
957
959
|
devices.video.forEach(function (device) {
|
|
958
|
-
videoCams.
|
|
960
|
+
if (!videoCams.find((cam) => device.id === cam.id)) {
|
|
961
|
+
videoCams.push(device);
|
|
962
|
+
}
|
|
959
963
|
})
|
|
960
964
|
devices.audio.forEach(function (device) {
|
|
961
|
-
mics.
|
|
965
|
+
if (!mics.find((mic) => device.id === mic.id)) {
|
|
966
|
+
mics.push(device);
|
|
967
|
+
}
|
|
962
968
|
})
|
|
963
969
|
navigator.getUserMedia(constraints, function (stream) {
|
|
964
970
|
loadVideo(display, stream, screenShare, requestAudioConstraints, resolve, constraints, useCanvas);
|
|
@@ -1188,6 +1194,7 @@ var createGainNode = function (stream) {
|
|
|
1188
1194
|
source.connect(gainNode);
|
|
1189
1195
|
gainNode.connect(destination);
|
|
1190
1196
|
var sourceAudioTrack = stream.getAudioTracks()[0];
|
|
1197
|
+
audioSourceDevice = sourceAudioTrack.label;
|
|
1191
1198
|
gainNode.sourceAudioTrack = sourceAudioTrack;
|
|
1192
1199
|
gainNode.release = function () {
|
|
1193
1200
|
this.sourceAudioTrack.stop();
|
|
@@ -1198,6 +1205,10 @@ var createGainNode = function (stream) {
|
|
|
1198
1205
|
return gainNode;
|
|
1199
1206
|
};
|
|
1200
1207
|
|
|
1208
|
+
const getAudioSourceDevice = function () {
|
|
1209
|
+
return audioSourceDevice;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1201
1212
|
//Fix to set screen resolution for screen sharing in Firefox
|
|
1202
1213
|
var setScreenResolution = function (video, stream, constraints) {
|
|
1203
1214
|
var newHeight;
|
|
@@ -1314,6 +1325,22 @@ function getCacheInstance(display) {
|
|
|
1314
1325
|
}
|
|
1315
1326
|
}
|
|
1316
1327
|
|
|
1328
|
+
function getVideoElement(display) {
|
|
1329
|
+
if (display) {
|
|
1330
|
+
for (const child of display.children) {
|
|
1331
|
+
if (child.tagName.toLowerCase() === "video") {
|
|
1332
|
+
return child;
|
|
1333
|
+
} else {
|
|
1334
|
+
let grandchild = getVideoElement(child);
|
|
1335
|
+
if (grandchild) {
|
|
1336
|
+
return grandchild;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return null;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1317
1344
|
function createVideoElement(useControls = false) {
|
|
1318
1345
|
let video = document.createElement('video');
|
|
1319
1346
|
// Prepare video tag to auto play and add specific Safari tweaks #WCS-2425
|
|
@@ -1440,8 +1467,8 @@ var listDevices = function (labels, kind, deviceConstraints) {
|
|
|
1440
1467
|
return;
|
|
1441
1468
|
}
|
|
1442
1469
|
navigator.getUserMedia(constraints, function (stream) {
|
|
1443
|
-
navigator.mediaDevices.enumerateDevices().then(function (
|
|
1444
|
-
resolve(getList(
|
|
1470
|
+
navigator.mediaDevices.enumerateDevices().then(function (devicesWithLabels) {
|
|
1471
|
+
resolve(getList(devicesWithLabels));
|
|
1445
1472
|
stream.getTracks().forEach(function (track) {
|
|
1446
1473
|
track.stop();
|
|
1447
1474
|
});
|
|
@@ -1581,5 +1608,10 @@ module.exports = {
|
|
|
1581
1608
|
logger = configuration.logger;
|
|
1582
1609
|
createMicGainNode = (typeof configuration.createMicGainNode !== 'undefined') ? configuration.createMicGainNode : true;
|
|
1583
1610
|
logger.info(LOG_PREFIX, "Initialized");
|
|
1584
|
-
}
|
|
1611
|
+
},
|
|
1612
|
+
videoCams: videoCams,
|
|
1613
|
+
mics: mics,
|
|
1614
|
+
getAudioSourceDevice: getAudioSourceDevice,
|
|
1615
|
+
getCacheInstance: getCacheInstance,
|
|
1616
|
+
getVideoElement: getVideoElement
|
|
1585
1617
|
};
|