@flashphoner/websdk 2.0.243 → 2.0.245

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.
@@ -1,4 +1,4 @@
1
- Web SDK - 2.0.243
1
+ Web SDK - 2.0.245
2
2
 
3
3
  [Download builds](https://docs.flashphoner.com/display/WEBSDK2EN/Web+SDK+release+notes)
4
4
 
@@ -1,8 +1,18 @@
1
1
  const Browser = Flashphoner.Browser;
2
2
  const STATS_INTERVAL = 1000;
3
+ const QUALITY_COLORS = {
4
+ NONE: "",
5
+ AVAILABLE: "black",
6
+ SELECTED: "blue"
7
+ };
8
+ const QUALITY_AUTO = "Auto";
3
9
  let remoteVideo = null;
4
10
  let hlsPlayer = null;
11
+ let playSrc = getUrlParam("src");
12
+ let autoplay = eval(getUrlParam("autoplay")) || false;
13
+ let llHlsEnabled = eval(getUrlParam("llhls")) || false;
5
14
  let playbackStats = null;
15
+ let qualityLevels = [];
6
16
 
7
17
  const loadPlayerPage = function() {
8
18
  loadPage("../hls-player/player-page.html", "playerPage", initPage );
@@ -22,17 +32,37 @@ const loadPage = function(page, containerId, onLoad) {
22
32
  }
23
33
 
24
34
  const initPage = function() {
25
- setText("header", "HLS.JS Player Minimal");
26
- setValue("urlServer", getHLSUrl());
27
- setText("applyBtn", "Play");
28
- setHandler("applyBtn", "click", playBtnClick);
35
+ if (playSrc) {
36
+ setValue("fullLink", decodeURIComponent(playSrc));
37
+ } else if (autoplay) {
38
+ console.warn("No HLS URL set, autoplay disabled");
39
+ autoplay = false;
40
+ }
41
+ if (llHlsEnabled) {
42
+ setCheckbox("llHlsEnabled", llHlsEnabled);
43
+ }
29
44
  remoteVideo = document.getElementById('remoteVideo');
30
- remoteVideo.style ="background-color: lightgrey;";
31
45
  if (Hls.isSupported()) {
32
46
  console.log("Using HLS.JS " + Hls.version);
33
- enableItem("applyBtn");
34
- showItem("llHlsMode");
35
- playbackStats = PlaybackStats(STATS_INTERVAL);
47
+ if (autoplay) {
48
+ // There should not be any visible item on the page unless player
49
+ hideAllToAutoplay();
50
+ // The player should use all available page width
51
+ setUpPlayerItem(true);
52
+ // The player should be muted to automatically start playback
53
+ initVideoPlayer(remoteVideo, true);
54
+ playBtnClick();
55
+ } else {
56
+ setText("header", "HLS.JS Player Minimal");
57
+ showItem("llHlsMode");
58
+ displayCommonItems();
59
+ setUpButtons();
60
+ enablePlaybackStats();
61
+ // The player should have a maximum fixed size
62
+ setUpPlayerItem(false);
63
+ // The player can be unmuted because user should click Play button
64
+ initVideoPlayer(remoteVideo, false);
65
+ }
36
66
  } else {
37
67
  setText("notifyFlash", "Your browser doesn't support MSE technology required to play video");
38
68
  disableItem("applyBtn");
@@ -42,21 +72,20 @@ const initPage = function() {
42
72
 
43
73
 
44
74
  const playBtnClick = function() {
45
- if (validateForm()) {
46
- let llHlsEnabled = getCheckbox("llHlsEnabled");
47
- let streamName = getValue("playStream");
48
- streamName = encodeURIComponent(streamName);
49
- let videoSrc = getValue("urlServer") + '/' + streamName + '/' + streamName + '.m3u8';
50
- let key = getValue('key');
51
- let token = getValue("token");
52
- if (key.length > 0 && token.length > 0) {
53
- videoSrc += "?" + key + "=" + token;
54
- }
75
+ let videoSrc = getVideoSrc(getValue("fullLink"));
76
+ if (videoSrc) {
77
+ llHlsEnabled = getCheckbox("llHlsEnabled");
55
78
  hlsPlayer = new Hls(getHlsConfig(llHlsEnabled));
56
79
  hlsPlayer.on(Hls.Events.MANIFEST_PARSED, function() {
57
80
  console.log("Play with HLS.js");
58
81
  remoteVideo.play();
82
+ initQualityLevels(hlsPlayer);
59
83
  });
84
+ remoteVideo.onplaying = () => {
85
+ console.log("playing event fired");
86
+ displayPermalink(videoSrc);
87
+ displayQualitySwitch();
88
+ }
60
89
  hlsPlayer.loadSource(videoSrc);
61
90
  hlsPlayer.attachMedia(remoteVideo);
62
91
  onStarted();
@@ -71,7 +100,7 @@ const getHlsConfig = function(llHlsEnabled) {
71
100
  backBufferLength: 90,
72
101
  manifestLoadingTimeOut: 15000
73
102
  };
74
- console.log("Low Latency HLS: "+llHlsEnabled)
103
+ console.log("Low Latency HLS: " + llHlsEnabled)
75
104
  if(llHlsEnabled) {
76
105
  // Here we configure HLS.JS for lower latency
77
106
  config = {
@@ -108,20 +137,27 @@ const stopBtnClick = function() {
108
137
 
109
138
 
110
139
  const onStarted = function() {
111
- toggleInputs(false);
112
- enableItem("applyBtn");
113
- setText("applyBtn", "Stop");
114
- setHandler("applyBtn", "click", stopBtnClick, playBtnClick);
115
- playbackStats.start();
140
+ if (!autoplay) {
141
+ toggleInputs(false);
142
+ enableItem("applyBtn");
143
+ hideItem("permalink");
144
+ setText("applyBtn", "Stop");
145
+ setHandler("applyBtn", "click", stopBtnClick, playBtnClick);
146
+ startPlaybackStats();
147
+ }
116
148
  }
117
149
 
118
150
 
119
151
  function onStopped() {
120
- toggleInputs(true);
121
- enableItem("applyBtn");
122
- setText("applyBtn", "Play");
123
- setHandler("applyBtn", "click", playBtnClick, stopBtnClick);
124
- playbackStats.stop();
152
+ if (!autoplay) {
153
+ toggleInputs(true);
154
+ enableItem("applyBtn");
155
+ setText("applyBtn", "Play");
156
+ setHandler("applyBtn", "click", playBtnClick, stopBtnClick);
157
+ stopPlaybackStats();
158
+ hideItem("quality");
159
+ disposeQualityLevels();
160
+ }
125
161
  }
126
162
 
127
163
 
@@ -166,6 +202,18 @@ const removeHighlight = function(input) {
166
202
  }
167
203
  }
168
204
 
205
+ const initVideoPlayer = function(video, muted) {
206
+ if (video) {
207
+ video.style.backgroundColor = "black";
208
+ video.muted = muted;
209
+ }
210
+ }
211
+
212
+ const setUpButtons = function() {
213
+ setHandler("applyBtn", "click", playBtnClick);
214
+ }
215
+
216
+
169
217
  const toggleInputs = function(enable) {
170
218
  if (enable) {
171
219
  enableItem("urlServer");
@@ -184,6 +232,88 @@ const toggleInputs = function(enable) {
184
232
  }
185
233
  }
186
234
 
235
+ const getVideoSrc = function(src) {
236
+ let videoSrc = src;
237
+ if (validateForm()) {
238
+ let streamName = getValue('playStream');
239
+ streamName = encodeURIComponent(streamName);
240
+ videoSrc = getValue("urlServer") + '/' + streamName + '/' + streamName + '.m3u8';
241
+ let key = getValue('key');
242
+ let token = getValue("token");
243
+ if (key.length > 0 && token.length > 0) {
244
+ videoSrc += "?" + key + "=" + token;
245
+ }
246
+ }
247
+ setValue("fullLink", videoSrc);
248
+ return videoSrc;
249
+ }
250
+
251
+ const displayPermalink = function(src) {
252
+ if (!autoplay) {
253
+ const permalinkId = "permalink";
254
+ let videoSrc = encodeURIComponent(src);
255
+ let linkObject = document.getElementById(permalinkId);
256
+ let href = window.location.href.split("?")[0] + "?llhls=" + llHlsEnabled + "&src=" + videoSrc;
257
+ linkObject.href = href;
258
+ showItem(permalinkId);
259
+ }
260
+ }
261
+
262
+ const displayQualitySwitch = function() {
263
+ if (!autoplay && qualityLevels.length) {
264
+ showItem("quality")
265
+ }
266
+ }
267
+
268
+ const hideAllToAutoplay = function() {
269
+ hideItem("header");
270
+ hideItem("notifyFlash");
271
+ hideItem("fieldset");
272
+ hideItem("stats");
273
+ }
274
+
275
+ const displayCommonItems = function() {
276
+ setValue("urlServer", getHLSUrl());
277
+ hideItem("permalink");
278
+ enableItem("applyBtn");
279
+ setText("applyBtn", "Play");
280
+ }
281
+
282
+ const setUpPlayerItem = function(fillPage) {
283
+ let videoContainer = document.getElementById('videoContainer');
284
+ let playerPage = document.getElementById('playerPage');
285
+
286
+ if (fillPage) {
287
+ playerPage.classList.remove("container");
288
+ videoContainer.style.marginTop = "0px";
289
+ videoContainer.style.width = "100vw";
290
+ videoContainer.style.height = "100vh";
291
+ videoContainer.style.maxWidth = "available";
292
+ videoContainer.style.maxHeight = "available";
293
+ } else {
294
+ videoContainer.style.maxWidth = "852px";
295
+ videoContainer.style.maxHeight = "480px";
296
+ }
297
+ }
298
+
299
+ const enablePlaybackStats = function() {
300
+ if (!autoplay && !playbackStats) {
301
+ playbackStats = PlaybackStats(STATS_INTERVAL);
302
+ }
303
+ }
304
+
305
+ const startPlaybackStats = function() {
306
+ if (!autoplay && playbackStats) {
307
+ playbackStats.start();
308
+ }
309
+ }
310
+
311
+ const stopPlaybackStats = function() {
312
+ if (!autoplay && playbackStats) {
313
+ playbackStats.stop();
314
+ }
315
+ }
316
+
187
317
  const PlaybackStats = function(interval) {
188
318
  const playbackStats = {
189
319
  interval: interval || STATS_INTERVAL,
@@ -229,4 +359,65 @@ const PlaybackStats = function(interval) {
229
359
  }
230
360
  };
231
361
  return playbackStats;
362
+ }
363
+
364
+ const initQualityLevels = function(player) {
365
+ if (player) {
366
+ let qualityDiv = document.getElementById("qualityBtns");
367
+ let qualityLevel;
368
+ for (let i = 0; i < player.levels.length; i++) {
369
+ qualityLevel = QualityLevel(player, player.levels[i].height, i, qualityDiv);
370
+ qualityLevels.push(qualityLevel);
371
+ }
372
+ if (qualityLevels.length) {
373
+ qualityLevel = QualityLevel(player, QUALITY_AUTO, -1, qualityDiv);
374
+ qualityLevels.push(qualityLevel);
375
+ }
376
+ }
377
+ }
378
+
379
+ const disposeQualityLevels = function() {
380
+ qualityLevels.forEach(level => {
381
+ if (level.button) {
382
+ level.button.remove();
383
+ }
384
+ });
385
+ qualityLevels = [];
386
+ }
387
+
388
+ const qualityBtnClick = function(button, player, index) {
389
+ if (player) {
390
+ player.currentLevel = index;
391
+ }
392
+ button.style.color = QUALITY_COLORS.SELECTED;
393
+ qualityLevels.forEach(item => {
394
+ if (item.button.id !== button.id) {
395
+ item.button.style.color = QUALITY_COLORS.AVAILABLE
396
+ }
397
+ });
398
+ }
399
+
400
+ const QualityLevel = function(object, levelId, index, btnParent) {
401
+ const btnId = "qualityBtn";
402
+ let button = document.createElement("button");
403
+ if (levelId === QUALITY_AUTO && index === -1) {
404
+ button.id = btnId + QUALITY_AUTO;
405
+ button.innerHTML = QUALITY_AUTO
406
+ } else {
407
+ button.id = btnId + index;
408
+ button.innerHTML = levelId;
409
+ }
410
+ button.type = "button";
411
+ button.className = "btn btn-default";
412
+ button.style.color = QUALITY_COLORS.AVAILABLE;
413
+ button.onclick = (event) => {
414
+ qualityBtnClick(button, object, index);
415
+ };
416
+ btnParent.appendChild(button);
417
+ const qualityLevel = {
418
+ level: levelId,
419
+ index: index,
420
+ button: button
421
+ };
422
+ return qualityLevel;
232
423
  }
@@ -1,6 +1,8 @@
1
1
  const Browser = Flashphoner.Browser;
2
2
  const STATS_INTERVAL = 1000;
3
3
  let remoteVideo = null;
4
+ let playSrc = getUrlParam("src");
5
+ let autoplay = eval(getUrlParam("autoplay")) || false;
4
6
  let playbackStats = null;
5
7
 
6
8
  const loadPlayerPage = function() {
@@ -21,19 +23,33 @@ const loadPage = function(page, containerId, onLoad) {
21
23
  }
22
24
 
23
25
  const initPage = function() {
24
- setText("header", "HLS Native Player Minimal");
25
- setValue("urlServer", getHLSUrl());
26
- setText("applyBtn", "Play");
27
- setHandler("applyBtn", "click", playBtnClick);
28
- remoteVideo = document.getElementById('remoteVideo');
29
- remoteVideo.style ="background-color: lightgrey;";
30
- if (Browser.isSafariWebRTC() && Browser.isiOS()) {
31
- // iOS hack when using standard controls to leave fullscreen mode
32
- setWebkitFullscreenHandlers(remoteVideo);
26
+ if (playSrc) {
27
+ setValue("fullLink", decodeURIComponent(playSrc));
28
+ } else if (autoplay) {
29
+ console.warn("No HLS URL set, autoplay disabled");
30
+ autoplay = false;
33
31
  }
32
+ remoteVideo = document.getElementById('remoteVideo');
34
33
  if (remoteVideo.canPlayType('application/vnd.apple.mpegurl') && Browser.isSafariWebRTC()) {
35
- enableItem("applyBtn");
36
- playbackStats = PlaybackStats(STATS_INTERVAL);
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
+ }
37
53
  } else {
38
54
  setText("notifyFlash", "Your browser doesn't support native HLS playback");
39
55
  disableItem("applyBtn");
@@ -42,21 +58,18 @@ const initPage = function() {
42
58
  }
43
59
 
44
60
  const playBtnClick = function() {
45
- if (validateForm()) {
46
- let streamName = getValue("playStream");
47
- streamName = encodeURIComponent(streamName);
48
- let videoSrc = getValue("urlServer") + '/' + streamName + '/' + streamName + '.m3u8';
49
- let key = getValue('key');
50
- let token = getValue("token");
51
- if (key.length > 0 && token.length > 0) {
52
- videoSrc += "?" + key + "=" + token;
53
- }
54
- remoteVideo.src = videoSrc;
55
- remoteVideo.addEventListener('loadedmetadata', function() {
61
+ let videoSrc = getVideoSrc(getValue("fullLink"));
62
+ if (videoSrc) {
63
+ remoteVideo.onloadedmetadata = () => {
56
64
  console.log("Play native HLS");
57
65
  remoteVideo.play();
58
66
  onStarted();
59
- });
67
+ };
68
+ remoteVideo.onplaying = () => {
69
+ console.log("playing event fired");
70
+ displayPermalink(videoSrc);
71
+ };
72
+ remoteVideo.src = videoSrc;
60
73
  }
61
74
  }
62
75
 
@@ -74,20 +87,25 @@ const stopBtnClick = function() {
74
87
 
75
88
 
76
89
  const onStarted = function() {
77
- toggleInputs(false);
78
- enableItem("applyBtn");
79
- setText("applyBtn", "Stop");
80
- setHandler("applyBtn", "click", stopBtnClick, playBtnClick);
81
- playbackStats.start();
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
+ }
82
98
  }
83
99
 
84
100
 
85
101
  const onStopped = function() {
86
- toggleInputs(true);
87
- enableItem("applyBtn");
88
- setText("applyBtn", "Play");
89
- setHandler("applyBtn", "click", playBtnClick, stopBtnClick);
90
- playbackStats.stop();
102
+ if (!autoplay) {
103
+ toggleInputs(true);
104
+ enableItem("applyBtn");
105
+ setText("applyBtn", "Play");
106
+ setHandler("applyBtn", "click", playBtnClick, stopBtnClick);
107
+ stopPlaybackStats();
108
+ }
91
109
  }
92
110
 
93
111
 
@@ -132,6 +150,21 @@ const removeHighlight = function(input) {
132
150
  }
133
151
  }
134
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
+
135
168
  const toggleInputs = function(enable) {
136
169
  if (enable) {
137
170
  enableItem("urlServer");
@@ -148,6 +181,82 @@ const toggleInputs = function(enable) {
148
181
  }
149
182
  }
150
183
 
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;
198
+ }
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
+ }
217
+
218
+ const displayCommonItems = function() {
219
+ setValue("urlServer", getHLSUrl());
220
+ hideItem("permalink");
221
+ enableItem("applyBtn");
222
+ setText("applyBtn", "Play");
223
+ }
224
+
225
+ const setUpPlayerItem = function(fillPage) {
226
+ let videoContainer = document.getElementById('videoContainer');
227
+ let playerPage = document.getElementById('playerPage');
228
+
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
+ }
252
+ }
253
+
254
+ const stopPlaybackStats = function() {
255
+ if (!autoplay && playbackStats) {
256
+ playbackStats.stop();
257
+ }
258
+ }
259
+
151
260
  const PlaybackStats = function(interval) {
152
261
  const playbackStats = {
153
262
  interval: interval || STATS_INTERVAL,