@flashphoner/sfusdk-examples 2.0.272 → 2.0.274
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
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
<script type="text/javascript" src="../sfu.js"></script>
|
|
16
16
|
<script type="text/javascript" src="../commons/js/util.js"></script>
|
|
17
17
|
<script type="text/javascript" src="../commons/js/config.js"></script>
|
|
18
|
-
<script type="text/javascript" src="../commons/js/display.js"></script>
|
|
19
18
|
<script type="text/javascript" src="bitrate_test.js"></script>
|
|
20
19
|
</head>
|
|
21
20
|
<body onload="init()">
|
|
@@ -27,27 +26,19 @@
|
|
|
27
26
|
<div id="connectionForm" class="col-sm-6 text-center">
|
|
28
27
|
<label for="url" class="control-label">Server url</label>
|
|
29
28
|
<input class="form-control" id="url" type="text">
|
|
30
|
-
<label for="
|
|
31
|
-
<input class="form-control" id="
|
|
29
|
+
<label for="bitrateTestDuration" class="control-label">Test duration, ms</label>
|
|
30
|
+
<input class="form-control" id="bitrateTestDuration" type="text">
|
|
32
31
|
</div>
|
|
33
32
|
</div>
|
|
34
|
-
<div class="row col-sm-12 justify-content-center" style="margin-top:
|
|
35
|
-
<div class="
|
|
36
|
-
<
|
|
37
|
-
<div
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
<div class="input-group-btn">
|
|
41
|
-
<button id="publishBtn" type="button" style="height: 30px; width: auto;">Connect</button>
|
|
42
|
-
</div>
|
|
43
|
-
<button id="publishBitrateBtn" type="button" style="height: 30px; width: auto;">Check bitrate
|
|
44
|
-
</button>
|
|
45
|
-
<label for="publishBitrateStatus" class="control-label">Bitrate status</label>
|
|
46
|
-
<output id="publishBitrateStatus">
|
|
33
|
+
<div class="row col-sm-12 justify-content-center" style="margin-top: 20px;">
|
|
34
|
+
<div class="text-center" style="margin-top: 20px">
|
|
35
|
+
<button id="bitrateTestBtn" type="button" style="height: 30px; width: auto;">Start</button>
|
|
36
|
+
<div class="text-center" style="margin-top: 20px">
|
|
37
|
+
<div id="bitrateTestStatus"></div>
|
|
38
|
+
<div id="bitrateTestErrorInfo"></div>
|
|
47
39
|
</div>
|
|
48
40
|
<div class="text-center" style="margin-top: 20px">
|
|
49
|
-
<
|
|
50
|
-
<div id="publishErrorInfo"></div>
|
|
41
|
+
<output id="bitrateTestCurrentState">
|
|
51
42
|
</div>
|
|
52
43
|
</div>
|
|
53
44
|
</div>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const constants = SFU.constants;
|
|
2
2
|
const sfu = SFU;
|
|
3
|
-
let
|
|
4
|
-
let publishState;
|
|
3
|
+
let bitrateTestState;
|
|
5
4
|
|
|
6
|
-
const
|
|
5
|
+
const BITRATE_TEST = "bitrateTest";
|
|
6
|
+
const TEST_DURATION = 30000;
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Default publishing config
|
|
@@ -28,81 +28,41 @@ const CurrentState = function (prefix) {
|
|
|
28
28
|
pc: null,
|
|
29
29
|
session: null,
|
|
30
30
|
room: null,
|
|
31
|
-
display: null,
|
|
32
|
-
roomEnded: false,
|
|
33
|
-
starting: false,
|
|
34
31
|
bitrateController: null,
|
|
35
32
|
set: function (pc, session, room) {
|
|
36
33
|
state.pc = pc;
|
|
37
34
|
state.session = session;
|
|
38
35
|
state.room = room;
|
|
39
|
-
state.roomEnded = false;
|
|
40
36
|
},
|
|
41
37
|
clear: function () {
|
|
42
38
|
state.room = null;
|
|
43
39
|
state.session = null;
|
|
44
40
|
state.pc = null;
|
|
45
|
-
state.
|
|
41
|
+
state.bitrateController = null;
|
|
46
42
|
},
|
|
47
|
-
|
|
48
|
-
state.
|
|
43
|
+
durationId: function () {
|
|
44
|
+
return state.prefix + "Duration";
|
|
49
45
|
},
|
|
50
46
|
buttonId: function () {
|
|
51
47
|
return state.prefix + "Btn";
|
|
52
48
|
},
|
|
53
|
-
buttonText: function () {
|
|
54
|
-
return "Connect";
|
|
55
|
-
},
|
|
56
|
-
inputId: function () {
|
|
57
|
-
return state.prefix + "Name";
|
|
58
|
-
},
|
|
59
49
|
statusId: function () {
|
|
60
50
|
return state.prefix + "Status";
|
|
61
51
|
},
|
|
62
|
-
formId: function () {
|
|
63
|
-
return state.prefix + "Form";
|
|
64
|
-
},
|
|
65
52
|
errInfoId: function () {
|
|
66
53
|
return state.prefix + "ErrorInfo";
|
|
67
54
|
},
|
|
68
|
-
|
|
69
|
-
return state.prefix + "
|
|
70
|
-
},
|
|
71
|
-
bitrateStatusId: function () {
|
|
72
|
-
return state.prefix + "BitrateStatus";
|
|
55
|
+
currentStateId: function () {
|
|
56
|
+
return state.prefix + "CurrentState";
|
|
73
57
|
},
|
|
74
58
|
getBitrateController: function () {
|
|
75
|
-
return
|
|
59
|
+
return state.bitrateController;
|
|
76
60
|
},
|
|
77
61
|
setBitrateController: function (controller) {
|
|
78
|
-
|
|
79
|
-
},
|
|
80
|
-
is: function (value) {
|
|
81
|
-
return (prefix === value);
|
|
82
|
-
},
|
|
83
|
-
isActive: function () {
|
|
84
|
-
return (state.room && !state.roomEnded && state.pc);
|
|
62
|
+
state.bitrateController = controller;
|
|
85
63
|
},
|
|
86
64
|
isConnected: function () {
|
|
87
65
|
return (state.session && state.session.state() === constants.SFU_STATE.CONNECTED);
|
|
88
|
-
},
|
|
89
|
-
isRoomEnded: function () {
|
|
90
|
-
return state.roomEnded;
|
|
91
|
-
},
|
|
92
|
-
setStarting: function (value) {
|
|
93
|
-
state.starting = value;
|
|
94
|
-
},
|
|
95
|
-
isStarting: function () {
|
|
96
|
-
return state.starting;
|
|
97
|
-
},
|
|
98
|
-
setDisplay: function (display) {
|
|
99
|
-
state.display = display;
|
|
100
|
-
},
|
|
101
|
-
disposeDisplay: function () {
|
|
102
|
-
if (state.display) {
|
|
103
|
-
state.display.stop();
|
|
104
|
-
state.display = null;
|
|
105
|
-
}
|
|
106
66
|
}
|
|
107
67
|
};
|
|
108
68
|
return state;
|
|
@@ -112,17 +72,12 @@ const CurrentState = function (prefix) {
|
|
|
112
72
|
* load config and set default values
|
|
113
73
|
*/
|
|
114
74
|
const init = function () {
|
|
115
|
-
|
|
75
|
+
bitrateTestState = CurrentState(BITRATE_TEST);
|
|
76
|
+
$("#" + bitrateTestState.buttonId()).prop('disabled', true);
|
|
116
77
|
$("#url").prop('disabled', true);
|
|
117
|
-
|
|
118
|
-
$("#
|
|
119
|
-
$("#
|
|
120
|
-
publishState = CurrentState(PUBLISH);
|
|
121
|
-
mainConfig = defaultConfig;
|
|
122
|
-
onDisconnected(publishState);
|
|
123
|
-
$("#url").val(mainConfig.room.url);
|
|
124
|
-
$("#roomName").val("ROOM1-" + createUUID(4));
|
|
125
|
-
$("#publishName").val("Publisher1-" + createUUID(4));
|
|
78
|
+
onDisconnected(bitrateTestState);
|
|
79
|
+
$("#url").val(setURL());
|
|
80
|
+
$("#" + bitrateTestState.durationId()).val(TEST_DURATION);
|
|
126
81
|
}
|
|
127
82
|
|
|
128
83
|
/**
|
|
@@ -132,13 +87,15 @@ const connect = async function (state) {
|
|
|
132
87
|
//create peer connection
|
|
133
88
|
const pc = new RTCPeerConnection();
|
|
134
89
|
//get config object for room creation
|
|
135
|
-
const roomConfig = getRoomConfig(
|
|
90
|
+
const roomConfig = getRoomConfig(defaultConfig);
|
|
136
91
|
roomConfig.url = $("#url").val();
|
|
137
|
-
roomConfig.roomName =
|
|
138
|
-
roomConfig.nickname = createUUID(
|
|
139
|
-
// clean
|
|
140
|
-
setStatus(state.statusId(), "");
|
|
141
|
-
setStatus(state.errInfoId(), "");
|
|
92
|
+
roomConfig.roomName = "ROOM1-" + createUUID(4);
|
|
93
|
+
roomConfig.nickname = "User1" + createUUID(4);
|
|
94
|
+
// clean status display items
|
|
95
|
+
setStatus(state.statusId(), " ");
|
|
96
|
+
setStatus(state.errInfoId(), " ");
|
|
97
|
+
// clean bitrate display item
|
|
98
|
+
$("#" + state.currentStateId()).val("");
|
|
142
99
|
// connect to server and create a room if not
|
|
143
100
|
try {
|
|
144
101
|
const session = await sfu.createRoom(roomConfig);
|
|
@@ -169,97 +126,78 @@ const connect = async function (state) {
|
|
|
169
126
|
|
|
170
127
|
const onConnected = function (state, pc, session) {
|
|
171
128
|
state.set(pc, session, session.room());
|
|
172
|
-
$("#" + state.buttonId()).text("
|
|
129
|
+
$("#" + state.buttonId()).text("Stop").off('click').click(function () {
|
|
173
130
|
onStopClick(state);
|
|
174
|
-
});
|
|
175
|
-
$("#" + state.bitrateButtonId()).off('click').click(function () {
|
|
176
|
-
onStartBitrateClick(state);
|
|
177
|
-
});
|
|
131
|
+
}).prop('disabled', false);
|
|
178
132
|
|
|
179
133
|
$('#url').prop('disabled', true);
|
|
180
|
-
$("#
|
|
181
|
-
$("#" + state.inputId()).prop('disabled', true);
|
|
134
|
+
$("#" + bitrateTestState.durationId()).prop('disabled', true);
|
|
182
135
|
// Add errors displaying
|
|
183
136
|
state.room.on(constants.SFU_ROOM_EVENT.FAILED, function (e) {
|
|
184
137
|
setStatus(state.errInfoId(), e, "red");
|
|
185
|
-
state.setRoomEnded();
|
|
186
138
|
onStopClick(state);
|
|
187
139
|
}).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
|
|
188
140
|
onOperationFailed(state, e);
|
|
189
141
|
}).on(constants.SFU_ROOM_EVENT.ENDED, function () {
|
|
190
142
|
setStatus(state.errInfoId(), "Room " + state.room.name() + " has ended", "red");
|
|
191
|
-
state.setRoomEnded();
|
|
192
143
|
onStopClick(state);
|
|
193
144
|
}).on(constants.SFU_ROOM_EVENT.DROPPED, function () {
|
|
194
145
|
setStatus(state.errInfoId(), "Dropped from the room " + state.room.name() + " due to network issues", "red");
|
|
195
|
-
state.setRoomEnded();
|
|
196
146
|
onStopClick(state);
|
|
197
147
|
});
|
|
198
|
-
|
|
148
|
+
startBitrateTest(state);
|
|
199
149
|
}
|
|
200
150
|
|
|
201
151
|
const onDisconnected = function (state) {
|
|
202
152
|
state.clear();
|
|
203
|
-
$("#" + state.buttonId()).text(
|
|
153
|
+
$("#" + state.buttonId()).text("Start").off('click').click(function () {
|
|
204
154
|
onStartClick(state);
|
|
205
155
|
}).prop('disabled', false);
|
|
206
156
|
$('#url').prop('disabled', false);
|
|
207
|
-
$("#
|
|
208
|
-
$("#" + state.inputId()).prop('disabled', false);
|
|
209
|
-
$("#" + state.bitrateButtonId()).prop('disabled', true);
|
|
157
|
+
$("#" + bitrateTestState.durationId()).prop('disabled', false);
|
|
210
158
|
}
|
|
211
159
|
|
|
212
160
|
const onStartClick = function (state) {
|
|
213
|
-
if (validateForm("connectionForm", state.errInfoId())
|
|
214
|
-
|
|
215
|
-
state
|
|
216
|
-
if (!state.is(PUBLISH) && Browser().isSafariWebRTC()) {
|
|
217
|
-
playFirstSound(document.getElementById("main"), PRELOADER_URL).then(function () {
|
|
218
|
-
connect(state);
|
|
219
|
-
});
|
|
220
|
-
} else {
|
|
221
|
-
connect(state);
|
|
222
|
-
}
|
|
161
|
+
if (validateForm("connectionForm", state.errInfoId())) {
|
|
162
|
+
$("#" + state.buttonId()).prop('disabled', true);
|
|
163
|
+
connect(state);
|
|
223
164
|
}
|
|
224
165
|
}
|
|
225
166
|
|
|
226
|
-
const
|
|
227
|
-
if (state.
|
|
228
|
-
|
|
229
|
-
state.
|
|
230
|
-
|
|
231
|
-
statusSelector.attr("style", "display:inline-block;margin-left: 10px");
|
|
167
|
+
const startBitrateTest = async function (state) {
|
|
168
|
+
if (state.room) {
|
|
169
|
+
await state.room.join(state.pc, null, {});
|
|
170
|
+
const stateSelector = $("#" + state.currentStateId());
|
|
171
|
+
stateSelector.attr("style", "display:inline-block;margin-left: 10px");
|
|
232
172
|
try {
|
|
233
173
|
const bitrateTest = state.room.getBitrateTest();
|
|
234
174
|
state.setBitrateController(bitrateTest);
|
|
235
175
|
bitrateTest.setListener({
|
|
236
|
-
onStatusUpdate(
|
|
237
|
-
|
|
176
|
+
onStatusUpdate(bitrateKbps) {
|
|
177
|
+
stateSelector.text("Current bitrate: " + bitrateKbps + " kbps");
|
|
238
178
|
}
|
|
239
|
-
})
|
|
240
|
-
bitrateTest.test(
|
|
241
|
-
|
|
179
|
+
});
|
|
180
|
+
bitrateTest.test($("#" + bitrateTestState.durationId()).val()).then((bitrateKbps) => {
|
|
181
|
+
stateSelector.text("Test is finished, last measured bitrate: " + bitrateKbps + " kbps");
|
|
242
182
|
state.setBitrateController(null);
|
|
243
|
-
|
|
244
|
-
onStartBitrateClick(state);
|
|
245
|
-
});
|
|
246
|
-
})
|
|
247
|
-
$("#" + state.bitrateButtonId()).text("Stop test").off('click').click(function () {
|
|
248
|
-
onStopBitrateClick(state);
|
|
183
|
+
onStopClick(state);
|
|
249
184
|
});
|
|
250
185
|
} catch (e) {
|
|
251
|
-
|
|
186
|
+
if (e.type === constants.SFU_ROOM_EVENT.OPERATION_FAILED) {
|
|
187
|
+
onOperationFailed(state, e);
|
|
188
|
+
} else {
|
|
189
|
+
console.error("Failed to start bitrate test: " + e);
|
|
190
|
+
setStatus(state.errInfoId(), e.name, "red");
|
|
191
|
+
onStopClick(state);
|
|
192
|
+
}
|
|
252
193
|
}
|
|
253
|
-
|
|
254
194
|
}
|
|
255
195
|
}
|
|
256
196
|
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
controller.stop();
|
|
262
|
-
}
|
|
197
|
+
const stopBitrateTest = function (state) {
|
|
198
|
+
const controller = state.getBitrateController();
|
|
199
|
+
if (controller) {
|
|
200
|
+
controller.stop();
|
|
263
201
|
}
|
|
264
202
|
}
|
|
265
203
|
|
|
@@ -269,50 +207,17 @@ const onOperationFailed = function (state, event) {
|
|
|
269
207
|
} else {
|
|
270
208
|
setStatus(state.errInfoId(), event, "red");
|
|
271
209
|
}
|
|
272
|
-
state.setRoomEnded();
|
|
273
210
|
onStopClick(state);
|
|
274
211
|
}
|
|
275
212
|
|
|
276
213
|
const onStopClick = async function (state) {
|
|
277
|
-
state.setStarting(false);
|
|
278
|
-
disposeStateDisplay(state);
|
|
279
214
|
if (state.isConnected()) {
|
|
280
|
-
|
|
281
|
-
onStopBitrateClick(state);
|
|
215
|
+
stopBitrateTest(state);
|
|
282
216
|
await state.session.disconnect();
|
|
283
217
|
onDisconnected(state);
|
|
284
218
|
}
|
|
285
219
|
}
|
|
286
220
|
|
|
287
|
-
const startStreaming = async function (state) {
|
|
288
|
-
await publishStreams(state);
|
|
289
|
-
state.setStarting(false);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const publishStreams = async function (state) {
|
|
293
|
-
if (state.isConnected()) {
|
|
294
|
-
try {
|
|
295
|
-
if (state.isConnected() && state.isActive()) {
|
|
296
|
-
await state.room.join(state.pc, null, null);
|
|
297
|
-
$("#" + state.bitrateButtonId()).prop('disabled', false);
|
|
298
|
-
}
|
|
299
|
-
} catch (e) {
|
|
300
|
-
if (e.type === constants.SFU_ROOM_EVENT.OPERATION_FAILED) {
|
|
301
|
-
onOperationFailed(state, e);
|
|
302
|
-
} else {
|
|
303
|
-
console.error("Failed to capture streams: " + e);
|
|
304
|
-
setStatus(state.errInfoId(), e.name, "red");
|
|
305
|
-
onStopClick(state);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const disposeStateDisplay = function (state) {
|
|
313
|
-
state.disposeDisplay();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
221
|
const setStatus = function (status, text, color) {
|
|
317
222
|
const field = document.getElementById(status);
|
|
318
223
|
if (color) {
|