@flashphoner/websdk 2.0.219 → 2.0.223
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/Gruntfile.js +30 -1
- package/docTemplate/README.md +1 -1
- package/examples/demo/streaming/console/console.html +149 -1
- package/examples/demo/streaming/console/console.js +282 -2
- package/examples/demo/streaming/console/jquery.dataTables.css +604 -0
- package/examples/demo/streaming/console/jquery.dataTables.js +15562 -0
- package/examples/demo/streaming/media_devices_manager/manager.js +49 -30
- package/flashphoner-no-flash.js +22 -7
- package/flashphoner-no-flash.min.js +2 -2
- package/flashphoner-no-webrtc.js +4158 -5643
- package/flashphoner-no-webrtc.min.js +2 -2
- package/flashphoner-no-wsplayer.js +4038 -5514
- package/flashphoner-no-wsplayer.min.js +2 -2
- package/flashphoner-rest-api.js +9 -1
- package/flashphoner-room-api.js +56 -658
- package/flashphoner-room-api.min.js +2 -2
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +4148 -5633
- package/flashphoner-temasys-flash-websocket.js +4148 -5633
- package/flashphoner-temasys-flash-websocket.min.js +1 -1
- package/flashphoner-webrtc-only.js +22 -7
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +4162 -5638
- package/flashphoner.min.js +2 -2
- package/package.json +1 -1
- package/src/flashphoner-core.js +2 -1
- package/src/rest-module.js +9 -1
- package/src/util.js +5 -1
- package/src/webrtc-media-provider.js +8 -1
package/Gruntfile.js
CHANGED
|
@@ -14,7 +14,33 @@ module.exports = function(grunt) {
|
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
enable_flash: {
|
|
19
|
+
files: {
|
|
20
|
+
'src/flashphoner-core.js': 'src/flashphoner-core.js'
|
|
21
|
+
},
|
|
22
|
+
options: {
|
|
23
|
+
replacements: [
|
|
24
|
+
{
|
|
25
|
+
pattern: /var flashProvider = null;/,
|
|
26
|
+
replacement: 'var flashProvider = require(\"./flash-media-provider\");'
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
disable_flash: {
|
|
32
|
+
files: {
|
|
33
|
+
'src/flashphoner-core.js': 'src/flashphoner-core.js'
|
|
34
|
+
},
|
|
35
|
+
options: {
|
|
36
|
+
replacements: [
|
|
37
|
+
{
|
|
38
|
+
pattern: /require\(\"\.\/flash-media-provider\"\);/,
|
|
39
|
+
replacement: 'null;'
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
18
44
|
},
|
|
19
45
|
flash: {
|
|
20
46
|
options: {
|
|
@@ -243,6 +269,7 @@ module.exports = function(grunt) {
|
|
|
243
269
|
grunt.registerTask('build', [
|
|
244
270
|
'clean:build',
|
|
245
271
|
'string-replace:version',
|
|
272
|
+
'string-replace:disable_flash',
|
|
246
273
|
'browserify',
|
|
247
274
|
'concat',
|
|
248
275
|
'minify',
|
|
@@ -257,6 +284,7 @@ module.exports = function(grunt) {
|
|
|
257
284
|
'clean:release',
|
|
258
285
|
'clean:build',
|
|
259
286
|
'string-replace:version',
|
|
287
|
+
'string-replace:disable_flash',
|
|
260
288
|
'browserify:flashphonerGlobalObjectWebRTCOnly',
|
|
261
289
|
'browserify:flashphonerGlobalObjectRestApi',
|
|
262
290
|
'browserify:flashphonerGlobalObjectRoomApi',
|
|
@@ -268,6 +296,7 @@ module.exports = function(grunt) {
|
|
|
268
296
|
'clean:release',
|
|
269
297
|
'clean:build',
|
|
270
298
|
'string-replace:version',
|
|
299
|
+
'string-replace:enable_flash',
|
|
271
300
|
'flash:release_media_provider',
|
|
272
301
|
'browserify',
|
|
273
302
|
'concat',
|
package/docTemplate/README.md
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
<link rel="stylesheet" href="../../dependencies/bootstrap/css/bootstrap.css">
|
|
7
7
|
<link rel="stylesheet" href="../../dependencies/bootstrap/font-awesome/css/font-awesome.min.css">
|
|
8
8
|
<link rel="stylesheet" href="console.css">
|
|
9
|
+
<link rel="stylesheet" type="text/css" href="jquery.dataTables.css">
|
|
9
10
|
<title>Console</title>
|
|
10
11
|
<script type="text/javascript" src="../../dependencies/jquery/jquery-1.12.0.js"></script>
|
|
11
12
|
<script type="text/javascript" src="../../dependencies/jquery/jquery-ui.js"></script>
|
|
12
13
|
<script type="text/javascript" src="../../dependencies/bootstrap/js/bootstrap.min.js"></script>
|
|
13
14
|
<script type="text/javascript" src="../../dependencies/js/utils.js"></script>
|
|
14
15
|
<script type="text/javascript" src="../../../../flashphoner-rest-api.js"></script>
|
|
16
|
+
<script type="text/javascript" charset="utf8" src="jquery.dataTables.js"></script>
|
|
15
17
|
<script type="text/javascript" src="console.js"></script>
|
|
16
18
|
</head>
|
|
17
19
|
<body>
|
|
@@ -19,7 +21,7 @@
|
|
|
19
21
|
<div class="row vdivide" id="controls">
|
|
20
22
|
<div class="col-sm-4">
|
|
21
23
|
<div id="addNodeForm" class="input-group">
|
|
22
|
-
<input class="form-control" type="text" id="nodeIp"
|
|
24
|
+
<input class="form-control" type="text" id="nodeIp" placeholder="Node ip/domain name">
|
|
23
25
|
<span class="input-group-btn">
|
|
24
26
|
<button id="addNodeFormSubmit" type="button" class="btn btn-primary">Add node</button>
|
|
25
27
|
</span>
|
|
@@ -59,6 +61,8 @@
|
|
|
59
61
|
<button id="callStressBatchModalBtn" data-toggle='modal' data-target='#callStressBatchModal' type="button" class="btn btn-default btn-success btn-block">Stress Call</button>
|
|
60
62
|
<button id="streamStressBatchModalBtn" data-toggle='modal' data-target='#streamStressBatchModal' type="button" class="btn btn-default btn-success btn-block">Stress Play Stream</button>
|
|
61
63
|
<button id="streamPublishStressBatchModalBtn" data-toggle='modal' data-target='#streamPublishStressBatchModal' type="button" class="btn btn-default btn-success btn-block">Stress Publish Stream</button>
|
|
64
|
+
<hr>
|
|
65
|
+
<button id="metricsModalBtn" data-toggle='modal' data-target='#streamMetricsModal' type="button" class="btn btn-default btn-success btn-block">Monitoring</button>
|
|
62
66
|
</div>
|
|
63
67
|
<div class="col-sm-9">
|
|
64
68
|
<form class="form-inline" action="">
|
|
@@ -560,6 +564,150 @@
|
|
|
560
564
|
</div>
|
|
561
565
|
</div>
|
|
562
566
|
</div>
|
|
567
|
+
<div id="streamMetricsModal" class="modal fade" role="dialog">
|
|
568
|
+
<div class="modal-dialog" style="width: 1250px">
|
|
569
|
+
<div class="modal-content">
|
|
570
|
+
<div class="modal-header">
|
|
571
|
+
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
572
|
+
<h4>Stream monitoring</h4>
|
|
573
|
+
</div>
|
|
574
|
+
<div class="modal-body">
|
|
575
|
+
<form action="" id="streamMonitoringForm">
|
|
576
|
+
<div class="form-group">
|
|
577
|
+
<label for="mediaTypeFilter">Stream type</label>
|
|
578
|
+
<select name="mediaTypeFilter" id="mediaTypeFilter">
|
|
579
|
+
<option value="all" selected>All</option>
|
|
580
|
+
<option value="publish">Publish</option>
|
|
581
|
+
<option value="play">Play</option>
|
|
582
|
+
</select>
|
|
583
|
+
</div>
|
|
584
|
+
<div class="form-group">
|
|
585
|
+
<label for="allStreams"></label>
|
|
586
|
+
<input type="checkbox" id="allStreams" value="true" checked> All streams
|
|
587
|
+
</div>
|
|
588
|
+
<div class="form-group">
|
|
589
|
+
<label for="monitoredStreamName"><span class="glyphicon glyphicon-play-circle"></span> Stream name</label>
|
|
590
|
+
<input type="text" class="form-control" id="monitoredStreamName" placeholder="Stream name" disabled >
|
|
591
|
+
</div>
|
|
592
|
+
<!-- <div class="form-group">-->
|
|
593
|
+
<!-- <label for="monitoringPollInterval"><span class="glyphicon glyphicon-play-circle"></span> Poll interval</label>-->
|
|
594
|
+
<!-- <input type="text" class="form-control" id="monitoringPollInterval" value="1000" placeholder="Polling interval (ms)">-->
|
|
595
|
+
<!-- </div>-->
|
|
596
|
+
<div class="form-group">
|
|
597
|
+
<label for="mediaProviderFilter">Media provider</label>
|
|
598
|
+
<select name="mediaProviderFilter" id="mediaProviderFilter">
|
|
599
|
+
<option value="all" selected>All</option>
|
|
600
|
+
<option value="WebRTC">WebRTC</option>
|
|
601
|
+
<option value="Flash">RTMP</option>
|
|
602
|
+
</select>
|
|
603
|
+
</div>
|
|
604
|
+
<div class="form-group">
|
|
605
|
+
<label for="streamTypeThresholdFilter">Apply filters to</label>
|
|
606
|
+
<select name="streamTypeThresholdFilter" id="streamTypeThresholdFilter">
|
|
607
|
+
<option value="all" selected>All</option>
|
|
608
|
+
<option value="publish">Published</option>
|
|
609
|
+
<option value="play">Playing</option>
|
|
610
|
+
</select>
|
|
611
|
+
</div>
|
|
612
|
+
<div class="panel panel-default">
|
|
613
|
+
<div class="panel-heading">Metric thresholds</div>
|
|
614
|
+
<table class="table">
|
|
615
|
+
<thead>
|
|
616
|
+
<tr>
|
|
617
|
+
<th>VIDEO_RATE</th>
|
|
618
|
+
<th>VIDEO_FPS</th>
|
|
619
|
+
<th>VIDEO_NACK</th>
|
|
620
|
+
<th>VIDEO_B_FRAMES</th>
|
|
621
|
+
</tr>
|
|
622
|
+
</thead>
|
|
623
|
+
<tbody>
|
|
624
|
+
<tr>
|
|
625
|
+
<td>
|
|
626
|
+
<input id="videoRateThreshold" type="text" class="text" value="0">
|
|
627
|
+
<select id="videoRateThresholdFilter">
|
|
628
|
+
<option value="eq">Equal</option>
|
|
629
|
+
<option selected value="gt">Greater than</option>
|
|
630
|
+
<option value="goe">Greater or equal</option>
|
|
631
|
+
<option value="lt">Lower than</option>
|
|
632
|
+
<option value="loe">Lower or equal</option>
|
|
633
|
+
</select>
|
|
634
|
+
</td>
|
|
635
|
+
<td>
|
|
636
|
+
<input id="videoFpsThreshold" type="text" class="text" value="0">
|
|
637
|
+
<select id="videoFpsThresholdFilter">
|
|
638
|
+
<option value="eq">Equal</option>
|
|
639
|
+
<option selected value="gt">Greater than</option>
|
|
640
|
+
<option value="goe">Greater or equal</option>
|
|
641
|
+
<option value="lt">Lower than</option>
|
|
642
|
+
<option value="loe">Lower or equal</option>
|
|
643
|
+
</select>
|
|
644
|
+
</td>
|
|
645
|
+
<td>
|
|
646
|
+
<input id="videoNackThreshold" type="text" class="text" value="0">
|
|
647
|
+
<select id="videoNackThresholdFilter">
|
|
648
|
+
<option selected value="eq">Equal</option>
|
|
649
|
+
<option value="gt">Greater than</option>
|
|
650
|
+
<option value="goe">Greater or equal</option>
|
|
651
|
+
<option value="lt">Lower than</option>
|
|
652
|
+
<option value="loe">Lower or equal</option>
|
|
653
|
+
</select>
|
|
654
|
+
</td>
|
|
655
|
+
<td>
|
|
656
|
+
<input id="videoBFramesThreshold" type="text" class="text" value="0">
|
|
657
|
+
<select id="videoBFramesThresholdFilter">
|
|
658
|
+
<option selected value="eq">Equal</option>
|
|
659
|
+
<option value="gt">Greater than</option>
|
|
660
|
+
<option value="goe">Greater or equal</option>
|
|
661
|
+
<option value="lt">Lower than</option>
|
|
662
|
+
<option value="loe">Lower or equal</option>
|
|
663
|
+
</select>
|
|
664
|
+
</td>
|
|
665
|
+
</tr>
|
|
666
|
+
</tbody>
|
|
667
|
+
</table>
|
|
668
|
+
</div>
|
|
669
|
+
|
|
670
|
+
<button id="streamMonitoring" type="button" class="btn btn-default btn-success btn-block"><span class="glyphicon glyphicon-off"></span> Start</button>
|
|
671
|
+
</form>
|
|
672
|
+
</div>
|
|
673
|
+
<div class="modal-footer">
|
|
674
|
+
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Cancel</button>
|
|
675
|
+
</div>
|
|
676
|
+
</div>
|
|
677
|
+
</div>
|
|
678
|
+
</div>
|
|
679
|
+
<div id="streamMetricsDetailsModal" class="modal fade" role="dialog">
|
|
680
|
+
<div class="modal-dialog" style="width: 100%">
|
|
681
|
+
<div class="modal-content">
|
|
682
|
+
<div class="modal-header">
|
|
683
|
+
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
684
|
+
<h4>Stream metrics details</h4>
|
|
685
|
+
</div>
|
|
686
|
+
<div class="modal-body">
|
|
687
|
+
<table id="metricsTable" class="metricsTable" width="100%">
|
|
688
|
+
<thead>
|
|
689
|
+
<tr>
|
|
690
|
+
<th></th>
|
|
691
|
+
<th>Name</th>
|
|
692
|
+
<th>Type</th>
|
|
693
|
+
<th>WIDTH</th>
|
|
694
|
+
<th>HEIGHT</th>
|
|
695
|
+
<th>V_RATE</th>
|
|
696
|
+
<th>NACK</th>
|
|
697
|
+
<th>B_FRAMES</th>
|
|
698
|
+
<th>V_LOST</th>
|
|
699
|
+
<th>FPS</th>
|
|
700
|
+
</tr>
|
|
701
|
+
</thead>
|
|
702
|
+
</table>
|
|
703
|
+
</div>
|
|
704
|
+
<div class="modal-footer">
|
|
705
|
+
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Cancel</button>
|
|
706
|
+
<button type="button" class="btn btn-default pull-right" id="refreshMetricsBtn"><span class="glyphicon glyphicon-refresh"></span> Refresh</button>
|
|
707
|
+
</div>
|
|
708
|
+
</div>
|
|
709
|
+
</div>
|
|
710
|
+
</div>
|
|
563
711
|
<div id="warningModal" class="modal fade" role="dialog">
|
|
564
712
|
<div class="modal-dialog">
|
|
565
713
|
<div class="modal-content">
|
|
@@ -112,6 +112,25 @@ $(function() {
|
|
|
112
112
|
$("#streamPublishStressBatch").on("click", function(e){
|
|
113
113
|
streamPublishStressTest();
|
|
114
114
|
});
|
|
115
|
+
$("#streamMonitoring").on("click", function(e){
|
|
116
|
+
streamMonitoring();
|
|
117
|
+
});
|
|
118
|
+
$('#streamMetricsModal').on('show.bs.modal', function(e) {
|
|
119
|
+
populateNodes($("#streamMonitoringNodes"));
|
|
120
|
+
});
|
|
121
|
+
$("#allStreams").on("click", function(e){
|
|
122
|
+
$("#monitoredStreamName").prop('disabled', $('#allStreams').is(':checked'));
|
|
123
|
+
})
|
|
124
|
+
$('#streamMetricsDetailsModal').on('hidden.bs.modal', function(e) {
|
|
125
|
+
$('#refreshMetricsBtn').off('click');
|
|
126
|
+
if ( $.fn.dataTable.isDataTable('#metricsTable') ) {
|
|
127
|
+
console.log("Destroy data table");
|
|
128
|
+
const table = $('#metricsTable').DataTable();
|
|
129
|
+
$('#metricsTable tbody').off('click', 'td.dt-control');
|
|
130
|
+
table.destroy();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
115
134
|
|
|
116
135
|
$("#generalInfoTable").sortable();
|
|
117
136
|
$("#streamStressMode").change(function() {
|
|
@@ -126,9 +145,16 @@ $(function() {
|
|
|
126
145
|
});
|
|
127
146
|
|
|
128
147
|
function createNode(id, ip) {
|
|
129
|
-
|
|
148
|
+
let nodeIp = ip;
|
|
149
|
+
let port = 8081;
|
|
150
|
+
if (ip.indexOf(':') !== -1) {
|
|
151
|
+
port = ip.substring(ip.indexOf(":") + 1);
|
|
152
|
+
nodeIp = ip.substring(0, ip.indexOf(":"));
|
|
153
|
+
}
|
|
154
|
+
var api = FlashphonerRestApi.instance("http://"+nodeIp+":"+port, "http://"+nodeIp+":"+port);
|
|
130
155
|
api.id = id;
|
|
131
|
-
api.ip =
|
|
156
|
+
api.ip = nodeIp;
|
|
157
|
+
api.port = port;
|
|
132
158
|
api.tests = [];
|
|
133
159
|
var state = NODE_STATE.NEW;
|
|
134
160
|
var pollState = function(){
|
|
@@ -242,11 +268,19 @@ function createNode(id, ip) {
|
|
|
242
268
|
break;
|
|
243
269
|
}
|
|
244
270
|
};
|
|
271
|
+
api.getTranscodingGroupStat = async function() {
|
|
272
|
+
const result = await fetch("http://" + nodeIp + ":" + port + "/?action=stat&format=json&groups=transcoding_stats")
|
|
273
|
+
const json = await result.json();
|
|
274
|
+
return json;
|
|
275
|
+
}
|
|
245
276
|
return api;
|
|
246
277
|
}
|
|
247
278
|
|
|
248
279
|
function addNode(ip) {
|
|
249
280
|
var id = ip.replace(/\./g, "");
|
|
281
|
+
if (ip.indexOf(':') !== -1) {
|
|
282
|
+
id = ip.substring(ip.indexOf(":") + 1).replace(/\./g, "");
|
|
283
|
+
}
|
|
250
284
|
if (nodes[id]) {
|
|
251
285
|
return;
|
|
252
286
|
}
|
|
@@ -1037,6 +1071,252 @@ function streamPlayStressTest() {
|
|
|
1037
1071
|
$("#streamStressBatchModal").modal('hide');
|
|
1038
1072
|
}
|
|
1039
1073
|
|
|
1074
|
+
async function streamMonitoring() {
|
|
1075
|
+
|
|
1076
|
+
const node = getActiveNode();
|
|
1077
|
+
const mediaTypeFilter = $('#mediaTypeFilter option:selected').val();
|
|
1078
|
+
const mediaProviderFilter = $('#mediaProviderFilter option:selected').val();
|
|
1079
|
+
const streamTypeThresholdFilter = $('#streamTypeThresholdFilter option:selected').val();
|
|
1080
|
+
const isAllStreams = $('#allStreams').is(':checked');
|
|
1081
|
+
const streamName = $('#monitoredStreamName').val();
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
// Metric thresholds
|
|
1085
|
+
const thresholds = {
|
|
1086
|
+
VIDEO_RATE: {
|
|
1087
|
+
value: parseInt($('#videoRateThreshold').val()),
|
|
1088
|
+
filter: $('#videoRateThresholdFilter option:selected').val()
|
|
1089
|
+
},
|
|
1090
|
+
VIDEO_FPS: {
|
|
1091
|
+
value: parseInt($('#videoFpsThreshold').val()),
|
|
1092
|
+
filter: $('#videoFpsThresholdFilter option:selected').val(),
|
|
1093
|
+
},
|
|
1094
|
+
VIDEO_NACK: {
|
|
1095
|
+
value: parseInt($('#videoNackThreshold').val()),
|
|
1096
|
+
filter: $('#videoNackThresholdFilter option:selected').val()
|
|
1097
|
+
},
|
|
1098
|
+
VIDEO_B_FRAMES: {
|
|
1099
|
+
value: parseInt($('#videoBFramesThreshold').val()),
|
|
1100
|
+
filter: $('#videoBFramesThresholdFilter option:selected').val()
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
const formatExtendedData = (row, data) => {
|
|
1105
|
+
const distributors = data.distributors;
|
|
1106
|
+
const info = $(
|
|
1107
|
+
'<div> <b>SessionId:</b> ' + data.sessionId + '</div>' +
|
|
1108
|
+
'<div> <b>MediaProvider:</b> ' + data.mediaProvider + '</div>'
|
|
1109
|
+
);
|
|
1110
|
+
|
|
1111
|
+
// Append nested distributor stat table
|
|
1112
|
+
if (data.published) {
|
|
1113
|
+
const table = $('<table id="' + data.mediaSessionId + '" class="display" width="100%"/>');
|
|
1114
|
+
table.appendTo(info);
|
|
1115
|
+
|
|
1116
|
+
const distributorsData = [];
|
|
1117
|
+
Object.keys(distributors).forEach(key => {
|
|
1118
|
+
const stat = distributors[key];
|
|
1119
|
+
distributorsData.push({
|
|
1120
|
+
id: key,
|
|
1121
|
+
codec: stat.codec,
|
|
1122
|
+
queueSize: stat.queueSize,
|
|
1123
|
+
resolution: stat.resolution,
|
|
1124
|
+
videoGroupsSendStats: stat.videoGroupsSendStats
|
|
1125
|
+
})
|
|
1126
|
+
})
|
|
1127
|
+
const distributorsTable = table.DataTable({
|
|
1128
|
+
data: distributorsData,
|
|
1129
|
+
columns: [
|
|
1130
|
+
{
|
|
1131
|
+
className: 'sub-dt-control',
|
|
1132
|
+
orderable: false,
|
|
1133
|
+
data: null,
|
|
1134
|
+
defaultContent: ''
|
|
1135
|
+
},
|
|
1136
|
+
{data: 'id', title: 'Id'},
|
|
1137
|
+
{data: 'codec', title: 'Codec'},
|
|
1138
|
+
{data: 'resolution', title: 'Resolution'},
|
|
1139
|
+
{data: 'queueSize', title: 'QueueSize'}
|
|
1140
|
+
],
|
|
1141
|
+
paging: false,
|
|
1142
|
+
|
|
1143
|
+
});
|
|
1144
|
+
const format = (d) => {
|
|
1145
|
+
let result = '';
|
|
1146
|
+
if (d.videoGroupsSendStats) {
|
|
1147
|
+
Object.keys(d.videoGroupsSendStats).forEach(key => {
|
|
1148
|
+
let groupInfo = '';
|
|
1149
|
+
const group = d.videoGroupsSendStats[key];
|
|
1150
|
+
groupInfo += '<div><b>ID:</b> ' + key + '</div>';
|
|
1151
|
+
groupInfo += '<p>';
|
|
1152
|
+
group.videoGroupSendStats.forEach(participant => {
|
|
1153
|
+
groupInfo += '<div><b>ID</b>: ' + participant.id + ' ; <b>maxSendTime:</b> ' + participant.maxSendTime + ' ; <b>minSendTime:</b> ' + participant.minSendTime + ' ; <b>averageSendTime:</b> ' + participant.averageSendTime + '</div>';
|
|
1154
|
+
});
|
|
1155
|
+
groupInfo += '</p>';
|
|
1156
|
+
result += groupInfo;
|
|
1157
|
+
})
|
|
1158
|
+
}
|
|
1159
|
+
return result;
|
|
1160
|
+
}
|
|
1161
|
+
// Add event listener for opening and closing details
|
|
1162
|
+
table.on('click', 'td.sub-dt-control', function () {
|
|
1163
|
+
const tr = $(this).closest('tr');
|
|
1164
|
+
const row = distributorsTable.row(tr);
|
|
1165
|
+
|
|
1166
|
+
if (row.child.isShown()) {
|
|
1167
|
+
// This row is already open - close it
|
|
1168
|
+
row.child.hide();
|
|
1169
|
+
tr.removeClass('shown');
|
|
1170
|
+
} else {
|
|
1171
|
+
// Open this row
|
|
1172
|
+
row.child(format(row.data())).show();
|
|
1173
|
+
tr.addClass('shown');
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
row.child( info ).show();
|
|
1178
|
+
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
//Todo: remove netsted table and do off event listeners
|
|
1182
|
+
const destroyDataTable = () => {
|
|
1183
|
+
if ( $.fn.dataTable.isDataTable('#metricsTable') ) {
|
|
1184
|
+
const table = $('#metricsTable').DataTable();
|
|
1185
|
+
$('#metricsTable tbody').off('click', 'td.dt-control');
|
|
1186
|
+
table.destroy();
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
const createDataTable = () => {
|
|
1191
|
+
if ( $.fn.dataTable.isDataTable('#metricsTable') ) {
|
|
1192
|
+
destroyDataTable();
|
|
1193
|
+
}
|
|
1194
|
+
return $('#metricsTable').DataTable({
|
|
1195
|
+
columns: [
|
|
1196
|
+
{
|
|
1197
|
+
className: 'dt-control',
|
|
1198
|
+
orderable: false,
|
|
1199
|
+
data: null,
|
|
1200
|
+
defaultContent: ''
|
|
1201
|
+
},
|
|
1202
|
+
{data: 'name'},
|
|
1203
|
+
{data: 'mediaType'},
|
|
1204
|
+
{data: 'metrics.VIDEO_WIDTH'},
|
|
1205
|
+
{data: 'metrics.VIDEO_HEIGHT'},
|
|
1206
|
+
{data: 'metrics.VIDEO_RATE'},
|
|
1207
|
+
{data: 'metrics.VIDEO_NACK'},
|
|
1208
|
+
{data: 'metrics.VIDEO_B_FRAMES'},
|
|
1209
|
+
{data: 'metrics.VIDEO_LOST'},
|
|
1210
|
+
{data: 'metrics.VIDEO_FPS'}
|
|
1211
|
+
]
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
const metricTable = createDataTable();
|
|
1216
|
+
|
|
1217
|
+
const feedDataTable = (data) => {
|
|
1218
|
+
|
|
1219
|
+
metricTable.clear();
|
|
1220
|
+
metricTable.rows.add(data);
|
|
1221
|
+
metricTable.draw();
|
|
1222
|
+
|
|
1223
|
+
// Add event listener for opening and closing details
|
|
1224
|
+
$('#metricsTable tbody').on('click', 'td.dt-control', function() {
|
|
1225
|
+
const tr = $(this).closest('tr');
|
|
1226
|
+
const row = metricTable.row(tr);
|
|
1227
|
+
|
|
1228
|
+
if (row.child.isShown()) {
|
|
1229
|
+
// This row is already open - close it
|
|
1230
|
+
row.child.hide();
|
|
1231
|
+
tr.removeClass('shown');
|
|
1232
|
+
} else {
|
|
1233
|
+
// Open this row
|
|
1234
|
+
row.child(formatExtendedData(row, row.data())).show();
|
|
1235
|
+
tr.addClass('shown');
|
|
1236
|
+
}
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
const transcodingGroupStat = await node.getTranscodingGroupStat();
|
|
1241
|
+
|
|
1242
|
+
const filterData = (data) => {
|
|
1243
|
+
const filteredData = [];
|
|
1244
|
+
let tmpData = data;
|
|
1245
|
+
if (mediaProviderFilter !== "all") {
|
|
1246
|
+
tmpData = data.filter(stream => stream.mediaProvider === mediaProviderFilter);
|
|
1247
|
+
}
|
|
1248
|
+
if (mediaTypeFilter === "play") {
|
|
1249
|
+
tmpData = data.filter(stream => stream.mediaType === mediaTypeFilter);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
const checkMetricThresholds = (metrics) => {
|
|
1253
|
+
const matched = [];
|
|
1254
|
+
Object.keys(thresholds).forEach(key => {
|
|
1255
|
+
if (thresholds[key].value >= 0) {
|
|
1256
|
+
const metric = parseInt(metrics[key]);
|
|
1257
|
+
switch (thresholds[key].filter) {
|
|
1258
|
+
case "eq":
|
|
1259
|
+
matched.push(metric === thresholds[key].value);
|
|
1260
|
+
break;
|
|
1261
|
+
case "gt":
|
|
1262
|
+
matched.push(metric > thresholds[key].value);
|
|
1263
|
+
break;
|
|
1264
|
+
case "lt":
|
|
1265
|
+
matched.push(metric < thresholds[key].value);
|
|
1266
|
+
break;
|
|
1267
|
+
case "goe":
|
|
1268
|
+
matched.push(metric >= thresholds[key].value);
|
|
1269
|
+
break;
|
|
1270
|
+
case "loe":
|
|
1271
|
+
matched.push(metric <= thresholds[key].value);
|
|
1272
|
+
break;
|
|
1273
|
+
}
|
|
1274
|
+
} else {
|
|
1275
|
+
matched.push(false);
|
|
1276
|
+
}
|
|
1277
|
+
})
|
|
1278
|
+
return !matched.some(el => el === false);
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
tmpData.forEach(stream => {
|
|
1282
|
+
const published = stream.published;
|
|
1283
|
+
if (streamTypeThresholdFilter === "all" || stream.mediaType === streamTypeThresholdFilter) {
|
|
1284
|
+
if (checkMetricThresholds(stream.metrics)) {
|
|
1285
|
+
if (published) {
|
|
1286
|
+
const stat = transcodingGroupStat.transcoding_stats.transcoding_video_full_info[stream.name];
|
|
1287
|
+
stream['distributors'] = stat.distributors;
|
|
1288
|
+
}
|
|
1289
|
+
filteredData.push(stream);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
})
|
|
1293
|
+
return filteredData;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
const publishedOnly = (mediaTypeFilter === "publish") ? true : null;
|
|
1297
|
+
|
|
1298
|
+
const getStreams = () => {
|
|
1299
|
+
const streams = node.stream.find(null, (isAllStreams) ? null : streamName, publishedOnly, true);
|
|
1300
|
+
streams
|
|
1301
|
+
.then((result) => {
|
|
1302
|
+
console.log("rest response: ", result);
|
|
1303
|
+
feedDataTable(filterData(result));
|
|
1304
|
+
})
|
|
1305
|
+
.catch((e) => {
|
|
1306
|
+
console.log("Failed to get all streams ", e);
|
|
1307
|
+
})
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
getStreams();
|
|
1311
|
+
|
|
1312
|
+
$('#refreshMetricsBtn').on('click', () => {
|
|
1313
|
+
getStreams();
|
|
1314
|
+
})
|
|
1315
|
+
|
|
1316
|
+
$("#streamMetricsModal").modal('hide');
|
|
1317
|
+
$("#streamMetricsDetailsModal").modal('show');
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1040
1320
|
function streamPublishStressTest() {
|
|
1041
1321
|
if (!$("#streamPublishStressBatchNodes").val()) {
|
|
1042
1322
|
$('#warningModal').modal();
|