@flashphoner/sfusdk-examples 2.0.56
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/README.md +43 -0
- package/package.json +32 -0
- package/src/client/chat.js +67 -0
- package/src/client/config.json +26 -0
- package/src/client/controls.js +314 -0
- package/src/client/display.js +502 -0
- package/src/client/main.css +45 -0
- package/src/client/main.html +220 -0
- package/src/client/main.js +157 -0
- package/src/client/resources/details_close.png +0 -0
- package/src/client/resources/details_open.png +0 -0
- package/src/client/util.js +67 -0
- package/src/commons/js/config.js +81 -0
- package/src/commons/js/display.js +484 -0
- package/src/commons/js/util.js +202 -0
- package/src/commons/media/silence.mp3 +0 -0
- package/src/controller/dependencies/sigma/sigma.renderers.edgeLabels.min.js +1 -0
- package/src/controller/dependencies/sigma/sigma.renderers.parallelEdges.min.js +1 -0
- package/src/controller/dependencies/sigma/sigma.require.js +12076 -0
- package/src/controller/graph-view.js +32 -0
- package/src/controller/main.css +45 -0
- package/src/controller/main.html +79 -0
- package/src/controller/main.js +65 -0
- package/src/controller/parser.js +202 -0
- package/src/controller/resources/details_close.png +0 -0
- package/src/controller/resources/details_open.png +0 -0
- package/src/controller/rest.js +56 -0
- package/src/controller/table-view.js +64 -0
- package/src/controller/test-data.js +382 -0
- package/src/player/config.json +8 -0
- package/src/player/player.css +19 -0
- package/src/player/player.html +54 -0
- package/src/player/player.js +209 -0
- package/src/sfu.ts +28 -0
- package/src/two-way-streaming/config.json +34 -0
- package/src/two-way-streaming/two-way-streaming.css +26 -0
- package/src/two-way-streaming/two-way-streaming.html +72 -0
- package/src/two-way-streaming/two-way-streaming.js +375 -0
- package/tsconfig.json +15 -0
- package/webpack.config.js +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @flashphoner/sfusdk
|
|
2
|
+
|
|
3
|
+
# Flashphoner WebCallServer SFU API (SFU SDK) usage examples
|
|
4
|
+
|
|
5
|
+
Flashphoner [WebCallServer](https://flashphoner.com) [SFU](https://docs.flashphoner.com/display/WCS52EN/SFU+functions+with+Simulcast) API (SFU SDK) usage examples.
|
|
6
|
+
|
|
7
|
+
## Get the sources
|
|
8
|
+
|
|
9
|
+
Install as NPM package
|
|
10
|
+
```
|
|
11
|
+
npm init
|
|
12
|
+
npm install @flashphoner/sfusdk-examples
|
|
13
|
+
cd node_modules/@flashphoner/sfusdk-examples
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
or download from GitHub
|
|
17
|
+
```
|
|
18
|
+
git clone https://github.com/flashphoner/sfu_sdk.git
|
|
19
|
+
cd sfu_sdk/examples
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Build
|
|
23
|
+
```
|
|
24
|
+
npm install && npm run build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Deploy to web server
|
|
28
|
+
```
|
|
29
|
+
mkdir -p /var/www/html/flashphoner-sfu-test
|
|
30
|
+
cp -r dist/* /var/www/html/flashphoner-sfu-test
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
|
|
35
|
+
[SFU functions description](https://docs.flashphoner.com/display/WCS52EN/SFU+functions+with+Simulcast)
|
|
36
|
+
|
|
37
|
+
[SFU SDK documentation](https://docs.flashphoner.com/display/SS1E/SFU+SDK+1.0+-+EN)
|
|
38
|
+
|
|
39
|
+
[SFU examples description](https://docs.flashphoner.com/display/SS1E/SFU+SDK+Examples)
|
|
40
|
+
|
|
41
|
+
[API documentation](http://flashphoner.com/docs/api/WCS5/client/sfu-sdk/latest)
|
|
42
|
+
|
|
43
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flashphoner/sfusdk-examples",
|
|
3
|
+
"version": "2.0.56",
|
|
4
|
+
"description": "Official Flashphoner WebCallServer SFU SDK usage examples",
|
|
5
|
+
"main": "dist/sfu.js",
|
|
6
|
+
"types": "src/sfu.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"/dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"clean": "rm -rf dist/*",
|
|
12
|
+
"build": "webpack --mode=production"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"Flashphoner",
|
|
16
|
+
"WebCallServer",
|
|
17
|
+
"SFU SDK"
|
|
18
|
+
],
|
|
19
|
+
"author": "Flashphoner",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@mapbox/node-pre-gyp": "^1.0.8",
|
|
23
|
+
"copy-webpack-plugin": "^10.2.4",
|
|
24
|
+
"ts-loader": "^9.2.8",
|
|
25
|
+
"typescript": "^4.6.3",
|
|
26
|
+
"webpack": "^5.72.0",
|
|
27
|
+
"webpack-cli": "^4.9.2"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@flashphoner/sfusdk": "^2.0.48"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const createChat = function(room, messages, input, sendButton) {
|
|
2
|
+
const constants = SFU.constants;
|
|
3
|
+
const chatSelfColour = "green";
|
|
4
|
+
const chatTextColour = "black";
|
|
5
|
+
const chatOtherColour = "red";
|
|
6
|
+
const chatEventColour = "navy";
|
|
7
|
+
|
|
8
|
+
room.on(constants.SFU_ROOM_EVENT.MESSAGE, function(e) {
|
|
9
|
+
appendMessage(e, chatOtherColour, chatTextColour);
|
|
10
|
+
}).on(constants.SFU_ROOM_EVENT.JOINED, function(e) {
|
|
11
|
+
appendMessage({
|
|
12
|
+
nickName: e.name,
|
|
13
|
+
message: e.type
|
|
14
|
+
}, chatOtherColour, chatEventColour);
|
|
15
|
+
}).on(constants.SFU_ROOM_EVENT.LEFT, function(e) {
|
|
16
|
+
appendMessage({
|
|
17
|
+
nickName: e.name,
|
|
18
|
+
message: e.type
|
|
19
|
+
}, chatOtherColour, chatEventColour);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const sendMessage = function() {
|
|
23
|
+
let message = input.value;
|
|
24
|
+
input.value = "";
|
|
25
|
+
room.sendMessage(message);
|
|
26
|
+
appendMessage({
|
|
27
|
+
nickName: nickName.value,
|
|
28
|
+
message: message
|
|
29
|
+
}, chatSelfColour, chatTextColour);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
sendButton.addEventListener("click", sendMessage);
|
|
33
|
+
input.onkeyup = function(e) {
|
|
34
|
+
if (e.keyCode === 13) {
|
|
35
|
+
if (e.shiftKey) {
|
|
36
|
+
|
|
37
|
+
} else {
|
|
38
|
+
sendMessage();
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const appendMessage = function(msg, nickColour, msgColour) {
|
|
45
|
+
let message = document.createElement('div');
|
|
46
|
+
message.setAttribute("class","message");
|
|
47
|
+
messages.appendChild(message);
|
|
48
|
+
let nickDiv = document.createElement('div');
|
|
49
|
+
nickDiv.style.color = nickColour;
|
|
50
|
+
nickDiv.innerText = getChatTimestamp() + " " + msg.nickName + ":";
|
|
51
|
+
message.appendChild(nickDiv);
|
|
52
|
+
let msgDiv = document.createElement('div');
|
|
53
|
+
msgDiv.style.color = msgColour;
|
|
54
|
+
msgDiv.innerText = msg.message;
|
|
55
|
+
message.appendChild(msgDiv);
|
|
56
|
+
scrollToBottom();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const scrollToBottom = function() {
|
|
60
|
+
messages.scrollTop = messages.scrollHeight;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const getChatTimestamp = function() {
|
|
64
|
+
let currentdate = new Date();
|
|
65
|
+
return currentdate.getHours() + ":" + currentdate.getMinutes() + ":" + currentdate.getSeconds();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"room": {
|
|
3
|
+
"url": "ws://127.0.0.1:8080",
|
|
4
|
+
"name": "ROOM1",
|
|
5
|
+
"pin": "1234",
|
|
6
|
+
"nickName": "Bob"
|
|
7
|
+
},
|
|
8
|
+
"media": {
|
|
9
|
+
"audio": {
|
|
10
|
+
"tracks": [
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"video": {
|
|
14
|
+
"tracks": [{
|
|
15
|
+
"source": "camera",
|
|
16
|
+
"width": 1280,
|
|
17
|
+
"height": 720,
|
|
18
|
+
"codec": "H264",
|
|
19
|
+
"encodings": [
|
|
20
|
+
{ "rid": "h", "active": true, "maxBitrate": 900000 },
|
|
21
|
+
{ "rid": "m", "active": true, "maxBitrate": 300000, "scaleResolutionDownBy": 2 }
|
|
22
|
+
]
|
|
23
|
+
}]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
const createControls = function(config) {
|
|
2
|
+
|
|
3
|
+
let trackCallback = function(){};
|
|
4
|
+
|
|
5
|
+
const controls = {
|
|
6
|
+
entrance: {
|
|
7
|
+
url: document.getElementById("url"),
|
|
8
|
+
roomName: document.getElementById("roomName"),
|
|
9
|
+
roomPin: document.getElementById("roomPin"),
|
|
10
|
+
nickName: document.getElementById("nickName"),
|
|
11
|
+
enter: document.getElementById("startButton")
|
|
12
|
+
},
|
|
13
|
+
addVideoTrack: {
|
|
14
|
+
source: document.getElementById("addVideoTrackSource"),
|
|
15
|
+
width: document.getElementById("addVideoTrackWidth"),
|
|
16
|
+
height: document.getElementById("addVideoTrackHeight"),
|
|
17
|
+
codec: document.getElementById("addVideoTrackCodec")
|
|
18
|
+
},
|
|
19
|
+
addAudioTrack: {
|
|
20
|
+
source: document.getElementById("addAudioTrackSource"),
|
|
21
|
+
channels: document.getElementById("addAudioTrackChannels")
|
|
22
|
+
},
|
|
23
|
+
addVideoEncoding: {
|
|
24
|
+
rid: document.getElementById("addVideoTrackEncodingRid"),
|
|
25
|
+
active: document.getElementById("addVideoTrackEncodingActive"),
|
|
26
|
+
maxBitrate: document.getElementById("addVideoTrackEncodingMaxBitrate"),
|
|
27
|
+
resolutionScale: document.getElementById("addVideoTrackEncodingResolutionScale")
|
|
28
|
+
},
|
|
29
|
+
tables: {
|
|
30
|
+
video: $('#videoTracksTable').DataTable({
|
|
31
|
+
"sDom": 't',
|
|
32
|
+
"columns": [
|
|
33
|
+
{
|
|
34
|
+
"className": 'details-control',
|
|
35
|
+
"orderable": false,
|
|
36
|
+
"data": null,
|
|
37
|
+
"defaultContent": ''
|
|
38
|
+
},
|
|
39
|
+
{"data": "source"},
|
|
40
|
+
{"data": "width"},
|
|
41
|
+
{"data": "height"},
|
|
42
|
+
{"data": "codec"},
|
|
43
|
+
{"data": "action"}
|
|
44
|
+
]
|
|
45
|
+
}),
|
|
46
|
+
audio: $('#audioTracksTable').DataTable({
|
|
47
|
+
"sDom": 't',
|
|
48
|
+
"columns": [
|
|
49
|
+
{"data": "source"},
|
|
50
|
+
{"data": "channels"},
|
|
51
|
+
{"data": "action"}
|
|
52
|
+
]
|
|
53
|
+
}),
|
|
54
|
+
encodings: $('#videoTrackEncodingsTable').DataTable({
|
|
55
|
+
"sDom": 't',
|
|
56
|
+
"columns": [
|
|
57
|
+
{"data": "rid"},
|
|
58
|
+
{"data": "active"},
|
|
59
|
+
{"data": "maxBitrate"},
|
|
60
|
+
{"data": "resolutionScale"},
|
|
61
|
+
{"data": "action"}
|
|
62
|
+
]
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//apply room config
|
|
68
|
+
controls.entrance.url.value = config.room.url;
|
|
69
|
+
controls.entrance.roomName.value = config.room.name;
|
|
70
|
+
controls.entrance.roomPin.value = config.room.pin;
|
|
71
|
+
controls.entrance.nickName.value = config.room.nickName;
|
|
72
|
+
|
|
73
|
+
const addAudioTrackRow = function(track) {
|
|
74
|
+
getMedia([track]).then(function(stream){
|
|
75
|
+
let button = '<button id="' + stream.id + '-button" class="btn btn-primary">Delete</button>';
|
|
76
|
+
const row = controls.tables.audio.row.add({
|
|
77
|
+
source: track.source,
|
|
78
|
+
channels: track.channels,
|
|
79
|
+
action: button,
|
|
80
|
+
stream: stream
|
|
81
|
+
}).node();
|
|
82
|
+
controls.tables.audio.draw();
|
|
83
|
+
|
|
84
|
+
$('#' + stream.id + "-button").on('click', function(){
|
|
85
|
+
//terminate stream
|
|
86
|
+
console.log("terminate stream " + stream.id);
|
|
87
|
+
let track = stream.getAudioTracks()[0];
|
|
88
|
+
track.stop();
|
|
89
|
+
track.dispatchEvent(new Event("ended"));
|
|
90
|
+
});
|
|
91
|
+
stream.getTracks()[0].onended = function() {
|
|
92
|
+
controls.tables.audio.row(row).remove().draw();
|
|
93
|
+
}
|
|
94
|
+
trackCallback({
|
|
95
|
+
stream: stream,
|
|
96
|
+
encodings: track.encodings,
|
|
97
|
+
source: track.source
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const addVideoTrackRow = function(track) {
|
|
103
|
+
getMedia([track]).then(function(stream){
|
|
104
|
+
let button = '<button id="' + stream.id + '-button" class="btn btn-primary">Delete</button>';
|
|
105
|
+
const row = controls.tables.video.row.add({
|
|
106
|
+
source: track.source,
|
|
107
|
+
width: track.width,
|
|
108
|
+
height: track.height,
|
|
109
|
+
codec: track.codec,
|
|
110
|
+
action: button,
|
|
111
|
+
stream: stream,
|
|
112
|
+
encodings: track.encodings
|
|
113
|
+
}).node();
|
|
114
|
+
controls.tables.video.draw();
|
|
115
|
+
|
|
116
|
+
$('#' + stream.id + "-button").on('click', function(){
|
|
117
|
+
//terminate stream
|
|
118
|
+
console.log("terminate stream " + stream.id);
|
|
119
|
+
let track = stream.getVideoTracks()[0];
|
|
120
|
+
track.stop();
|
|
121
|
+
track.dispatchEvent(new Event("ended"));
|
|
122
|
+
});
|
|
123
|
+
stream.getTracks()[0].addEventListener("ended", function() {
|
|
124
|
+
controls.tables.video.row(row).remove().draw();
|
|
125
|
+
});
|
|
126
|
+
trackCallback({
|
|
127
|
+
stream: stream,
|
|
128
|
+
encodings: track.encodings,
|
|
129
|
+
source: track.source
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const format = function(d) {
|
|
135
|
+
if (!d.encodings) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
let details = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
|
|
139
|
+
d.encodings.forEach(function(encoding){
|
|
140
|
+
details += '<tr>';
|
|
141
|
+
for (const [key, value] of Object.entries(encoding)) {
|
|
142
|
+
details += '<td>'+ key + '</td>'+
|
|
143
|
+
'<td>'+ value + '</td>';
|
|
144
|
+
}
|
|
145
|
+
details += '</tr>';
|
|
146
|
+
});
|
|
147
|
+
details +='</table>';
|
|
148
|
+
return details;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Add event listener for opening and closing details
|
|
152
|
+
$('#videoTracksTableBody').on('click', 'td.details-control', function () {
|
|
153
|
+
let tr = $(this).closest('tr');
|
|
154
|
+
let row = controls.tables.video.row(tr);
|
|
155
|
+
if (row.child.isShown()) {
|
|
156
|
+
// This row is already open - close it
|
|
157
|
+
row.child.hide();
|
|
158
|
+
tr.removeClass('shown');
|
|
159
|
+
} else {
|
|
160
|
+
// Open this row
|
|
161
|
+
row.child(format(row.data())).show();
|
|
162
|
+
tr.addClass('shown');
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
config.media.audio.tracks.forEach(function(track){
|
|
167
|
+
addAudioTrackRow(track);
|
|
168
|
+
})
|
|
169
|
+
config.media.video.tracks.forEach(function(track){
|
|
170
|
+
addVideoTrackRow(track);
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
const muteForm = function(form) {
|
|
174
|
+
for (const [key, value] of Object.entries(form)) {
|
|
175
|
+
value.disabled = true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const unmuteForm = function(form) {
|
|
180
|
+
for (const [key, value] of Object.entries(form)) {
|
|
181
|
+
value.disabled = false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const muteInput = function() {
|
|
186
|
+
muteForm(controls.entrance);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const roomConfig = function() {
|
|
190
|
+
return {
|
|
191
|
+
url: controls.entrance.url.value,
|
|
192
|
+
roomName: controls.entrance.roomName.value,
|
|
193
|
+
pin: controls.entrance.roomPin.value,
|
|
194
|
+
nickname: controls.entrance.nickName.value
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const getVideoStreams = function() {
|
|
199
|
+
let streams = [];
|
|
200
|
+
controls.tables.video.rows().every(function(rowIdx, tableLoop, rowLoop) {
|
|
201
|
+
let data = this.data();
|
|
202
|
+
streams.push({
|
|
203
|
+
stream: data.stream,
|
|
204
|
+
encodings: data.encodings,
|
|
205
|
+
source: data.source
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
return streams;
|
|
209
|
+
}
|
|
210
|
+
const getAudioStreams = function() {
|
|
211
|
+
let streams = [];
|
|
212
|
+
controls.tables.audio.rows().every(function(rowIdx, tableLoop, rowLoop) {
|
|
213
|
+
let data = this.data();
|
|
214
|
+
streams.push({
|
|
215
|
+
stream: data.stream,
|
|
216
|
+
encodings: [],
|
|
217
|
+
source: data.source
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
return streams;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
document.getElementById("addVideoTrack").addEventListener("click", function(e){
|
|
224
|
+
let encodings = [];
|
|
225
|
+
controls.tables.encodings.rows().every(function() {
|
|
226
|
+
let encoding = this.data();
|
|
227
|
+
encodings.push({
|
|
228
|
+
rid: encoding.rid,
|
|
229
|
+
active: encoding.active,
|
|
230
|
+
maxBitrate: encoding.maxBitrate,
|
|
231
|
+
scaleResolutionDownBy: encoding.resolutionScale
|
|
232
|
+
})
|
|
233
|
+
});
|
|
234
|
+
let track = {
|
|
235
|
+
source: controls.addVideoTrack.source.value,
|
|
236
|
+
width: controls.addVideoTrack.width.value,
|
|
237
|
+
height: controls.addVideoTrack.height.value,
|
|
238
|
+
codec: controls.addVideoTrack.codec.value,
|
|
239
|
+
encodings: encodings
|
|
240
|
+
}
|
|
241
|
+
addVideoTrackRow(track);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
$("#videoTrackEncodingsTable").on("click", ".remove", function(){
|
|
245
|
+
controls.tables.encodings.row($(this).parents('tr')).remove().draw();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
document.getElementById("addVideoTrackEncoding").addEventListener("click", function(){
|
|
249
|
+
let button = '<button class="btn btn-primary remove">Delete</button>';
|
|
250
|
+
controls.tables.encodings.row.add({
|
|
251
|
+
rid: controls.addVideoEncoding.rid.value,
|
|
252
|
+
active: controls.addVideoEncoding.active.value,
|
|
253
|
+
maxBitrate: controls.addVideoEncoding.maxBitrate.value,
|
|
254
|
+
resolutionScale: controls.addVideoEncoding.resolutionScale.value,
|
|
255
|
+
action: button
|
|
256
|
+
}).draw();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
document.getElementById("addAudioTrack").addEventListener("click", function(e){
|
|
260
|
+
let encodings = [];
|
|
261
|
+
let track = {
|
|
262
|
+
source: controls.addAudioTrack.source.value,
|
|
263
|
+
channels: controls.addAudioTrack.channels.value,
|
|
264
|
+
encodings: encodings
|
|
265
|
+
}
|
|
266
|
+
addAudioTrackRow(track);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const onTrack = function(callback) {
|
|
270
|
+
trackCallback = callback;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
muteInput: muteInput,
|
|
276
|
+
roomConfig: roomConfig,
|
|
277
|
+
getAudioStreams: getAudioStreams,
|
|
278
|
+
getVideoStreams: getVideoStreams,
|
|
279
|
+
onTrack: onTrack
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const getMedia = async function(tracks) {
|
|
284
|
+
//convert to constraints
|
|
285
|
+
let screen = false;
|
|
286
|
+
const constraints= {};
|
|
287
|
+
tracks.forEach(function(track){
|
|
288
|
+
if (track.source === "mic") {
|
|
289
|
+
//audio
|
|
290
|
+
constraints.audio = {};
|
|
291
|
+
constraints.audio.stereo = track.channels !== 1
|
|
292
|
+
} else if (track.source === "camera") {
|
|
293
|
+
constraints.video = {
|
|
294
|
+
width: track.width,
|
|
295
|
+
height: track.height
|
|
296
|
+
};
|
|
297
|
+
} else if (track.source === "screen") {
|
|
298
|
+
constraints.video = {
|
|
299
|
+
width: track.width,
|
|
300
|
+
height: track.height
|
|
301
|
+
};
|
|
302
|
+
screen = true;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
//get access to a/v
|
|
307
|
+
let stream;
|
|
308
|
+
if (screen) {
|
|
309
|
+
stream = await navigator.mediaDevices.getDisplayMedia(constraints);
|
|
310
|
+
} else {
|
|
311
|
+
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
312
|
+
}
|
|
313
|
+
return stream;
|
|
314
|
+
}
|