@flashphoner/sfusdk-examples 2.0.244 → 2.0.248
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/package.json +2 -2
- package/src/client/chat.js +15 -1
- package/src/client/config.json +2 -2
- package/src/client/controls.js +4 -2
- package/src/client/main.html +3 -2
- package/src/client/main.js +49 -47
- package/src/commons/js/display.js +1481 -635
- package/src/commons/js/util.js +4 -0
- package/src/player/player.js +3 -7
- package/src/track-test/track-test.css +26 -0
- package/src/track-test/track-test.html +89 -0
- package/src/track-test/track-test.js +646 -0
- package/src/two-way-streaming/config.json +3 -3
- package/src/two-way-streaming/two-way-streaming.js +86 -89
- package/src/webrtc-abr-player/player.js +16 -23
- package/src/client/display.js +0 -502
- package/src/client/util.js +0 -67
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flashphoner/sfusdk-examples",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.248",
|
|
4
4
|
"description": "Official Flashphoner WebCallServer SFU SDK usage examples",
|
|
5
5
|
"main": "dist/sfu.js",
|
|
6
6
|
"types": "src/sfu.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"ts-loader": "^9.2.8",
|
|
25
25
|
"typescript": "^4.6.3",
|
|
26
26
|
"webpack": "^5.72.0",
|
|
27
|
-
"webpack-cli": "^4.
|
|
27
|
+
"webpack-cli": "^4.10.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@flashphoner/sfusdk": "^2.0.193",
|
package/src/client/chat.js
CHANGED
|
@@ -7,16 +7,19 @@ const createChat = function(room, messages, input, sendButton) {
|
|
|
7
7
|
|
|
8
8
|
room.on(constants.SFU_ROOM_EVENT.MESSAGE, function(e) {
|
|
9
9
|
appendMessage({
|
|
10
|
+
userId: getUserId(e.message),
|
|
10
11
|
nickName: getNickName(e.message),
|
|
11
12
|
message: getMessage(e.message)
|
|
12
13
|
}, chatOtherColour, chatTextColour);
|
|
13
14
|
}).on(constants.SFU_ROOM_EVENT.JOINED, function(e) {
|
|
14
15
|
appendMessage({
|
|
16
|
+
userId: getShortUserId(e.userId),
|
|
15
17
|
nickName: e.name,
|
|
16
18
|
message: e.type
|
|
17
19
|
}, chatOtherColour, chatEventColour);
|
|
18
20
|
}).on(constants.SFU_ROOM_EVENT.LEFT, function(e) {
|
|
19
21
|
appendMessage({
|
|
22
|
+
userId: getShortUserId(e.userId),
|
|
20
23
|
nickName: e.name,
|
|
21
24
|
message: e.type
|
|
22
25
|
}, chatOtherColour, chatEventColour);
|
|
@@ -27,6 +30,7 @@ const createChat = function(room, messages, input, sendButton) {
|
|
|
27
30
|
input.value = "";
|
|
28
31
|
await room.sendMessage(message);
|
|
29
32
|
appendMessage({
|
|
33
|
+
userId: getShortUserId(room.userId()),
|
|
30
34
|
nickName: nickName.value,
|
|
31
35
|
message: message
|
|
32
36
|
}, chatSelfColour, chatTextColour);
|
|
@@ -50,7 +54,7 @@ const createChat = function(room, messages, input, sendButton) {
|
|
|
50
54
|
messages.appendChild(message);
|
|
51
55
|
let nickDiv = document.createElement('div');
|
|
52
56
|
nickDiv.style.color = nickColour;
|
|
53
|
-
nickDiv.innerText = getChatTimestamp() + " " + msg.nickName + ":";
|
|
57
|
+
nickDiv.innerText = getChatTimestamp() + " " + msg.nickName + "#" + msg.userId + ":";
|
|
54
58
|
message.appendChild(nickDiv);
|
|
55
59
|
let msgDiv = document.createElement('div');
|
|
56
60
|
msgDiv.style.color = msgColour;
|
|
@@ -68,6 +72,16 @@ const createChat = function(room, messages, input, sendButton) {
|
|
|
68
72
|
return currentdate.getHours() + ":" + currentdate.getMinutes() + ":" + currentdate.getSeconds();
|
|
69
73
|
}
|
|
70
74
|
|
|
75
|
+
const getUserId = function(msgData) {
|
|
76
|
+
let userId = "unknown";
|
|
77
|
+
if (msgData.userId) {
|
|
78
|
+
userId = msgData.userId;
|
|
79
|
+
} else if (msgData.message.userId) {
|
|
80
|
+
userId = msgData.message.userId;
|
|
81
|
+
}
|
|
82
|
+
return getShortUserId(userId);
|
|
83
|
+
}
|
|
84
|
+
|
|
71
85
|
const getNickName = function(msgData) {
|
|
72
86
|
let nickName = "unknown";
|
|
73
87
|
if (msgData.nickName) {
|
package/src/client/config.json
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"height": 720,
|
|
18
18
|
"codec": "H264",
|
|
19
19
|
"encodings": [
|
|
20
|
-
{ "rid": "
|
|
21
|
-
{ "rid": "
|
|
20
|
+
{ "rid": "m", "active": true, "maxBitrate": 300000, "scaleResolutionDownBy": 2 },
|
|
21
|
+
{ "rid": "h", "active": true, "maxBitrate": 900000 }
|
|
22
22
|
]
|
|
23
23
|
}]
|
|
24
24
|
}
|
package/src/client/controls.js
CHANGED
|
@@ -94,7 +94,8 @@ const createControls = function(config) {
|
|
|
94
94
|
trackCallback({
|
|
95
95
|
stream: stream,
|
|
96
96
|
encodings: track.encodings,
|
|
97
|
-
source: track.source
|
|
97
|
+
source: track.source,
|
|
98
|
+
type: track.type
|
|
98
99
|
});
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -185,7 +186,8 @@ const createControls = function(config) {
|
|
|
185
186
|
streams.push({
|
|
186
187
|
stream: data.stream,
|
|
187
188
|
encodings: data.encodings,
|
|
188
|
-
source: data.source
|
|
189
|
+
source: data.source,
|
|
190
|
+
type: data.type
|
|
189
191
|
});
|
|
190
192
|
});
|
|
191
193
|
return streams;
|
package/src/client/main.html
CHANGED
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
<link rel="stylesheet" href="main.css">
|
|
17
17
|
<script type="text/javascript" src="../sfu.js"></script>
|
|
18
18
|
<script type="text/javascript" src="chat.js"></script>
|
|
19
|
-
<script type="text/javascript" src="display.js"></script>
|
|
20
|
-
<script type="text/javascript" src="util.js"></script>
|
|
19
|
+
<script type="text/javascript" src="../commons/js/display.js"></script>
|
|
20
|
+
<script type="text/javascript" src="../commons/js/util.js"></script>
|
|
21
|
+
<script type="text/javascript" src="../commons/js/stats.js"></script>
|
|
21
22
|
<script type="text/javascript" src="controls.js"></script>
|
|
22
23
|
<script type="text/javascript" src="main.js"></script>
|
|
23
24
|
</head>
|
package/src/client/main.js
CHANGED
|
@@ -27,8 +27,8 @@ const defaultConfig = {
|
|
|
27
27
|
height: 720,
|
|
28
28
|
codec: "H264",
|
|
29
29
|
encodings: [
|
|
30
|
-
{
|
|
31
|
-
{
|
|
30
|
+
{rid: "m", active: true, maxBitrate: 300000, scaleResolutionDownBy: 2},
|
|
31
|
+
{rid: "h", active: true, maxBitrate: 900000}
|
|
32
32
|
]
|
|
33
33
|
}
|
|
34
34
|
]
|
|
@@ -39,11 +39,11 @@ const defaultConfig = {
|
|
|
39
39
|
/**
|
|
40
40
|
* Load track configuration and show entrance modal
|
|
41
41
|
*/
|
|
42
|
-
const init = function() {
|
|
42
|
+
const init = function () {
|
|
43
43
|
//read config
|
|
44
|
-
$.getJSON("config.json", function(config){
|
|
44
|
+
$.getJSON("config.json", function (config) {
|
|
45
45
|
cControls = createControls(config);
|
|
46
|
-
}).fail(function(){
|
|
46
|
+
}).fail(function () {
|
|
47
47
|
//use default config
|
|
48
48
|
cControls = createControls(defaultConfig);
|
|
49
49
|
});
|
|
@@ -67,7 +67,7 @@ async function connect() {
|
|
|
67
67
|
try {
|
|
68
68
|
const session = await sfu.createRoom(roomConfig);
|
|
69
69
|
// Now we connected to the server (if no exception was thrown)
|
|
70
|
-
session.on(constants.SFU_EVENT.FAILED, function(e) {
|
|
70
|
+
session.on(constants.SFU_EVENT.FAILED, function (e) {
|
|
71
71
|
if (e.status && e.statusText) {
|
|
72
72
|
displayError("CONNECTION FAILED: " + e.status + " " + e.statusText);
|
|
73
73
|
} else if (e.type && e.info) {
|
|
@@ -75,11 +75,11 @@ async function connect() {
|
|
|
75
75
|
} else {
|
|
76
76
|
displayError("CONNECTION FAILED: " + e);
|
|
77
77
|
}
|
|
78
|
-
}).on(constants.SFU_EVENT.DISCONNECTED, function(e) {
|
|
78
|
+
}).on(constants.SFU_EVENT.DISCONNECTED, function (e) {
|
|
79
79
|
displayError("DISCONNECTED. Refresh the page to enter the room again");
|
|
80
80
|
});
|
|
81
81
|
const room = session.room();
|
|
82
|
-
room.on(constants.SFU_ROOM_EVENT.FAILED, function(e) {
|
|
82
|
+
room.on(constants.SFU_ROOM_EVENT.FAILED, function (e) {
|
|
83
83
|
displayError(e);
|
|
84
84
|
}).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
|
|
85
85
|
displayError(e.operation + " failed: " + e.error);
|
|
@@ -100,7 +100,11 @@ async function connect() {
|
|
|
100
100
|
|
|
101
101
|
//setup remote display for showing remote audio/video tracks
|
|
102
102
|
const remoteDisplay = document.getElementById("display");
|
|
103
|
-
|
|
103
|
+
initDefaultRemoteDisplay(room, remoteDisplay, {quality: true},{thresholds: [
|
|
104
|
+
{parameter: "nackCount", maxLeap: 10},
|
|
105
|
+
{parameter: "freezeCount", maxLeap: 10},
|
|
106
|
+
{parameter: "packetsLost", maxLeap: 10}
|
|
107
|
+
], abrKeepOnGoodQuality: ABR_KEEP_ON_QUALITY, abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY, interval: ABR_QUALITY_CHECK_PERIOD});
|
|
104
108
|
|
|
105
109
|
//get configured local video streams
|
|
106
110
|
let streams = cControls.getVideoStreams();
|
|
@@ -109,7 +113,7 @@ async function connect() {
|
|
|
109
113
|
|
|
110
114
|
// Publish preconfigured streams
|
|
111
115
|
publishPreconfiguredStreams(room, pc, streams);
|
|
112
|
-
} catch(e) {
|
|
116
|
+
} catch (e) {
|
|
113
117
|
console.error(e);
|
|
114
118
|
displayError(e);
|
|
115
119
|
}
|
|
@@ -121,7 +125,7 @@ async function connect() {
|
|
|
121
125
|
* @param prefix
|
|
122
126
|
* @param event
|
|
123
127
|
*/
|
|
124
|
-
const onOperationFailed = function(prefix, event) {
|
|
128
|
+
const onOperationFailed = function (prefix, event) {
|
|
125
129
|
let reason = "reason unknown";
|
|
126
130
|
if (event.operation && event.error) {
|
|
127
131
|
reason = event.operation + " failed: " + event.error;
|
|
@@ -137,34 +141,32 @@ const onOperationFailed = function(prefix, event) {
|
|
|
137
141
|
|
|
138
142
|
/**
|
|
139
143
|
* Publish streams after entering room according to configuration file
|
|
140
|
-
*
|
|
144
|
+
*
|
|
141
145
|
* @param {*} room
|
|
142
146
|
* @param {*} pc
|
|
143
|
-
* @param {*} streams
|
|
147
|
+
* @param {*} streams
|
|
144
148
|
*/
|
|
145
|
-
const publishPreconfiguredStreams = async function(room, pc, streams) {
|
|
149
|
+
const publishPreconfiguredStreams = async function (room, pc, streams) {
|
|
146
150
|
try {
|
|
147
|
-
|
|
151
|
+
const config = {};
|
|
148
152
|
//add our local streams to the room (to PeerConnection)
|
|
149
153
|
streams.forEach(function (s) {
|
|
150
|
-
|
|
151
|
-
localDisplay.add(s.stream.id, "local", s.stream);
|
|
154
|
+
let contentType = s.type || s.source;
|
|
152
155
|
//add each track to PeerConnection
|
|
153
156
|
s.stream.getTracks().forEach((track) => {
|
|
154
|
-
|
|
155
|
-
config[track.id] = s.source;
|
|
156
|
-
}
|
|
157
|
+
config[track.id] = contentType;
|
|
157
158
|
addTrackToPeerConnection(pc, s.stream, track, s.encodings);
|
|
158
159
|
subscribeTrackToEndedEvent(room, track, pc);
|
|
159
160
|
});
|
|
161
|
+
localDisplay.add(s.stream.id, "local", s.stream, contentType);
|
|
160
162
|
});
|
|
161
163
|
//join room
|
|
162
|
-
await room.join(pc, null, config);
|
|
164
|
+
await room.join(pc, null, config, 10);
|
|
163
165
|
// Enable Delete button for each preconfigured stream #WCS-3689
|
|
164
166
|
streams.forEach(function (s) {
|
|
165
167
|
$('#' + s.stream.id + "-button").prop('disabled', false);
|
|
166
168
|
});
|
|
167
|
-
} catch(e) {
|
|
169
|
+
} catch (e) {
|
|
168
170
|
onOperationFailed("Failed to publish a preconfigured streams", e);
|
|
169
171
|
// Enable Delete button for each preconfigured stream #WCS-3689
|
|
170
172
|
streams.forEach(function (s) {
|
|
@@ -175,21 +177,21 @@ const publishPreconfiguredStreams = async function(room, pc, streams) {
|
|
|
175
177
|
|
|
176
178
|
/**
|
|
177
179
|
* Publish a new media track to the room
|
|
178
|
-
*
|
|
180
|
+
*
|
|
179
181
|
* @param {*} room
|
|
180
182
|
* @param {*} pc
|
|
181
|
-
* @param {*} media
|
|
183
|
+
* @param {*} media
|
|
182
184
|
*/
|
|
183
|
-
const publishNewTrack = async function(room, pc, media) {
|
|
185
|
+
const publishNewTrack = async function (room, pc, media) {
|
|
184
186
|
try {
|
|
185
187
|
let config = {};
|
|
186
188
|
//add local stream to local display
|
|
187
|
-
|
|
189
|
+
let contentType = media.type || media.source;
|
|
190
|
+
|
|
191
|
+
localDisplay.add(media.stream.id, "local", media.stream, contentType);
|
|
188
192
|
//add each track to PeerConnection
|
|
189
193
|
media.stream.getTracks().forEach((track) => {
|
|
190
|
-
|
|
191
|
-
config[track.id] = media.source;
|
|
192
|
-
}
|
|
194
|
+
config[track.id] = contentType;
|
|
193
195
|
addTrackToPeerConnection(pc, media.stream, track, media.encodings);
|
|
194
196
|
subscribeTrackToEndedEvent(room, track, pc);
|
|
195
197
|
});
|
|
@@ -199,7 +201,7 @@ const publishNewTrack = async function(room, pc, media) {
|
|
|
199
201
|
await room.updateState(config);
|
|
200
202
|
// Enable Delete button for a new stream #WCS-3689
|
|
201
203
|
$('#' + media.stream.id + "-button").prop('disabled', false);
|
|
202
|
-
} catch(e) {
|
|
204
|
+
} catch (e) {
|
|
203
205
|
onOperationFailed("Failed to publish a new track", e);
|
|
204
206
|
// Enable Delete button for a new stream #WCS-3689
|
|
205
207
|
$('#' + media.stream.id + "-button").prop('disabled', false);
|
|
@@ -208,13 +210,13 @@ const publishNewTrack = async function(room, pc, media) {
|
|
|
208
210
|
|
|
209
211
|
/**
|
|
210
212
|
* Subscribe to track ended event to renegotiate WebRTC connection
|
|
211
|
-
*
|
|
212
|
-
* @param {*} room
|
|
213
|
-
* @param {*} track
|
|
214
|
-
* @param {*} pc
|
|
213
|
+
*
|
|
214
|
+
* @param {*} room
|
|
215
|
+
* @param {*} track
|
|
216
|
+
* @param {*} pc
|
|
215
217
|
*/
|
|
216
|
-
const subscribeTrackToEndedEvent = function(room, track, pc) {
|
|
217
|
-
track.addEventListener("ended", async function() {
|
|
218
|
+
const subscribeTrackToEndedEvent = function (room, track, pc) {
|
|
219
|
+
track.addEventListener("ended", async function () {
|
|
218
220
|
try {
|
|
219
221
|
//track ended, see if we need to cleanup
|
|
220
222
|
let negotiate = false;
|
|
@@ -232,7 +234,7 @@ const subscribeTrackToEndedEvent = function(room, track, pc) {
|
|
|
232
234
|
//kickoff renegotiation
|
|
233
235
|
await room.updateState();
|
|
234
236
|
}
|
|
235
|
-
} catch(e) {
|
|
237
|
+
} catch (e) {
|
|
236
238
|
onOperationFailed("Failed to update room state", e);
|
|
237
239
|
}
|
|
238
240
|
});
|
|
@@ -240,13 +242,13 @@ const subscribeTrackToEndedEvent = function(room, track, pc) {
|
|
|
240
242
|
|
|
241
243
|
/**
|
|
242
244
|
* Add track to WebRTC PeerConnection
|
|
243
|
-
*
|
|
244
|
-
* @param {*} pc
|
|
245
|
-
* @param {*} stream
|
|
246
|
-
* @param {*} track
|
|
247
|
-
* @param {*} encodings
|
|
245
|
+
*
|
|
246
|
+
* @param {*} pc
|
|
247
|
+
* @param {*} stream
|
|
248
|
+
* @param {*} track
|
|
249
|
+
* @param {*} encodings
|
|
248
250
|
*/
|
|
249
|
-
const addTrackToPeerConnection = function(pc, stream, track, encodings) {
|
|
251
|
+
const addTrackToPeerConnection = function (pc, stream, track, encodings) {
|
|
250
252
|
pc.addTransceiver(track, {
|
|
251
253
|
direction: "sendonly",
|
|
252
254
|
streams: [stream],
|
|
@@ -256,10 +258,10 @@ const addTrackToPeerConnection = function(pc, stream, track, encodings) {
|
|
|
256
258
|
|
|
257
259
|
/**
|
|
258
260
|
* Display error message
|
|
259
|
-
*
|
|
260
|
-
* @param {*} text
|
|
261
|
+
*
|
|
262
|
+
* @param {*} text
|
|
261
263
|
*/
|
|
262
|
-
const displayError = function(text) {
|
|
264
|
+
const displayError = function (text) {
|
|
263
265
|
const errField = document.getElementById("errorMsg");
|
|
264
266
|
errField.style.color = "red";
|
|
265
267
|
errField.innerText = text;
|
|
@@ -268,7 +270,7 @@ const displayError = function(text) {
|
|
|
268
270
|
/**
|
|
269
271
|
* Entrance modal cancelled, we do not enter to a room
|
|
270
272
|
*/
|
|
271
|
-
const cancel = function() {
|
|
273
|
+
const cancel = function () {
|
|
272
274
|
//hide modal
|
|
273
275
|
$('#entranceModal').modal('hide');
|
|
274
276
|
//disable controls
|