@flashphoner/websdk 2.0.239 → 2.0.241
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/utils.js +16 -14
- package/examples/demo/streaming/embed_player/player.js +2 -0
- package/examples/demo/streaming/hls-player/hls-player.js +108 -13
- package/examples/demo/streaming/hls-player/player-page.html +13 -2
- package/examples/demo/streaming/player/player.html +8 -0
- package/examples/demo/streaming/player/player.js +28 -6
- package/flashphoner-no-flash.js +38 -10
- package/flashphoner-no-flash.min.js +3 -3
- package/flashphoner-no-webrtc.js +26 -10
- package/flashphoner-no-webrtc.min.js +3 -3
- package/flashphoner-no-wsplayer.js +38 -10
- package/flashphoner-no-wsplayer.min.js +3 -3
- package/flashphoner-room-api.js +45 -14
- package/flashphoner-room-api.min.js +6 -6
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +26 -10
- package/flashphoner-temasys-flash-websocket.js +26 -10
- package/flashphoner-temasys-flash-websocket.min.js +3 -3
- package/flashphoner-webrtc-only.js +36 -8
- package/flashphoner-webrtc-only.min.js +1 -1
- package/flashphoner.js +38 -10
- package/flashphoner.min.js +3 -3
- package/package.json +1 -1
- package/src/flashphoner-core.js +28 -10
- package/src/media-source-media-provider.js +4 -4
- package/src/webrtc-media-provider.js +13 -0
package/docTemplate/README.md
CHANGED
|
@@ -405,7 +405,7 @@ function downScaleToFitSize(videoWidth, videoHeight, dstWidth, dstHeight) {
|
|
|
405
405
|
*
|
|
406
406
|
* @param video
|
|
407
407
|
*/
|
|
408
|
-
function setWebkitFullscreenHandlers(video) {
|
|
408
|
+
function setWebkitFullscreenHandlers(video, startFullScreen = true) {
|
|
409
409
|
if (video) {
|
|
410
410
|
let needRestart = false;
|
|
411
411
|
let wasFullscreen = false;
|
|
@@ -422,20 +422,22 @@ function setWebkitFullscreenHandlers(video) {
|
|
|
422
422
|
wasFullscreen = true;
|
|
423
423
|
video.play();
|
|
424
424
|
needRestart = true;
|
|
425
|
-
});
|
|
426
|
-
// Start playback in fullscreen if webkit-playsinline is set
|
|
427
|
-
video.addEventListener("playing", function () {
|
|
428
|
-
// Do not enter fullscreen again if we just left it #WCS-3860
|
|
429
|
-
if (canWebkitFullScreen(video) && !wasFullscreen) {
|
|
430
|
-
// We should catch if fullscreen mode is not available
|
|
431
|
-
try {
|
|
432
|
-
video.webkitEnterFullscreen();
|
|
433
|
-
} catch (e) {
|
|
434
|
-
console.log("Fullscreen is not allowed: " + e);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
wasFullscreen = false;
|
|
438
425
|
});
|
|
426
|
+
if (startFullScreen) {
|
|
427
|
+
// Start playback in fullscreen if webkit-playsinline is set
|
|
428
|
+
video.addEventListener("playing", function () {
|
|
429
|
+
// Do not enter fullscreen again if we just left it #WCS-3860
|
|
430
|
+
if (canWebkitFullScreen(video) && !wasFullscreen) {
|
|
431
|
+
// We should catch if fullscreen mode is not available
|
|
432
|
+
try {
|
|
433
|
+
video.webkitEnterFullscreen();
|
|
434
|
+
} catch (e) {
|
|
435
|
+
console.log("Fullscreen is not allowed: " + e);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
wasFullscreen = false;
|
|
439
|
+
});
|
|
440
|
+
}
|
|
439
441
|
} else {
|
|
440
442
|
console.log("No video tag is passed, skip webkit fullscreen handlers setup");
|
|
441
443
|
}
|
|
@@ -167,6 +167,8 @@ function playStream(session) {
|
|
|
167
167
|
console.log("Not enough bandwidth, consider using lower video resolution or bitrate. Bandwidth " + (Math.round(networkBandwidth / 1000)) + " bitrate " + (Math.round(remoteBitrate / 1000)));
|
|
168
168
|
} else if (STREAM_EVENT_TYPE.RESIZE === streamEvent.type) {
|
|
169
169
|
console.log("New video size: " + streamEvent.payload.streamerVideoWidth + "x" + streamEvent.payload.streamerVideoHeight);
|
|
170
|
+
} else if (STREAM_EVENT_TYPE.UNMUTE_REQUIRED === streamEvent.type) {
|
|
171
|
+
console.log("Stream is muted by autoplay policy, user action required to unmute");
|
|
170
172
|
}
|
|
171
173
|
});
|
|
172
174
|
playingStream.play();
|
|
@@ -3,7 +3,11 @@ const VIDEOJS_VERSION_TYPE = {
|
|
|
3
3
|
VIDEOJS7: "videojs7",
|
|
4
4
|
VIDEOJS8: "videojs8"
|
|
5
5
|
};
|
|
6
|
+
const LIVE_THRESHOLD = 5;
|
|
7
|
+
const LIVE_TOLERANCE = 5;
|
|
8
|
+
const LIVE_UI_INTERVAL = 1000;
|
|
6
9
|
let player = null;
|
|
10
|
+
let liveUITimer = null;
|
|
7
11
|
let videojsVersion = getUrlParam("version");
|
|
8
12
|
|
|
9
13
|
const loadPlayerPage = function() {
|
|
@@ -116,6 +120,10 @@ const initPage = function() {
|
|
|
116
120
|
enableItem("applyBtn");
|
|
117
121
|
setText("applyBtn", "Play");
|
|
118
122
|
setHandler("applyBtn", "click", playBtnClick);
|
|
123
|
+
setHandler("backBtn10", "click", backBtnClick);
|
|
124
|
+
setHandler("backBtn30", "click", backBtnClick);
|
|
125
|
+
setHandler("backBtnMax", "click", backBtnClick);
|
|
126
|
+
setHandler("liveBtn", "click", liveBtnClick);
|
|
119
127
|
let remoteVideo = document.getElementById('remoteVideo');
|
|
120
128
|
remoteVideo.className = "video-js vjs-default-skin";
|
|
121
129
|
player = initVideoJsPlayer(remoteVideo);
|
|
@@ -144,6 +152,21 @@ const playBtnClick = function() {
|
|
|
144
152
|
playBtnClick();
|
|
145
153
|
}
|
|
146
154
|
});
|
|
155
|
+
player.on('playing', function() {
|
|
156
|
+
console.log("playing event fired");
|
|
157
|
+
if (player.liveTracker) {
|
|
158
|
+
if (!player.liveTracker.isLive()) {
|
|
159
|
+
// A cratch to display live UI for the first subscriber
|
|
160
|
+
liveUIDisplay();
|
|
161
|
+
}
|
|
162
|
+
if (player.liveTracker.atLiveEdge()) {
|
|
163
|
+
// Unlock backward buttons when seeked to live edge
|
|
164
|
+
toggleBackButtons(true);
|
|
165
|
+
// Stop live UI startup timer
|
|
166
|
+
stopLiveUITimer();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
147
170
|
player.src({
|
|
148
171
|
src: videoSrc,
|
|
149
172
|
type: "application/vnd.apple.mpegurl"
|
|
@@ -152,36 +175,72 @@ const playBtnClick = function() {
|
|
|
152
175
|
}
|
|
153
176
|
}
|
|
154
177
|
|
|
178
|
+
const liveUIDisplay = function() {
|
|
179
|
+
stopLiveUITimer()
|
|
180
|
+
if (player && player.liveTracker) {
|
|
181
|
+
liveUITimer = setInterval(function() {
|
|
182
|
+
if (!player.liveTracker.isLive() && player.liveTracker.liveWindow() > LIVE_THRESHOLD) {
|
|
183
|
+
// Live UI is not displayed yet, seek to live edge to display
|
|
184
|
+
player.liveTracker.seekToLiveEdge();
|
|
185
|
+
}
|
|
186
|
+
}, LIVE_UI_INTERVAL)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const stopLiveUITimer = function () {
|
|
191
|
+
if (liveUITimer) {
|
|
192
|
+
clearInterval(liveUITimer);
|
|
193
|
+
liveUITimer = null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
155
196
|
|
|
156
197
|
const stopBtnClick = function() {
|
|
157
198
|
if (player != null) {
|
|
158
199
|
console.log("Stop VideoJS player");
|
|
159
|
-
|
|
200
|
+
stopLiveUITimer();
|
|
160
201
|
player.dispose();
|
|
161
202
|
}
|
|
162
203
|
onStopped();
|
|
163
204
|
}
|
|
164
205
|
|
|
206
|
+
const backBtnClick = function(event) {
|
|
207
|
+
if (player != null && player.liveTracker) {
|
|
208
|
+
toggleBackButtons(false);
|
|
209
|
+
let seekable = player.seekable();
|
|
210
|
+
let backTime = -1;
|
|
211
|
+
if (event.target.id.indexOf("10") !== -1) {
|
|
212
|
+
backTime = player.currentTime() - 10;
|
|
213
|
+
} else if (event.target.id.indexOf("30") !== -1) {
|
|
214
|
+
backTime = player.currentTime() - 30;
|
|
215
|
+
}
|
|
216
|
+
if (backTime < 0) {
|
|
217
|
+
backTime = seekable ? seekable.start(0) : player.currentTime();
|
|
218
|
+
}
|
|
219
|
+
player.currentTime(backTime);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const liveBtnClick = function() {
|
|
224
|
+
if (player != null && player.liveTracker) {
|
|
225
|
+
player.liveTracker.seekToLiveEdge();
|
|
226
|
+
toggleBackButtons(true);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
165
229
|
|
|
166
230
|
const onStarted = function() {
|
|
167
|
-
|
|
168
|
-
disableItem("playStream");
|
|
169
|
-
disableItem("key");
|
|
170
|
-
disableItem("token");
|
|
171
|
-
disableItem("player");
|
|
231
|
+
toggleInputs(false);
|
|
172
232
|
enableItem("applyBtn");
|
|
233
|
+
showItem("backward");
|
|
234
|
+
toggleBackButtons(true);
|
|
173
235
|
setText("applyBtn", "Stop");
|
|
174
236
|
setHandler("applyBtn", "click", stopBtnClick, playBtnClick);
|
|
175
237
|
}
|
|
176
238
|
|
|
177
239
|
|
|
178
240
|
const onStopped = function() {
|
|
179
|
-
|
|
180
|
-
enableItem("playStream");
|
|
181
|
-
enableItem("key");
|
|
182
|
-
enableItem("token");
|
|
183
|
-
enableItem("player");
|
|
241
|
+
toggleInputs(true);
|
|
184
242
|
enableItem("applyBtn");
|
|
243
|
+
hideItem("backward");
|
|
185
244
|
setText("applyBtn", "Play");
|
|
186
245
|
setHandler("applyBtn", "click", playBtnClick, stopBtnClick);
|
|
187
246
|
if(!document.getElementById('remoteVideo')) {
|
|
@@ -248,13 +307,21 @@ const removeHighlight = function(input) {
|
|
|
248
307
|
}
|
|
249
308
|
|
|
250
309
|
const initVideoJsPlayer = function(video) {
|
|
251
|
-
let videoJsPlayer = videojs(video
|
|
310
|
+
let videoJsPlayer = videojs(video, {
|
|
311
|
+
playsinline: true,
|
|
312
|
+
playbackRates: [0.1, 0.25, 0.5, 1, 1.5, 2],
|
|
313
|
+
liveui: true,
|
|
314
|
+
liveTracker: {
|
|
315
|
+
trackingThreshold: LIVE_THRESHOLD,
|
|
316
|
+
liveTolerance: LIVE_TOLERANCE
|
|
317
|
+
}
|
|
318
|
+
});
|
|
252
319
|
console.log("Using VideoJs " + videojs.VERSION);
|
|
253
320
|
if (Browser.isSafariWebRTC() && Browser.isiOS()) {
|
|
254
321
|
// iOS hack when using standard controls to leave fullscreen mode
|
|
255
322
|
let videoTag = getActualVideoTag();
|
|
256
323
|
if(videoTag) {
|
|
257
|
-
setWebkitFullscreenHandlers(videoTag);
|
|
324
|
+
setWebkitFullscreenHandlers(videoTag, false);
|
|
258
325
|
}
|
|
259
326
|
}
|
|
260
327
|
return videoJsPlayer;
|
|
@@ -267,3 +334,31 @@ const getActualVideoTag = function() {
|
|
|
267
334
|
}
|
|
268
335
|
return null;
|
|
269
336
|
}
|
|
337
|
+
|
|
338
|
+
const toggleBackButtons = function(enable) {
|
|
339
|
+
if (enable) {
|
|
340
|
+
enableItem("backBtn10");
|
|
341
|
+
enableItem("backBtn30");
|
|
342
|
+
enableItem("backBtnMax");
|
|
343
|
+
} else {
|
|
344
|
+
disableItem("backBtn10");
|
|
345
|
+
disableItem("backBtn30");
|
|
346
|
+
disableItem("backBtnMax");
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const toggleInputs = function(enable) {
|
|
351
|
+
if (enable) {
|
|
352
|
+
enableItem("urlServer");
|
|
353
|
+
enableItem("playStream");
|
|
354
|
+
enableItem("key");
|
|
355
|
+
enableItem("token");
|
|
356
|
+
enableItem("player");
|
|
357
|
+
} else {
|
|
358
|
+
disableItem("urlServer");
|
|
359
|
+
disableItem("playStream");
|
|
360
|
+
disableItem("key");
|
|
361
|
+
disableItem("token");
|
|
362
|
+
disableItem("player");
|
|
363
|
+
}
|
|
364
|
+
}
|
|
@@ -44,13 +44,24 @@
|
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
46
|
<div class="row" style="margin-top: 20px">
|
|
47
|
-
<div class="col-sm-
|
|
47
|
+
<div class="col-sm-4 text-left">
|
|
48
48
|
<div id="llHlsMode" style="display: none;">
|
|
49
49
|
<input id="llHlsEnabled" class="form-check-input" type="checkbox" value="">
|
|
50
50
|
<label class="form-check-label" for="llHlsEnabled">Low latency HLS</label>
|
|
51
51
|
</div>
|
|
52
52
|
</div>
|
|
53
|
-
<div class="col-sm-
|
|
53
|
+
<div class="col-sm-5">
|
|
54
|
+
<div id="backward" style="display: none;">
|
|
55
|
+
<label class="form-check-label text-right" for="backBtnMax"><< seconds</label>
|
|
56
|
+
<div class="input-group-btn">
|
|
57
|
+
<button id="backBtnMax" type="button" class="btn btn-default">Max</button>
|
|
58
|
+
<button id="backBtn30" type="button" class="btn btn-default">30</button>
|
|
59
|
+
<button id="backBtn10" type="button" class="btn btn-default">10</button>
|
|
60
|
+
<button id="liveBtn" type="button" class="btn btn-default">Live</button>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="col-sm-3 text-right">
|
|
54
65
|
<button id="applyBtn" type="button" class="btn btn-default">Play</button>
|
|
55
66
|
</div>
|
|
56
67
|
</div>
|
|
@@ -54,6 +54,14 @@
|
|
|
54
54
|
<div id="volumeControl" style="margin-top: 12px"></div>
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
|
+
<div id="unmute" class="form-group">
|
|
58
|
+
<label class="col-sm-2 control-label">Unmute</label>
|
|
59
|
+
<div class="col-sm-1">
|
|
60
|
+
<button type="button" class="btn btn-default btn-sm" id="unmuteBtn">
|
|
61
|
+
<span class="glyphicon glyphicon-volume-off"></span>
|
|
62
|
+
</button>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
57
65
|
<div id="fullScreen" class="form-group">
|
|
58
66
|
<label class="col-sm-2 control-label">Full Screen</label>
|
|
59
67
|
<div class="col-sm-1" >
|
|
@@ -44,12 +44,8 @@ function init_page() {
|
|
|
44
44
|
step: 10,
|
|
45
45
|
animate: true,
|
|
46
46
|
slide: function(event, ui) {
|
|
47
|
-
//WCS-2375. fixed autoplay in ios safari
|
|
48
|
-
if (stream.isRemoteAudioMuted()) {
|
|
49
|
-
stream.unmuteRemoteAudio();
|
|
50
|
-
}
|
|
51
47
|
currentVolumeValue = ui.value;
|
|
52
|
-
stream
|
|
48
|
+
setStreamVolume(stream, currentVolumeValue);
|
|
53
49
|
}
|
|
54
50
|
}).slider("disable");
|
|
55
51
|
onStopped();
|
|
@@ -87,6 +83,8 @@ function onStopped() {
|
|
|
87
83
|
$("#volumeControl").slider("disable");
|
|
88
84
|
$("#fullScreenBtn").prop('disabled', true);
|
|
89
85
|
$("#preloader").hide();
|
|
86
|
+
$("#unmuteBtn").off('click').click(unmuteBtnClick);
|
|
87
|
+
$("#unmute").hide();
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
function playBtnClick() {
|
|
@@ -108,6 +106,11 @@ function playBtnClick() {
|
|
|
108
106
|
}
|
|
109
107
|
}
|
|
110
108
|
|
|
109
|
+
function unmuteBtnClick() {
|
|
110
|
+
setStreamVolume(stream, currentVolumeValue)
|
|
111
|
+
$("#volumeControl").slider('value', currentVolumeValue);
|
|
112
|
+
}
|
|
113
|
+
|
|
111
114
|
function start() {
|
|
112
115
|
var url = $('#url').val();
|
|
113
116
|
//check if we already have session
|
|
@@ -200,6 +203,14 @@ function playStream(session) {
|
|
|
200
203
|
video.addEventListener("playing", function () {
|
|
201
204
|
$("#preloader").hide();
|
|
202
205
|
});
|
|
206
|
+
// Hide unmute button
|
|
207
|
+
video.addEventListener("volumechange", function () {
|
|
208
|
+
if (video.muted) {
|
|
209
|
+
$("#unmute").show();
|
|
210
|
+
} else {
|
|
211
|
+
$("#unmute").hide();
|
|
212
|
+
}
|
|
213
|
+
});
|
|
203
214
|
}
|
|
204
215
|
}).on(STREAM_STATUS.PLAYING, function (stream) {
|
|
205
216
|
// Android Firefox may pause stream playback via MSE even if video element is muted
|
|
@@ -225,8 +236,10 @@ function playStream(session) {
|
|
|
225
236
|
console.log("Not enough bandwidth, consider using lower video resolution or bitrate. Bandwidth " + (Math.round(networkBandwidth / 1000)) + " bitrate " + (Math.round(remoteBitrate / 1000)));
|
|
226
237
|
} else if (STREAM_EVENT_TYPE.RESIZE === streamEvent.type) {
|
|
227
238
|
console.log("New video size: " + streamEvent.payload.streamerVideoWidth + "x" + streamEvent.payload.streamerVideoHeight);
|
|
239
|
+
} else if (STREAM_EVENT_TYPE.UNMUTE_REQUIRED === streamEvent.type) {
|
|
240
|
+
console.log("Stream is muted by autoplay policy, user action required to unmute");
|
|
241
|
+
$("#unmute").show();
|
|
228
242
|
}
|
|
229
|
-
|
|
230
243
|
});
|
|
231
244
|
stream.play();
|
|
232
245
|
}
|
|
@@ -249,6 +262,15 @@ function setStatus(status, stream) {
|
|
|
249
262
|
}
|
|
250
263
|
}
|
|
251
264
|
|
|
265
|
+
function setStreamVolume(stream, currentVolumeValue) {
|
|
266
|
+
if (stream) {
|
|
267
|
+
if (stream.isRemoteAudioMuted()) {
|
|
268
|
+
stream.unmuteRemoteAudio();
|
|
269
|
+
}
|
|
270
|
+
stream.setVolume(currentVolumeValue);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
252
274
|
function validateForm() {
|
|
253
275
|
var valid = true;
|
|
254
276
|
$('#form :text').each(function(){
|