@flashphoner/websdk 2.0.242 → 2.0.244
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/dependencies/js/stats.js +105 -0
- package/examples/demo/dependencies/js/utils.js +95 -6
- package/examples/demo/streaming/hls-js-player/hls-js-player.html +1 -4
- package/examples/demo/streaming/hls-js-player/hls-js-player.js +263 -58
- package/examples/demo/streaming/hls-native/hls-native.html +1 -4
- package/examples/demo/streaming/hls-native/hls-native.js +264 -63
- package/examples/demo/streaming/hls-player/hls-player.html +1 -4
- package/examples/demo/streaming/hls-player/hls-player.js +220 -61
- package/examples/demo/streaming/hls-player/player-page.html +53 -5
- package/package.json +1 -1
|
@@ -1,48 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const Browser = Flashphoner.Browser;
|
|
2
|
+
const STATS_INTERVAL = 1000;
|
|
3
|
+
let remoteVideo = null;
|
|
4
|
+
let playSrc = getUrlParam("src");
|
|
5
|
+
let autoplay = eval(getUrlParam("autoplay")) || false;
|
|
6
|
+
let playbackStats = null;
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
8
|
+
const loadPlayerPage = function() {
|
|
9
|
+
loadPage("../hls-player/player-page.html", "playerPage", initPage );
|
|
6
10
|
}
|
|
7
11
|
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
const loadPage = function(page, containerId, onLoad) {
|
|
13
|
+
fetch(page).then(function (response) {
|
|
14
|
+
if (response.ok) {
|
|
15
|
+
return response.text();
|
|
16
|
+
}
|
|
17
|
+
throw response;
|
|
18
|
+
}).then(function (text) {
|
|
19
|
+
let container = document.getElementById(containerId);
|
|
20
|
+
container.innerHTML = text;
|
|
21
|
+
onLoad();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const initPage = function() {
|
|
26
|
+
if (playSrc) {
|
|
27
|
+
setValue("fullLink", decodeURIComponent(playSrc));
|
|
28
|
+
} else if (autoplay) {
|
|
29
|
+
console.warn("No HLS URL set, autoplay disabled");
|
|
30
|
+
autoplay = false;
|
|
31
|
+
}
|
|
12
32
|
remoteVideo = document.getElementById('remoteVideo');
|
|
13
|
-
remoteVideo.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
33
|
+
if (remoteVideo.canPlayType('application/vnd.apple.mpegurl') && Browser.isSafariWebRTC()) {
|
|
34
|
+
console.log("Using Native HLS player");
|
|
35
|
+
if (autoplay) {
|
|
36
|
+
// There should not be any visible item on the page unless player
|
|
37
|
+
hideAllToAutoplay();
|
|
38
|
+
// The player should use all available page width
|
|
39
|
+
setUpPlayerItem(true);
|
|
40
|
+
// The player should be muted to automatically start playback
|
|
41
|
+
initVideoPlayer(remoteVideo, true);
|
|
42
|
+
playBtnClick();
|
|
43
|
+
} else {
|
|
44
|
+
setText("header", "HLS Native Player Minimal");
|
|
45
|
+
displayCommonItems();
|
|
46
|
+
setUpButtons();
|
|
47
|
+
enablePlaybackStats();
|
|
48
|
+
// The player should have a maximum fixed size
|
|
49
|
+
setUpPlayerItem(false);
|
|
50
|
+
// The player can be unmuted because user should click Play button
|
|
51
|
+
initVideoPlayer(remoteVideo, false);
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
setText("notifyFlash", "Your browser doesn't support native HLS playback");
|
|
55
|
+
disableItem("applyBtn");
|
|
56
|
+
toggleInputs(false);
|
|
17
57
|
}
|
|
18
58
|
}
|
|
19
59
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
console.log("Play native HLS");
|
|
34
|
-
remoteVideo.play();
|
|
35
|
-
onStarted();
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
$("#notifyFlash").text("Your browser doesn't support native HLS playback");
|
|
40
|
-
}
|
|
60
|
+
const playBtnClick = function() {
|
|
61
|
+
let videoSrc = getVideoSrc(getValue("fullLink"));
|
|
62
|
+
if (videoSrc) {
|
|
63
|
+
remoteVideo.onloadedmetadata = () => {
|
|
64
|
+
console.log("Play native HLS");
|
|
65
|
+
remoteVideo.play();
|
|
66
|
+
onStarted();
|
|
67
|
+
};
|
|
68
|
+
remoteVideo.onplaying = () => {
|
|
69
|
+
console.log("playing event fired");
|
|
70
|
+
displayPermalink(videoSrc);
|
|
71
|
+
};
|
|
72
|
+
remoteVideo.src = videoSrc;
|
|
41
73
|
}
|
|
42
74
|
}
|
|
43
75
|
|
|
44
76
|
|
|
45
|
-
|
|
77
|
+
const stopBtnClick = function() {
|
|
46
78
|
if (remoteVideo != null) {
|
|
47
79
|
console.log("Stop HTML5 player");
|
|
48
80
|
remoteVideo.pause();
|
|
@@ -54,51 +86,220 @@ function stopBtnClick() {
|
|
|
54
86
|
}
|
|
55
87
|
|
|
56
88
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
const onStarted = function() {
|
|
90
|
+
if (!autoplay) {
|
|
91
|
+
toggleInputs(false);
|
|
92
|
+
enableItem("applyBtn");
|
|
93
|
+
hideItem("permalink");
|
|
94
|
+
setText("applyBtn", "Stop");
|
|
95
|
+
setHandler("applyBtn", "click", stopBtnClick, playBtnClick);
|
|
96
|
+
startPlaybackStats();
|
|
97
|
+
}
|
|
64
98
|
}
|
|
65
99
|
|
|
66
100
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
101
|
+
const onStopped = function() {
|
|
102
|
+
if (!autoplay) {
|
|
103
|
+
toggleInputs(true);
|
|
104
|
+
enableItem("applyBtn");
|
|
105
|
+
setText("applyBtn", "Play");
|
|
106
|
+
setHandler("applyBtn", "click", playBtnClick, stopBtnClick);
|
|
107
|
+
stopPlaybackStats();
|
|
108
|
+
}
|
|
74
109
|
}
|
|
75
110
|
|
|
76
111
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
112
|
+
const validateForm = function() {
|
|
113
|
+
let valid = validateInput("urlServer");
|
|
114
|
+
if (valid) {
|
|
115
|
+
valid = validateInput("playStream");
|
|
116
|
+
}
|
|
117
|
+
return valid;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const validateInput = function(id) {
|
|
121
|
+
let value = getValue(id);
|
|
122
|
+
let valid = true;
|
|
123
|
+
if (!value || !value.length) {
|
|
124
|
+
highlightInput(id);
|
|
81
125
|
valid = false;
|
|
82
126
|
} else {
|
|
83
|
-
removeHighlight(
|
|
127
|
+
removeHighlight(id);
|
|
84
128
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
129
|
+
return valid;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const highlightInput = function(input) {
|
|
133
|
+
let item = document.getElementById(input);
|
|
134
|
+
if (item) {
|
|
135
|
+
let parent = closest(input,'.form-group');
|
|
136
|
+
if (parent) {
|
|
137
|
+
parent.classList.add("has-error");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
const removeHighlight = function(input) {
|
|
144
|
+
let item = document.getElementById(input);
|
|
145
|
+
if (item) {
|
|
146
|
+
let parent = closest(input,'.form-group');
|
|
147
|
+
if (parent) {
|
|
148
|
+
parent.classList.remove("has-error");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const initVideoPlayer = function(video, muted) {
|
|
154
|
+
if (video) {
|
|
155
|
+
video.style.backgroundColor = "black";
|
|
156
|
+
video.muted = muted;
|
|
157
|
+
if (Browser.isiOS()) {
|
|
158
|
+
// iOS hack when using standard controls to leave fullscreen mode
|
|
159
|
+
setWebkitFullscreenHandlers(video);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const setUpButtons = function() {
|
|
165
|
+
setHandler("applyBtn", "click", playBtnClick);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const toggleInputs = function(enable) {
|
|
169
|
+
if (enable) {
|
|
170
|
+
enableItem("urlServer");
|
|
171
|
+
enableItem("playStream");
|
|
172
|
+
enableItem("key");
|
|
173
|
+
enableItem("token");
|
|
174
|
+
enableItem("player");
|
|
88
175
|
} else {
|
|
89
|
-
|
|
176
|
+
disableItem("urlServer");
|
|
177
|
+
disableItem("playStream");
|
|
178
|
+
disableItem("key");
|
|
179
|
+
disableItem("token");
|
|
180
|
+
disableItem("player");
|
|
90
181
|
}
|
|
182
|
+
}
|
|
91
183
|
|
|
92
|
-
|
|
93
|
-
|
|
184
|
+
const getVideoSrc = function(src) {
|
|
185
|
+
let videoSrc = src;
|
|
186
|
+
if (validateForm()) {
|
|
187
|
+
let streamName = getValue('playStream');
|
|
188
|
+
streamName = encodeURIComponent(streamName);
|
|
189
|
+
videoSrc = getValue("urlServer") + '/' + streamName + '/' + streamName + '.m3u8';
|
|
190
|
+
let key = getValue('key');
|
|
191
|
+
let token = getValue("token");
|
|
192
|
+
if (key.length > 0 && token.length > 0) {
|
|
193
|
+
videoSrc += "?" + key + "=" + token;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
setValue("fullLink", videoSrc);
|
|
197
|
+
return videoSrc;
|
|
94
198
|
}
|
|
95
199
|
|
|
200
|
+
const displayPermalink = function(src) {
|
|
201
|
+
if (!autoplay) {
|
|
202
|
+
const permalinkId = "permalink";
|
|
203
|
+
let videoSrc = encodeURIComponent(src);
|
|
204
|
+
let linkObject = document.getElementById(permalinkId);
|
|
205
|
+
let href = window.location.href.split("?")[0] + "?src=" + videoSrc;
|
|
206
|
+
linkObject.href = href;
|
|
207
|
+
showItem(permalinkId);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const hideAllToAutoplay = function() {
|
|
212
|
+
hideItem("header");
|
|
213
|
+
hideItem("notifyFlash");
|
|
214
|
+
hideItem("fieldset");
|
|
215
|
+
hideItem("stats");
|
|
216
|
+
}
|
|
96
217
|
|
|
97
|
-
function
|
|
98
|
-
|
|
218
|
+
const displayCommonItems = function() {
|
|
219
|
+
setValue("urlServer", getHLSUrl());
|
|
220
|
+
hideItem("permalink");
|
|
221
|
+
enableItem("applyBtn");
|
|
222
|
+
setText("applyBtn", "Play");
|
|
99
223
|
}
|
|
100
224
|
|
|
225
|
+
const setUpPlayerItem = function(fillPage) {
|
|
226
|
+
let videoContainer = document.getElementById('videoContainer');
|
|
227
|
+
let playerPage = document.getElementById('playerPage');
|
|
101
228
|
|
|
102
|
-
|
|
103
|
-
|
|
229
|
+
if (fillPage) {
|
|
230
|
+
playerPage.classList.remove("container");
|
|
231
|
+
videoContainer.style.marginTop = "0px";
|
|
232
|
+
videoContainer.style.width = "100vw";
|
|
233
|
+
videoContainer.style.height = "100vh";
|
|
234
|
+
videoContainer.style.maxWidth = "available";
|
|
235
|
+
videoContainer.style.maxHeight = "available";
|
|
236
|
+
} else {
|
|
237
|
+
videoContainer.style.maxWidth = "852px";
|
|
238
|
+
videoContainer.style.maxHeight = "480px";
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const enablePlaybackStats = function() {
|
|
243
|
+
if (!autoplay && !playbackStats) {
|
|
244
|
+
playbackStats = PlaybackStats(STATS_INTERVAL);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const startPlaybackStats = function() {
|
|
249
|
+
if (!autoplay && playbackStats) {
|
|
250
|
+
playbackStats.start();
|
|
251
|
+
}
|
|
104
252
|
}
|
|
253
|
+
|
|
254
|
+
const stopPlaybackStats = function() {
|
|
255
|
+
if (!autoplay && playbackStats) {
|
|
256
|
+
playbackStats.stop();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const PlaybackStats = function(interval) {
|
|
261
|
+
const playbackStats = {
|
|
262
|
+
interval: interval || STATS_INTERVAL,
|
|
263
|
+
timer: null,
|
|
264
|
+
stats: null,
|
|
265
|
+
start: function() {
|
|
266
|
+
let video = remoteVideo;
|
|
267
|
+
|
|
268
|
+
playbackStats.stop();
|
|
269
|
+
stats = HTML5Stats(video);
|
|
270
|
+
playbackStats.timer = setInterval(playbackStats.displayStats, playbackStats.interval);
|
|
271
|
+
setText("videoWidth", "N/A");
|
|
272
|
+
setText("videoHeight", "N/A");
|
|
273
|
+
setText("videoRate", "N/A");
|
|
274
|
+
setText("videoFps", "N/A");
|
|
275
|
+
showItem("stats");
|
|
276
|
+
},
|
|
277
|
+
stop: function() {
|
|
278
|
+
if (playbackStats.timer) {
|
|
279
|
+
clearInterval(playbackStats.timer);
|
|
280
|
+
playbackStats.timer = null;
|
|
281
|
+
}
|
|
282
|
+
playbackStats.stats = null;
|
|
283
|
+
hideItem("stats");
|
|
284
|
+
},
|
|
285
|
+
displayStats: function() {
|
|
286
|
+
if (stats.collect()) {
|
|
287
|
+
let width = stats.getWidth();
|
|
288
|
+
let height = stats.getHeight();
|
|
289
|
+
let bitrate = stats.getBitrate();
|
|
290
|
+
let fps = stats.getFps();
|
|
291
|
+
|
|
292
|
+
setText("videoWidth", width);
|
|
293
|
+
setText("videoHeight", height);
|
|
294
|
+
|
|
295
|
+
if (bitrate !== undefined) {
|
|
296
|
+
setText("videoRate", Math.round(bitrate));
|
|
297
|
+
}
|
|
298
|
+
if (fps !== undefined) {
|
|
299
|
+
setText("videoFps", fps.toFixed(1));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
return playbackStats;
|
|
305
|
+
}
|
|
@@ -5,14 +5,11 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<link rel="stylesheet" href="../../dependencies/bootstrap/css/bootstrap.css">
|
|
7
7
|
<link rel="stylesheet" href="hls-player.css">
|
|
8
|
-
<!-- <link rel="stylesheet" href="video-js.css"> -->
|
|
9
8
|
<title>HLS VideoJS Player Minimal</title>
|
|
10
9
|
<script type="text/javascript" src="../../../../flashphoner.js"></script>
|
|
11
|
-
<!-- <script type="text/javascript" src="../../dependencies/jquery/jquery-1.12.0.js"></script>
|
|
12
|
-
<script type="text/javascript" src="../../dependencies/jquery/jquery-ui.js"></script> -->
|
|
13
10
|
<script type="text/javascript" src="../../dependencies/js/utils.js"></script>
|
|
11
|
+
<script type="text/javascript" src="../../dependencies/js/stats.js"></script>
|
|
14
12
|
<script type="text/javascript" src="hls-player.js"></script>
|
|
15
|
-
<!-- <script type="text/javascript" src="video.js"></script> -->
|
|
16
13
|
</head>
|
|
17
14
|
<body onload="loadPlayerPage()">
|
|
18
15
|
<div class="row form-group" id="videojsInputForm">
|