@reactoo/watchtogether-sdk-js 2.7.80 → 2.7.82
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/dist/watchtogether-sdk.min.js +2 -2
- package/example/index.html +7 -1
- package/package.json +1 -1
- package/src/index.js +2 -2
- package/src/models/asset.js +1 -1
- package/src/models/auth.js +5 -5
- package/src/models/room-session.js +1 -1
- package/src/models/room.js +6 -6
- package/src/models/user.js +10 -10
- package/src/models/utils.js +261 -116
- package/src/modules/sync-modules/sync-dash-vod.js +63 -63
- package/src/modules/sync-modules/sync-dash.js +85 -85
- package/src/modules/sync-modules/sync-dazn-dash.js +92 -92
- package/src/modules/sync-modules/sync-dazn.js +91 -91
- package/src/modules/sync-modules/sync-doris.js +84 -84
- package/src/modules/sync-modules/sync-hls-vod.js +65 -65
- package/src/modules/sync-modules/sync-hls.js +58 -58
- package/src/modules/sync-modules/sync-module.js +68 -68
- package/src/modules/sync-modules/sync-native-hls-vod.js +66 -66
- package/src/modules/sync-modules/sync-native-hls.js +82 -82
- package/src/modules/sync-modules/sync-shaka-dash-vod.js +62 -62
- package/src/modules/sync-modules/sync-shaka-dash.js +93 -93
- package/src/modules/wt-iot.js +1 -1
- package/src/modules/wt-iot2.js +1 -1
- package/src/modules/wt-room.js +5 -4
- package/src/modules/wt-utils.js +0 -142
package/example/index.html
CHANGED
|
@@ -222,7 +222,7 @@
|
|
|
222
222
|
console.log('Iot message:', r);
|
|
223
223
|
});
|
|
224
224
|
|
|
225
|
-
Instance.auth.
|
|
225
|
+
Instance.auth.login('dusan1','abc123ABC') // login as browser
|
|
226
226
|
.then(r => Instance.iot.iotLogin()) // login to mqtt
|
|
227
227
|
.then(r => {
|
|
228
228
|
if(roomId) {
|
|
@@ -527,6 +527,12 @@
|
|
|
527
527
|
sess.sendSystemMessage('customData', {some: 'data'})
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
window.testUnsetAttributesObject = function() {
|
|
531
|
+
Instance.room.updateAttribute({id:'boha', roomId: roomId, operation: 'setAll', attributeName:'layoutAttributes', value: {cicina:'kuchyna'}})
|
|
532
|
+
.then(r => console.log(r))
|
|
533
|
+
.catch(e => console.log(e))
|
|
534
|
+
}
|
|
535
|
+
|
|
530
536
|
</script>
|
|
531
537
|
|
|
532
538
|
</body>
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -9,8 +9,8 @@ import room from './models/room';
|
|
|
9
9
|
import user from './models/user';
|
|
10
10
|
import asset from "./models/asset";
|
|
11
11
|
import system from "./models/system"
|
|
12
|
-
import utils from './models/utils';
|
|
13
12
|
import iot from './models/iot'
|
|
13
|
+
import * as utils from './models/utils';
|
|
14
14
|
|
|
15
15
|
function WatchTogether(modules = {}, instanceType, debug, playerFactory, providerAuth) {
|
|
16
16
|
this.username = null;
|
|
@@ -31,7 +31,7 @@ function WatchTogether(modules = {}, instanceType, debug, playerFactory, provide
|
|
|
31
31
|
this.isReady = modules.room.whenInitialized;
|
|
32
32
|
this.browser = modules.room.browser;
|
|
33
33
|
this.browserDetails = modules.room.browserDetails
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
this.auth = {...auth.call(this)};
|
|
36
36
|
this.user = {...user.call(this)};
|
|
37
37
|
this.room = {...room.call(this)};
|
package/src/models/asset.js
CHANGED
package/src/models/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {getBrowserFingerprint} from "./utils";
|
|
4
4
|
|
|
5
5
|
let auth = function () {
|
|
6
6
|
return {
|
|
@@ -15,11 +15,11 @@ let auth = function () {
|
|
|
15
15
|
},
|
|
16
16
|
|
|
17
17
|
providerLogin: (domain, token, displayname, deviceId) => {
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
if(!token && typeof this.__privates.providerAuth === 'function') {
|
|
20
20
|
({token, displayname} = this.__privates.providerAuth());
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
return this.__privates.auth.__client
|
|
24
24
|
.then(client => client.apis.auth.providerSignIn({},{requestBody:{domain, token, ...(displayname && {displayname}), ...(deviceId && {deviceId})}}))
|
|
25
25
|
.then(response => {
|
|
@@ -32,7 +32,7 @@ let auth = function () {
|
|
|
32
32
|
getProviderAuth: () => {
|
|
33
33
|
return this.__privates.providerAuth;
|
|
34
34
|
},
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
deviceLogin: ( usePrecise = false, salt = 'ThisIsSaltyAF') => {
|
|
37
37
|
return getBrowserFingerprint(this.__instanceType, usePrecise, salt)
|
|
38
38
|
.then( deviceId => Promise.all([deviceId, this.__privates.auth.__client]))
|
|
@@ -55,7 +55,7 @@ let auth = function () {
|
|
|
55
55
|
setLanguage: (language) => {
|
|
56
56
|
return this.__privates.auth.setLanguage(language);
|
|
57
57
|
},
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
getLanguage: () => {
|
|
60
60
|
return this.__privates.auth.__language;
|
|
61
61
|
},
|
package/src/models/room.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import roomSession from './room-session';
|
|
4
4
|
import streamingSession from "./streaming-session";
|
|
5
|
-
import {decodeJanusDisplay} from "
|
|
5
|
+
import {decodeJanusDisplay} from "./utils";
|
|
6
6
|
|
|
7
7
|
let room = function () {
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
let roomSessions = [];
|
|
10
10
|
|
|
11
11
|
let setExitListeners = () => {
|
|
@@ -54,7 +54,7 @@ let room = function () {
|
|
|
54
54
|
}
|
|
55
55
|
}))
|
|
56
56
|
},
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
createRoom: ({sourceRoomId, title, description, isPublic, isRouter, isStudioLayout, wtChannelId, isHd, disableSync, reduceRoomControls, hasStudioChat, maxParticipants, customAttributes, chatRoomId, linkedRoomId, type, dotAttribute} = {}) => {
|
|
59
59
|
let _da = dotAttribute
|
|
60
60
|
? (Array.isArray(dotAttribute)
|
|
@@ -122,12 +122,12 @@ let room = function () {
|
|
|
122
122
|
}
|
|
123
123
|
}))
|
|
124
124
|
},
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
deleteRoom: (roomId) => {
|
|
127
127
|
return this.__privates.auth.__client
|
|
128
128
|
.then(client => client.apis.wt.deleteRoom({id: roomId}))
|
|
129
129
|
},
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
leaveRoom: (roomId) => {
|
|
132
132
|
return this.__privates.auth.__client
|
|
133
133
|
.then(client => client.apis.wt.leave({roomId}))
|
|
@@ -354,7 +354,7 @@ let room = function () {
|
|
|
354
354
|
},
|
|
355
355
|
|
|
356
356
|
destroySessions: () => {
|
|
357
|
-
roomSessions.forEach(session => session.destroy().catch(e => this.
|
|
357
|
+
roomSessions.forEach(session => session.destroy().catch(e => this.__privates.room._log(e)));
|
|
358
358
|
roomSessions.length = 0;
|
|
359
359
|
},
|
|
360
360
|
|
package/src/models/user.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import {generateUUID, chunkArray} from "
|
|
3
|
+
import {generateUUID, chunkArray} from "./utils";
|
|
4
4
|
import {serializeError} from "serialize-error";
|
|
5
5
|
|
|
6
6
|
let user = function () {
|
|
@@ -9,12 +9,12 @@ let user = function () {
|
|
|
9
9
|
return this.__privates.auth.__client
|
|
10
10
|
.then(client => client.apis.user.updateMyself({...(data.lastRoomId && {lastRoomId:data.lastRoomId})},{requestBody: {...data}}))
|
|
11
11
|
},
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
updateUser: (data = {}) => {
|
|
14
14
|
return this.__privates.auth.__client
|
|
15
15
|
.then(client => client.apis.user.updateUser({id: data.id, lastRoomId: data.lastRoomId}, {requestBody: {displayname: data.displayname, bio: data.bio}}));
|
|
16
16
|
},
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
uploadAvatar: (file, lastRoomId) => {
|
|
19
19
|
let id = generateUUID();
|
|
20
20
|
return this.__privates.auth.__client
|
|
@@ -53,7 +53,7 @@ let user = function () {
|
|
|
53
53
|
return this.__privates.auth.__client
|
|
54
54
|
.then(client => client.apis.reaction.getReactionById({id}))
|
|
55
55
|
},
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
getReactions: ({userId, roomId, type, size, startKey, includeUserModels = false} = {}) => {
|
|
58
58
|
let apiParams = {
|
|
59
59
|
...(roomId && {roomId}),
|
|
@@ -66,12 +66,12 @@ let user = function () {
|
|
|
66
66
|
return this.__privates.auth.__client
|
|
67
67
|
.then(client => client.apis.reaction.getReactions(apiParams))
|
|
68
68
|
},
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
getVideoById: (id) => {
|
|
71
71
|
return this.__privates.auth.__client
|
|
72
72
|
.then(client => client.apis.video.getVideoById({id}))
|
|
73
73
|
},
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
getVideos: ({roomId, userId, type, size, startKey, ids, includeUserModels = false, includeRoomQueueStatus, filter} = {}) => {
|
|
76
76
|
return chunkArray(ids, 50)
|
|
77
77
|
.reduce((promiseChain, idsChunk) => {
|
|
@@ -105,7 +105,7 @@ let user = function () {
|
|
|
105
105
|
return this.__privates.auth.__client
|
|
106
106
|
.then(client => client.apis.video.getVideoListFilters({roomId}));
|
|
107
107
|
},
|
|
108
|
-
|
|
108
|
+
|
|
109
109
|
deleteVideo: (id) => {
|
|
110
110
|
return this.__privates.auth.__client
|
|
111
111
|
.then(client => client.apis.video.deleteVideo({id}))
|
|
@@ -152,7 +152,7 @@ let user = function () {
|
|
|
152
152
|
return this.__privates.auth.__client
|
|
153
153
|
.then(client => client.apis.user.getUsers(apiParams))
|
|
154
154
|
},
|
|
155
|
-
|
|
155
|
+
|
|
156
156
|
//TODO:deprecated
|
|
157
157
|
track: ({eventType = 'ERROR', message} = {}) => {
|
|
158
158
|
return this.__privates.auth.__client
|
|
@@ -202,7 +202,7 @@ let user = function () {
|
|
|
202
202
|
|
|
203
203
|
//TODO:deprecated
|
|
204
204
|
analytics: ({action, startKey = null, limit = 20} = {}) => {
|
|
205
|
-
|
|
205
|
+
|
|
206
206
|
let apiParams = {
|
|
207
207
|
action,
|
|
208
208
|
limit,
|
|
@@ -210,7 +210,7 @@ let user = function () {
|
|
|
210
210
|
};
|
|
211
211
|
return this.__privates.auth.__client
|
|
212
212
|
.then(client => client.apis.wt.analytics({},{requestBody:{instanceType : this.__instanceType, ...apiParams}}));
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
};
|
package/src/models/utils.js
CHANGED
|
@@ -1,5 +1,147 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// import FingerprintJs from "@fingerprintjs/fingerprintjs";
|
|
4
|
+
// import FingerprintJsPro from "@fingerprintjs/fingerprintjs-pro";
|
|
5
|
+
import {getFingerPrint} from "../modules/wt-fingerprint";
|
|
6
|
+
|
|
7
|
+
const wait = function(ms) { return new Promise(resolve => setTimeout(resolve, ms))};
|
|
8
|
+
|
|
9
|
+
const median = function(values) {
|
|
10
|
+
|
|
11
|
+
if(values.length ===0) return 0;
|
|
12
|
+
|
|
13
|
+
values.sort(function(a,b){
|
|
14
|
+
return a-b;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
var half = Math.floor(values.length / 2);
|
|
18
|
+
|
|
19
|
+
if (values.length % 2)
|
|
20
|
+
return values[half];
|
|
21
|
+
|
|
22
|
+
return (values[half - 1] + values[half]) / 2.0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
// const getFingerPrint = function(instanceType, salt) {
|
|
27
|
+
//
|
|
28
|
+
// let fingerprint = FingerprintJs.load({
|
|
29
|
+
// monitoring: false
|
|
30
|
+
// })
|
|
31
|
+
//
|
|
32
|
+
// return fingerprint
|
|
33
|
+
// .then(fp => fp.get())
|
|
34
|
+
// .then(result => {
|
|
35
|
+
// const components = {
|
|
36
|
+
// ...result.components,
|
|
37
|
+
// instanceType: { value: instanceType + '_' + salt },
|
|
38
|
+
// }
|
|
39
|
+
// return [8,13,18,23].reduce((acc, cur) => {
|
|
40
|
+
// return acc.slice(0,cur) + '-' + acc.slice(cur)
|
|
41
|
+
// }, FingerprintJs.hashComponents(components)).substring(0,36)
|
|
42
|
+
// })
|
|
43
|
+
// }
|
|
44
|
+
//
|
|
45
|
+
// const getPreciseFingerPrint = function() {
|
|
46
|
+
//
|
|
47
|
+
// let fingerprintPro = FingerprintJsPro.load({
|
|
48
|
+
// monitoring: false,
|
|
49
|
+
// apiKey: '5UHdpSuX3wHr3CjyEiSP',
|
|
50
|
+
// endpoint: "https://fingerprint.reactoo.com"
|
|
51
|
+
// })
|
|
52
|
+
//
|
|
53
|
+
// return fingerprintPro
|
|
54
|
+
// .then(fp => fp.get())
|
|
55
|
+
// .then(result => {
|
|
56
|
+
// let id = result.visitorId.padEnd(32, '0');
|
|
57
|
+
// return [8,13,18,23].reduce((acc, cur) => {
|
|
58
|
+
// return acc.slice(0,cur) + '-' + acc.slice(cur)
|
|
59
|
+
// }, id).substring(0,36)
|
|
60
|
+
// })
|
|
61
|
+
// }
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
const getBrowserFingerprint = function (instanceType = '', usePrecise = false, salt = '') {
|
|
65
|
+
// if(!usePrecise) {
|
|
66
|
+
// return getFingerPrint(instanceType, salt)
|
|
67
|
+
// }
|
|
68
|
+
// else {
|
|
69
|
+
// return getPreciseFingerPrint()
|
|
70
|
+
// .catch(() => getFingerPrint(instanceType, salt))
|
|
71
|
+
// }
|
|
72
|
+
|
|
73
|
+
return getFingerPrint(instanceType, salt);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
let generateUUID = function () {
|
|
77
|
+
var d = Date.now();
|
|
78
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
79
|
+
var r = (d + Math.random()*16)%16 | 0;
|
|
80
|
+
d = Math.floor(d/16);
|
|
81
|
+
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
const janusDisplayDelimiter = ',';
|
|
87
|
+
const decodeJanusDisplay = display => {
|
|
88
|
+
let output = { userId: null, role: "participant", start: Date.now(), displayName: "?" };
|
|
89
|
+
if(display && typeof display === "string") {
|
|
90
|
+
if(display.indexOf(janusDisplayDelimiter) >= 0) {
|
|
91
|
+
let values = display
|
|
92
|
+
.split( new RegExp(`\\${janusDisplayDelimiter}(?=(?:(?:[^"]*"){2})*[^"]*$)`, 'mi') )
|
|
93
|
+
.map(v => (v && v.startsWith('"') || v.endsWith('"')) ? v.substring(1, v.length-1) : ( /^\d+$/.test(v) ? parseInt(v) : v ));
|
|
94
|
+
Object.keys(output).forEach((key, i) => values[i] ? output[key] = values[i] : null);
|
|
95
|
+
} else {
|
|
96
|
+
output.userId = display;
|
|
97
|
+
}
|
|
98
|
+
return output;
|
|
99
|
+
} else if(display && typeof display === "object") {
|
|
100
|
+
return Object.assign({}, output, display);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const setExactTimeout = function(callback, duration, resolution) {
|
|
106
|
+
const start = (new Date()).getTime();
|
|
107
|
+
const timeout = setInterval(function(){
|
|
108
|
+
if ((new Date()).getTime() - start > duration) {
|
|
109
|
+
callback();
|
|
110
|
+
clearInterval(timeout);
|
|
111
|
+
}
|
|
112
|
+
}, resolution);
|
|
113
|
+
|
|
114
|
+
return timeout;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const clearExactTimeout = function(timeout) {
|
|
118
|
+
clearInterval(timeout);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
const maxJitter = (x) => {
|
|
123
|
+
// A function that returns a value between 0.3 and 0.5 depending on the input x
|
|
124
|
+
// The function is based on a logistic curve with parameters a, b, c, and d
|
|
125
|
+
// The parameters are chosen such that f(30) = 0.3 and f(2) = 0.5
|
|
126
|
+
let a = 0.2; // The maximum value of the function
|
|
127
|
+
let b = -0.1; // The growth rate of the function
|
|
128
|
+
let c = 16; // The inflection point of the function
|
|
129
|
+
let d = 0.3; // The minimum value of the function
|
|
130
|
+
return a / (1 + Math.exp(-b * (x - c))) + d; // Fixed the typo here
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const chunkArray = (array = [], chunkSize) => {
|
|
134
|
+
array = [...array];
|
|
135
|
+
if (!array?.length) return [[]];
|
|
136
|
+
|
|
137
|
+
let results = [];
|
|
138
|
+
while (array.length) {
|
|
139
|
+
results.push(array.splice(0, chunkSize));
|
|
140
|
+
}
|
|
141
|
+
return results;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
3
145
|
const getUserMediaConstraints = ({
|
|
4
146
|
|
|
5
147
|
hasVideo,
|
|
@@ -52,126 +194,129 @@ const getUserMediaConstraints = ({
|
|
|
52
194
|
|
|
53
195
|
};
|
|
54
196
|
|
|
55
|
-
export default {
|
|
56
|
-
//TODO: add more constraints
|
|
57
|
-
applyConstraints({
|
|
58
|
-
autoGainControl = false,
|
|
59
|
-
echoCancellation = true,
|
|
60
|
-
noiseSuppression = true,
|
|
61
|
-
channelCount = 1,
|
|
62
|
-
stream = null,
|
|
63
|
-
width, height
|
|
64
|
-
}) {
|
|
65
|
-
|
|
66
|
-
if(stream) {
|
|
67
|
-
|
|
68
|
-
let fullConstraints = getUserMediaConstraints({
|
|
69
|
-
hasVideo: true,
|
|
70
|
-
hasAudio: true,
|
|
71
|
-
autoGainControl, echoCancellation, noiseSuppression, channelCount, width, height
|
|
72
|
-
});
|
|
73
|
-
let returnPromises = [];
|
|
74
|
-
|
|
75
|
-
const videoTrack = stream.getVideoTracks()[0];
|
|
76
|
-
if(videoTrack) {
|
|
77
|
-
returnPromises.push(videoTrack.applyConstraints(fullConstraints.video));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const audioTrack = stream.getAudioTracks()[0];
|
|
81
|
-
if(audioTrack) {
|
|
82
|
-
returnPromises.push(audioTrack.applyConstraints(fullConstraints.audio));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return Promise.all(returnPromises).then(() => {
|
|
86
|
-
return stream;
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
197
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
echoCancellation = true,
|
|
101
|
-
noiseSuppression = true,
|
|
102
|
-
channelCount = 1,
|
|
103
|
-
muteAudio = false,
|
|
104
|
-
muteVideo = false,
|
|
105
|
-
width = 1920,
|
|
106
|
-
height = 1080
|
|
107
|
-
} = {}
|
|
108
|
-
) {
|
|
198
|
+
const applyConstraints = ({
|
|
199
|
+
autoGainControl = false,
|
|
200
|
+
echoCancellation = true,
|
|
201
|
+
noiseSuppression = true,
|
|
202
|
+
channelCount = 1,
|
|
203
|
+
stream = null,
|
|
204
|
+
width, height
|
|
205
|
+
}) => {
|
|
206
|
+
|
|
207
|
+
if(stream) {
|
|
109
208
|
|
|
110
209
|
let fullConstraints = getUserMediaConstraints({
|
|
111
|
-
hasVideo
|
|
210
|
+
hasVideo: true,
|
|
211
|
+
hasAudio: true,
|
|
212
|
+
autoGainControl, echoCancellation, noiseSuppression, channelCount, width, height
|
|
112
213
|
});
|
|
214
|
+
let returnPromises = [];
|
|
113
215
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
autoGainControl = false,
|
|
128
|
-
echoCancellation = false,
|
|
129
|
-
noiseSuppression = false,
|
|
130
|
-
channelCount = 1,
|
|
131
|
-
width = 1920,
|
|
132
|
-
height = 1080,
|
|
133
|
-
} = {}
|
|
134
|
-
) {
|
|
135
|
-
|
|
136
|
-
let audioOnlyConstraints = {
|
|
137
|
-
audio: {
|
|
138
|
-
...(aDeviceId && {deviceId: {exact:aDeviceId}}),
|
|
139
|
-
autoGainControl,
|
|
140
|
-
echoCancellation,
|
|
141
|
-
noiseSuppression,
|
|
142
|
-
channelCount
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
let videoOnlyConstraints = {
|
|
147
|
-
video: {
|
|
148
|
-
...(vDeviceId && {deviceId: {exact:vDeviceId}}),
|
|
149
|
-
frameRate: {ideal: 30, max: 30},
|
|
150
|
-
width, height
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
let fullConstraints = {
|
|
155
|
-
...(hasAudio ? audioOnlyConstraints : {audio: false}),
|
|
156
|
-
...(hasVideo ? videoOnlyConstraints : {video: false})
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
return navigator.mediaDevices.getUserMedia(fullConstraints);
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
getDisplayMedia() {
|
|
163
|
-
|
|
164
|
-
const constraints = {
|
|
165
|
-
video: {
|
|
166
|
-
cursor: "always",
|
|
167
|
-
displaySurface: "monitor",
|
|
168
|
-
logicalSurface: false
|
|
169
|
-
},
|
|
170
|
-
surfaceSwitching: "include",
|
|
171
|
-
selfBrowserSurface: "exclude",
|
|
172
|
-
systemAudio: "exclude",
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
return navigator.mediaDevices.getDisplayMedia(constraints);
|
|
216
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
217
|
+
if(videoTrack) {
|
|
218
|
+
returnPromises.push(videoTrack.applyConstraints(fullConstraints.video));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const audioTrack = stream.getAudioTracks()[0];
|
|
222
|
+
if(audioTrack) {
|
|
223
|
+
returnPromises.push(audioTrack.applyConstraints(fullConstraints.audio));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return Promise.all(returnPromises).then(() => {
|
|
227
|
+
return stream;
|
|
228
|
+
});
|
|
176
229
|
}
|
|
230
|
+
|
|
231
|
+
else return Promise.resolve(null);
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
};
|
|
235
|
+
const getUserStream = ({
|
|
236
|
+
hasVideo,
|
|
237
|
+
hasAudio = true,
|
|
238
|
+
aDeviceId,
|
|
239
|
+
vDeviceId,
|
|
240
|
+
autoGainControl = false,
|
|
241
|
+
echoCancellation = true,
|
|
242
|
+
noiseSuppression = true,
|
|
243
|
+
channelCount = 1,
|
|
244
|
+
muteAudio = false,
|
|
245
|
+
muteVideo = false,
|
|
246
|
+
width = 1920,
|
|
247
|
+
height = 1080
|
|
248
|
+
} = {}
|
|
249
|
+
) => {
|
|
250
|
+
|
|
251
|
+
let fullConstraints = getUserMediaConstraints({
|
|
252
|
+
hasVideo, hasAudio, aDeviceId, vDeviceId, autoGainControl, echoCancellation, noiseSuppression, channelCount, width, height
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
return navigator.mediaDevices.getUserMedia(fullConstraints)
|
|
256
|
+
.then(stream => {
|
|
257
|
+
stream.getAudioTracks().forEach(track => track.enabled = !muteAudio);
|
|
258
|
+
stream.getVideoTracks().forEach(track => track.enabled = !muteVideo);
|
|
259
|
+
return stream;
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
const getHostStream = ({
|
|
263
|
+
hasAudio,
|
|
264
|
+
hasVideo,
|
|
265
|
+
aDeviceId,
|
|
266
|
+
vDeviceId,
|
|
267
|
+
autoGainControl = false,
|
|
268
|
+
echoCancellation = false,
|
|
269
|
+
noiseSuppression = false,
|
|
270
|
+
channelCount = 1,
|
|
271
|
+
width = 1920,
|
|
272
|
+
height = 1080,
|
|
273
|
+
} = {}
|
|
274
|
+
) => {
|
|
275
|
+
|
|
276
|
+
let audioOnlyConstraints = {
|
|
277
|
+
audio: {
|
|
278
|
+
...(aDeviceId && {deviceId: {exact:aDeviceId}}),
|
|
279
|
+
autoGainControl,
|
|
280
|
+
echoCancellation,
|
|
281
|
+
noiseSuppression,
|
|
282
|
+
channelCount
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
let videoOnlyConstraints = {
|
|
287
|
+
video: {
|
|
288
|
+
...(vDeviceId && {deviceId: {exact:vDeviceId}}),
|
|
289
|
+
frameRate: {ideal: 30, max: 30},
|
|
290
|
+
width, height
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
let fullConstraints = {
|
|
295
|
+
...(hasAudio ? audioOnlyConstraints : {audio: false}),
|
|
296
|
+
...(hasVideo ? videoOnlyConstraints : {video: false})
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
return navigator.mediaDevices.getUserMedia(fullConstraints);
|
|
300
|
+
};
|
|
301
|
+
const getDisplayMedia = () =>{
|
|
302
|
+
const constraints = {
|
|
303
|
+
video: {
|
|
304
|
+
cursor: "always",
|
|
305
|
+
displaySurface: "monitor",
|
|
306
|
+
logicalSurface: false
|
|
307
|
+
},
|
|
308
|
+
surfaceSwitching: "include",
|
|
309
|
+
selfBrowserSurface: "exclude",
|
|
310
|
+
systemAudio: "exclude",
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
return navigator.mediaDevices.getDisplayMedia(constraints);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
export {
|
|
319
|
+
//TODO: add more constraints
|
|
320
|
+
getDisplayMedia, getHostStream, getUserStream, applyConstraints,
|
|
321
|
+
wait, getBrowserFingerprint, generateUUID, decodeJanusDisplay, setExactTimeout, clearExactTimeout, median, maxJitter, chunkArray
|
|
177
322
|
}
|