@flashphoner/websdk 2.0.245 → 2.0.247
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/media_devices_manager/manager.js +65 -53
- package/examples/demo/streaming/media_devices_manager/media_device_manager.html +14 -14
- package/examples/demo/streaming/screen-camera-mixer/screen-camera-mixer.html +4 -0
- package/examples/demo/streaming/screen-camera-mixer/screen-camera-mixer.js +70 -2
- package/flashphoner-no-flash.js +627 -143
- package/flashphoner-no-flash.min.js +2 -2
- package/flashphoner-no-webrtc.js +556 -132
- package/flashphoner-no-webrtc.min.js +2 -2
- package/flashphoner-no-wsplayer.js +626 -142
- package/flashphoner-no-wsplayer.min.js +2 -2
- package/flashphoner-room-api.js +390 -27
- package/flashphoner-room-api.min.js +3 -3
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +557 -133
- package/flashphoner-temasys-flash-websocket.js +556 -132
- package/flashphoner-temasys-flash-websocket.min.js +1 -1
- package/flashphoner-webrtc-only.js +623 -139
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +627 -143
- 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/media-source-media-provider.js +3 -3
- package/src/webrtc-media-provider.js +58 -11
package/docTemplate/README.md
CHANGED
|
@@ -433,6 +433,7 @@ function publish() {
|
|
|
433
433
|
stripCodecs: strippedCodecs,
|
|
434
434
|
videoContentHint: contentHint
|
|
435
435
|
}).on(STREAM_STATUS.PUBLISHING, function (stream) {
|
|
436
|
+
publishConnectionQualityStat.connectionQualityUpdateTimestamp = new Date().valueOf();
|
|
436
437
|
$("#testBtn").prop('disabled', true);
|
|
437
438
|
var video = document.getElementById(stream.id());
|
|
438
439
|
//resize local if resolution is available
|
|
@@ -891,33 +892,39 @@ function readyControls() {
|
|
|
891
892
|
function loadPublishStats() {
|
|
892
893
|
if (publishStream) {
|
|
893
894
|
publishStream.getStats(function (stats) {
|
|
894
|
-
if (stats
|
|
895
|
-
if (stats.outboundStream
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
895
|
+
if (stats) {
|
|
896
|
+
if (stats.outboundStream) {
|
|
897
|
+
if (stats.outboundStream.video) {
|
|
898
|
+
showStat(stats.outboundStream.video, "outVideoStat");
|
|
899
|
+
let vBitrate = (stats.outboundStream.video.bytesSent - videoBytesSent) * 8;
|
|
900
|
+
if ($('#outVideoStatBitrate').length == 0) {
|
|
901
|
+
let html = "<div>Bitrate: " + "<span id='outVideoStatBitrate' style='font-weight: normal'>" + vBitrate + "</span>" + "</div>";
|
|
902
|
+
$("#outVideoStat").append(html);
|
|
903
|
+
} else {
|
|
904
|
+
$('#outVideoStatBitrate').text(vBitrate);
|
|
905
|
+
}
|
|
906
|
+
videoBytesSent = stats.outboundStream.video.bytesSent;
|
|
905
907
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
+
if(new Date().valueOf() - CONNECTION_QUALITY_UPDATE_TIMEOUT_MS > publishConnectionQualityStat.connectionQualityUpdateTimestamp) {
|
|
909
|
+
publishConnectionQualityStat.quality = CONNECTION_QUALITY.UNKNOWN;
|
|
910
|
+
}
|
|
908
911
|
}
|
|
909
|
-
}
|
|
910
912
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
913
|
+
if (stats.outboundStream.audio) {
|
|
914
|
+
showStat(stats.outboundStream.audio, "outAudioStat");
|
|
915
|
+
let aBitrate = (stats.outboundStream.audio.bytesSent - audioBytesSent) * 8;
|
|
916
|
+
if ($('#outAudioStatBitrate').length == 0) {
|
|
917
|
+
let html = "<div>Bitrate: " + "<span id='outAudioStatBitrate' style='font-weight: normal'>" + aBitrate + "</span>" + "</div>";
|
|
918
|
+
$("#outAudioStat").append(html);
|
|
919
|
+
} else {
|
|
920
|
+
$('#outAudioStatBitrate').text(aBitrate);
|
|
921
|
+
}
|
|
922
|
+
audioBytesSent = stats.outboundStream.audio.bytesSent;
|
|
919
923
|
}
|
|
920
|
-
|
|
924
|
+
|
|
925
|
+
}
|
|
926
|
+
if (stats.otherStats) {
|
|
927
|
+
showStat(stats.otherStats, "outConnectionStat");
|
|
921
928
|
}
|
|
922
929
|
}
|
|
923
930
|
if (publishConnectionQualityStat.quality !== undefined) {
|
|
@@ -931,47 +938,52 @@ function loadPublishStats() {
|
|
|
931
938
|
function loadPlayStats() {
|
|
932
939
|
if (previewStream) {
|
|
933
940
|
previewStream.getStats(function (stats) {
|
|
934
|
-
if (stats
|
|
935
|
-
if (stats.inboundStream
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
941
|
+
if (stats) {
|
|
942
|
+
if (stats.inboundStream) {
|
|
943
|
+
if (stats.inboundStream.video) {
|
|
944
|
+
showStat(stats.inboundStream.video, "inVideoStat");
|
|
945
|
+
let vBitrate = (stats.inboundStream.video.bytesReceived - videoBytesReceived) * 8;
|
|
946
|
+
if ($('#inVideoStatBitrate').length == 0) {
|
|
947
|
+
let html = "<div>Bitrate: " + "<span id='inVideoStatBitrate' style='font-weight: normal'>" + vBitrate + "</span>" + "</div>";
|
|
948
|
+
$("#inVideoStat").append(html);
|
|
949
|
+
} else {
|
|
950
|
+
$('#inVideoStatBitrate').text(vBitrate);
|
|
951
|
+
}
|
|
952
|
+
videoBytesReceived = stats.inboundStream.video.bytesReceived;
|
|
945
953
|
|
|
946
|
-
|
|
947
|
-
|
|
954
|
+
if (new Date().valueOf() - CONNECTION_QUALITY_UPDATE_TIMEOUT_MS > playConnectionQualityStat.connectionQualityUpdateTimestamp) {
|
|
955
|
+
playConnectionQualityStat.quality = CONNECTION_QUALITY.UNKNOWN;
|
|
956
|
+
}
|
|
948
957
|
}
|
|
949
|
-
}
|
|
950
958
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
959
|
+
if (stats.inboundStream.audio) {
|
|
960
|
+
if (stats.inboundStream.audio.audioLevel) {
|
|
961
|
+
// Round audio level to 6 decimal places
|
|
962
|
+
stats.inboundStream.audio.audioLevel = stats.inboundStream.audio.audioLevel.toFixed(6);
|
|
963
|
+
}
|
|
964
|
+
showStat(stats.inboundStream.audio, "inAudioStat");
|
|
965
|
+
let aBitrate = (stats.inboundStream.audio.bytesReceived - audioBytesReceived) * 8;
|
|
966
|
+
if ($('#inAudioStatBitrate').length == 0) {
|
|
967
|
+
let html = "<div style='font-weight: bold'>Bitrate: " + "<span id='inAudioStatBitrate' style='font-weight: normal'>" + aBitrate + "</span>" + "</div>";
|
|
968
|
+
$("#inAudioStat").append(html);
|
|
969
|
+
} else {
|
|
970
|
+
$('#inAudioStatBitrate').text(aBitrate);
|
|
971
|
+
}
|
|
972
|
+
audioBytesReceived = stats.inboundStream.audio.bytesReceived;
|
|
963
973
|
}
|
|
964
|
-
audioBytesReceived = stats.inboundStream.audio.bytesReceived;
|
|
965
974
|
}
|
|
966
|
-
if (
|
|
967
|
-
showStat(
|
|
975
|
+
if (stats.otherStats) {
|
|
976
|
+
showStat(stats.otherStats, "inConnectionStat");
|
|
968
977
|
}
|
|
969
978
|
}
|
|
979
|
+
if (playConnectionQualityStat.quality !== undefined) {
|
|
980
|
+
showStat({"quality": playConnectionQualityStat.quality}, "inConnectionStat");
|
|
981
|
+
}
|
|
970
982
|
});
|
|
971
983
|
}
|
|
972
984
|
}
|
|
973
985
|
|
|
974
|
-
// Helper
|
|
986
|
+
// Helper function to display stats
|
|
975
987
|
function showStat(stat, type) {
|
|
976
988
|
Object.keys(stat).forEach(function(key) {
|
|
977
989
|
if (typeof stat[key] !== 'object') {
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
</div>
|
|
30
30
|
<div class="row">
|
|
31
31
|
<h2 id="notifyFlash" class="text-danger"></h2>
|
|
32
|
-
<div class="col-sm-2"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
<div class="col-sm-2">
|
|
33
|
+
<label id="outVideoStat">Video stats</label>
|
|
34
|
+
<div></div>
|
|
35
|
+
<label id="outAudioStat">Audio stats</label>
|
|
36
|
+
<div></div>
|
|
37
|
+
<label id="outConnectionStat">Connection</label>
|
|
38
38
|
</div>
|
|
39
39
|
<div class="col-sm-4">
|
|
40
40
|
<div class="text-center text-muted">Local</div>
|
|
@@ -68,16 +68,16 @@
|
|
|
68
68
|
<div id="playStatus"></div>
|
|
69
69
|
</div>
|
|
70
70
|
</div>
|
|
71
|
-
<div class="col-sm-2"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
<div class="col-sm-2">
|
|
72
|
+
<label id="inVideoStat">Video stats</label>
|
|
73
|
+
<div></div>
|
|
74
|
+
<label id="inAudioStat">Audio stats</label>
|
|
75
|
+
<div></div>
|
|
76
|
+
<label id="inConnectionStat">Connection</label>
|
|
77
77
|
</div>
|
|
78
78
|
</div>
|
|
79
79
|
<div class="row row-space">
|
|
80
|
-
<div class="col-sm-4 col-sm-offset-
|
|
80
|
+
<div class="col-sm-4 col-sm-offset-4">
|
|
81
81
|
<div id="connectionForm" class="input-group form-group">
|
|
82
82
|
<input class="form-control" id="urlServer" type="text">
|
|
83
83
|
<div class="input-group-btn">
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
</div>
|
|
99
99
|
<div class="row">
|
|
100
100
|
<form id="form" class="form-horizontal" role="form" style="margin-top: 10px; margin-left: 10px">
|
|
101
|
-
<div class="col-sm-4 col-sm-offset-
|
|
101
|
+
<div class="col-sm-4 col-sm-offset-2">
|
|
102
102
|
<div class="form-group" id="sendAudioGroup">
|
|
103
103
|
<div class="form-group">
|
|
104
104
|
<label class="col-sm-2 control-label"></label>
|
|
@@ -82,6 +82,8 @@
|
|
|
82
82
|
<div id="screenName"></div>
|
|
83
83
|
<div id="screenStatus"></div>
|
|
84
84
|
<div id="screenInfo"></div>
|
|
85
|
+
<div id="screenBitrate"></div>
|
|
86
|
+
<div id="screenAvailableBitrate"></div>
|
|
85
87
|
</div>
|
|
86
88
|
</div>
|
|
87
89
|
<div class="col-sm-6 text-center">
|
|
@@ -93,6 +95,8 @@
|
|
|
93
95
|
<div id="cameraName"></div>
|
|
94
96
|
<div id="cameraStatus"></div>
|
|
95
97
|
<div id="cameraInfo"></div>
|
|
98
|
+
<div id="cameraBitrate"></div>
|
|
99
|
+
<div id="cameraAvailableBitrate"></div>
|
|
96
100
|
</div>
|
|
97
101
|
</div>
|
|
98
102
|
<div class="row row-space text-center" style="margin-top: 20px">
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
|
|
2
2
|
const STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
|
|
3
3
|
const Browser = Flashphoner.Browser;
|
|
4
|
+
const STAT_INTERVAL = 1000;
|
|
4
5
|
let localVideoScreen;
|
|
5
6
|
let localVideoCamera;
|
|
7
|
+
let screenStats;
|
|
8
|
+
let cameraStats;
|
|
6
9
|
|
|
7
10
|
const init_page = function() {
|
|
8
11
|
//init api
|
|
@@ -61,6 +64,12 @@ const onStarted = function(cameraStream) {
|
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
const onStopped = function(session) {
|
|
67
|
+
if (cameraStats) {
|
|
68
|
+
cameraStats.stop();
|
|
69
|
+
}
|
|
70
|
+
if (screenStats) {
|
|
71
|
+
screenStats.stop();
|
|
72
|
+
}
|
|
64
73
|
setPublishButton("Start", session, null);
|
|
65
74
|
$("#connectBtn").prop('disabled', false);
|
|
66
75
|
}
|
|
@@ -152,6 +161,7 @@ const startStreamingScreen = function(session) {
|
|
|
152
161
|
resizeVideo(event.target);
|
|
153
162
|
});
|
|
154
163
|
setStatus("screen", STREAM_STATUS.PUBLISHING, screenStream);
|
|
164
|
+
screenStats = StreamStats("screen", screenStream, STAT_INTERVAL);
|
|
155
165
|
startStreamingCamera(session, screenStream);
|
|
156
166
|
}).on(STREAM_STATUS.UNPUBLISHED, function() {
|
|
157
167
|
setStatus("screen", STREAM_STATUS.UNPUBLISHED);
|
|
@@ -175,6 +185,7 @@ const startStreamingCamera = function(session, screenStream) {
|
|
|
175
185
|
resizeVideo(event.target);
|
|
176
186
|
});
|
|
177
187
|
setStatus("camera", STREAM_STATUS.PUBLISHING, cameraStream);
|
|
188
|
+
cameraStats = StreamStats("camera", cameraStream, STAT_INTERVAL);
|
|
178
189
|
onStarted(cameraStream);
|
|
179
190
|
}).on(STREAM_STATUS.UNPUBLISHED, function() {
|
|
180
191
|
setStatus("camera", STREAM_STATUS.UNPUBLISHED);
|
|
@@ -188,7 +199,6 @@ const startStreamingCamera = function(session, screenStream) {
|
|
|
188
199
|
}).publish();
|
|
189
200
|
}
|
|
190
201
|
|
|
191
|
-
//show connection or local stream status
|
|
192
202
|
const setStatus = function(type, status, stream) {
|
|
193
203
|
let nameField = $("#"+type+"Name");
|
|
194
204
|
let statusField = $("#"+type+"Status");
|
|
@@ -211,6 +221,24 @@ const setStatus = function(type, status, stream) {
|
|
|
211
221
|
}
|
|
212
222
|
}
|
|
213
223
|
|
|
224
|
+
const setBitrate = function(type, bitrate) {
|
|
225
|
+
let bitrateField = $("#" + type + "Bitrate");
|
|
226
|
+
let text = bitrate;
|
|
227
|
+
if (bitrate !== "") {
|
|
228
|
+
text = "Bitrate: " + bitrate;
|
|
229
|
+
}
|
|
230
|
+
bitrateField.text(text);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const setAvailableBitrate = function(type, bitrate) {
|
|
234
|
+
let bitrateField = $("#" + type + "AvailableBitrate");
|
|
235
|
+
let text = bitrate;
|
|
236
|
+
if (bitrate !== "") {
|
|
237
|
+
text = "Available bitrate: " + bitrate;
|
|
238
|
+
}
|
|
239
|
+
bitrateField.text(text);
|
|
240
|
+
}
|
|
241
|
+
|
|
214
242
|
const muteInputs = function() {
|
|
215
243
|
$(":input").each(function() {
|
|
216
244
|
$(this).prop('disabled',true);
|
|
@@ -250,7 +278,7 @@ const removeHighlight = function(input) {
|
|
|
250
278
|
input.closest('.form-group').removeClass("has-error");
|
|
251
279
|
}
|
|
252
280
|
|
|
253
|
-
|
|
281
|
+
const getStreamName = function(type, url) {
|
|
254
282
|
let streamName = url.endsWith('/') === false ? url.split('/')[3] : "";
|
|
255
283
|
if (streamName) {
|
|
256
284
|
streamName += "-" + type;
|
|
@@ -262,4 +290,44 @@ function getStreamName(type, url) {
|
|
|
262
290
|
}
|
|
263
291
|
}
|
|
264
292
|
return streamName;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const StreamStats = function(type, stream, interval) {
|
|
296
|
+
const streamStats = {
|
|
297
|
+
type: type,
|
|
298
|
+
timer: null,
|
|
299
|
+
stream: stream,
|
|
300
|
+
bytesSent: 0,
|
|
301
|
+
start: function(interval) {
|
|
302
|
+
if (!streamStats.timer) {
|
|
303
|
+
streamStats.timer = setInterval(streamStats.displayStats, interval);
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
stop: function() {
|
|
307
|
+
if (streamStats.timer) {
|
|
308
|
+
clearInterval(streamStats.timer);
|
|
309
|
+
streamStats.timer = null;
|
|
310
|
+
}
|
|
311
|
+
setBitrate(streamStats.type, "");
|
|
312
|
+
setAvailableBitrate(streamStats.type, "");
|
|
313
|
+
},
|
|
314
|
+
displayStats: function() {
|
|
315
|
+
if (streamStats.stream) {
|
|
316
|
+
streamStats.stream.getStats((stats) => {
|
|
317
|
+
if (stats) {
|
|
318
|
+
if (stats.outboundStream && stats.outboundStream.video) {
|
|
319
|
+
let vBitrate = (stats.outboundStream.video.bytesSent - streamStats.bytesSent) * 8;
|
|
320
|
+
setBitrate(streamStats.type, vBitrate);
|
|
321
|
+
streamStats.bytesSent = stats.outboundStream.video.bytesSent;
|
|
322
|
+
}
|
|
323
|
+
if (stats.otherStats && stats.otherStats.availableOutgoingBitrate !== undefined) {
|
|
324
|
+
setAvailableBitrate(streamStats.type, stats.otherStats.availableOutgoingBitrate);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
streamStats.start(interval);
|
|
332
|
+
return streamStats;
|
|
265
333
|
}
|