@antmedia/web_player 2.11.2 → 2.11.11
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/.github/workflows/publish-release.yml +20 -3
- package/.github/workflows/publish-snapshot.yml +1 -1
- package/dist/browser/web_player.js +176 -117
- package/dist/es/index.d.ts +19 -2
- package/dist/es/{plugin-50e1316e.js → plugin-06260ef3.js} +1 -1
- package/dist/es/{video.es-be70c095.js → video.es-0951ae41.js} +41 -36
- package/dist/es/{videojs-webrtc-plugin-7054aa21.js → videojs-webrtc-plugin-7e293bd2.js} +1 -1
- package/dist/es/{videojs-webrtc-plugin.es-777bf41a.js → videojs-webrtc-plugin.es-0f1490f6.js} +7 -13
- package/dist/es/web_player.js +180 -121
- package/dist/index.d.ts +19 -2
- package/dist/{plugin-bec9dc4a.js → plugin-1270024e.js} +9 -9
- package/dist/{video.es-df9af03d.js → video.es-474303e7.js} +43 -36
- package/dist/{videojs-webrtc-plugin-3becde8c.js → videojs-webrtc-plugin-5dd8808d.js} +1 -1
- package/dist/{videojs-webrtc-plugin.es-ee6d0333.js → videojs-webrtc-plugin.es-812e1a77.js} +28 -34
- package/dist/web_player.js +180 -121
- package/package.json +2 -2
- package/src/web_player.js +197 -136
- package/test/embedded-player.test.js +136 -28
- package/dist/es/videojs-webrtc-plugin-f56e1f9e.js +0 -3
- package/dist/es/videojs-webrtc-plugin.es-2a0dfc29.js +0 -40977
- package/dist/es/videojs-webrtc-plugin.es-333788d9.js +0 -7673
- package/dist/es/videojs-webrtc-plugin.es-9544f6e0.js +0 -7699
- package/dist/videojs-webrtc-plugin-77a9860b.js +0 -5
- package/dist/videojs-webrtc-plugin.es-0787d11e.js +0 -7701
- package/dist/videojs-webrtc-plugin.es-493b195e.js +0 -40979
- package/dist/videojs-webrtc-plugin.es-8f4ea4e4.js +0 -7675
- package/visual.code-workspace +0 -11
package/src/web_player.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getUrlParameter } from "@antmedia/webrtc_adaptor/dist/fetch.stream";
|
|
2
2
|
import { Logger } from "@antmedia/webrtc_adaptor/dist/loglevel.min";
|
|
3
|
-
import
|
|
3
|
+
import { UpArrow } from "./icons/images";
|
|
4
4
|
|
|
5
5
|
export const STATIC_VIDEO_HTML = "<video id='video-player' class='video-js vjs-default-skin vjs-big-play-centered' controls playsinline></video>";
|
|
6
6
|
|
|
@@ -14,6 +14,8 @@ const PTZ_ZOOM_TEXT_BUTTON_ID = "zoom-text";
|
|
|
14
14
|
|
|
15
15
|
export class WebPlayer {
|
|
16
16
|
|
|
17
|
+
static PLAYER_EVENTS = ['abort','canplay','canplaythrough','durationchange','emptied','ended','error','loadeddata','loadedmetadata','loadstart','pause','play','playing','progress','ratechange','seeked','seeking','stalled','suspend','timeupdate','volumechange','waiting','enterpictureinpicture','leavepictureinpicture','fullscreenchange','resize','audioonlymodechange','audiopostermodechange','controlsdisabled','controlsenabled','debugon','debugoff','disablepictureinpicturechanged','dispose','enterFullWindow','error','exitFullWindow','firstplay','fullscreenerror','languagechange','loadedmetadata','loadstart','playerreset','playerresize','posterchange','ready','textdata','useractive','userinactive','usingcustomcontrols','usingnativecontrols'];
|
|
18
|
+
|
|
17
19
|
static DEFAULT_PLAY_ORDER = ["webrtc", "hls"];
|
|
18
20
|
|
|
19
21
|
static DEFAULT_PLAY_TYPE = ["mp4", "webm"];
|
|
@@ -95,6 +97,12 @@ export class WebPlayer {
|
|
|
95
97
|
*/
|
|
96
98
|
mute = false;
|
|
97
99
|
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* controls: Toggles the visibility of player controls.
|
|
103
|
+
*/
|
|
104
|
+
controls = true;
|
|
105
|
+
|
|
98
106
|
/**
|
|
99
107
|
* Force the Player to play with audio Auto Play might not work.
|
|
100
108
|
*/
|
|
@@ -213,6 +221,17 @@ export class WebPlayer {
|
|
|
213
221
|
*/
|
|
214
222
|
isIPCamera;
|
|
215
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Stream id of backup stream.
|
|
226
|
+
*/
|
|
227
|
+
backupStreamId;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* activeStreamId: is the stream id that is being played currently
|
|
231
|
+
* It can be streamID or backupStreamId
|
|
232
|
+
*/
|
|
233
|
+
activeStreamId;
|
|
234
|
+
|
|
216
235
|
|
|
217
236
|
constructor(configOrWindow, containerElement, placeHolderElement) {
|
|
218
237
|
|
|
@@ -234,6 +253,9 @@ export class WebPlayer {
|
|
|
234
253
|
WebPlayer.LL_HLS_Folder = "ll-hls";
|
|
235
254
|
|
|
236
255
|
WebPlayer.VIDEO_PLAYER_ID = "video-player";
|
|
256
|
+
|
|
257
|
+
WebPlayer.PLAYER_EVENTS = ['abort','canplay','canplaythrough','durationchange','emptied','ended','error','loadeddata','loadedmetadata','loadstart','pause','play','playing','progress','ratechange','seeked','seeking','stalled','suspend','timeupdate','volumechange','waiting','enterpictureinpicture','leavepictureinpicture','fullscreenchange','resize','audioonlymodechange','audiopostermodechange','controlsdisabled','controlsenabled','debugon','debugoff','disablepictureinpicturechanged','dispose','enterFullWindow','error','exitFullWindow','firstplay','fullscreenerror','languagechange','loadedmetadata','loadstart','playerreset','playerresize','posterchange','ready','textdata','useractive','userinactive','usingcustomcontrols','usingnativecontrols'];
|
|
258
|
+
|
|
237
259
|
|
|
238
260
|
// Initialize default values
|
|
239
261
|
this.setDefaults();
|
|
@@ -271,6 +293,8 @@ export class WebPlayer {
|
|
|
271
293
|
alert(message);
|
|
272
294
|
throw new Error(message);
|
|
273
295
|
}
|
|
296
|
+
//set the active stream id as stream id
|
|
297
|
+
this.activeStreamId = this.streamId;
|
|
274
298
|
|
|
275
299
|
if (!this.httpBaseURL)
|
|
276
300
|
{
|
|
@@ -294,22 +318,21 @@ export class WebPlayer {
|
|
|
294
318
|
path += appName
|
|
295
319
|
|
|
296
320
|
this.httpBaseURL = this.window.location.protocol + "//" + path;
|
|
297
|
-
this.
|
|
321
|
+
this.websocketBaseURL = "ws://" + path;
|
|
298
322
|
|
|
299
323
|
if (this.window.location.protocol.startsWith("https")) {
|
|
300
|
-
this.
|
|
324
|
+
this.websocketBaseURL = this.websocketBaseURL.replace("ws", "wss");
|
|
301
325
|
}
|
|
302
326
|
|
|
303
327
|
}
|
|
304
|
-
else if (!this.
|
|
328
|
+
else if (!this.websocketBaseURL)
|
|
305
329
|
{
|
|
306
330
|
//this is the case where web player gets inputs from config object
|
|
307
331
|
if (!this.httpBaseURL.endsWith("/")) {
|
|
308
332
|
this.httpBaseURL += "/";
|
|
309
333
|
}
|
|
310
334
|
|
|
311
|
-
this.
|
|
312
|
-
this.websocketURL += this.streamId + ".webrtc";
|
|
335
|
+
this.websocketBaseURL = this.httpBaseURL.replace("http", "ws");
|
|
313
336
|
}
|
|
314
337
|
|
|
315
338
|
this.dom = this.window.document;
|
|
@@ -382,7 +405,7 @@ export class WebPlayer {
|
|
|
382
405
|
this.aScene = null;
|
|
383
406
|
this.playerListener = null;
|
|
384
407
|
this.webRTCDataListener = null;
|
|
385
|
-
this.
|
|
408
|
+
this.websocketBaseURL = null;
|
|
386
409
|
this.httpBaseURL = null;
|
|
387
410
|
this.videoHTMLContent = STATIC_VIDEO_HTML;
|
|
388
411
|
this.videoPlayerId = "video-player";
|
|
@@ -398,6 +421,8 @@ export class WebPlayer {
|
|
|
398
421
|
this.ptzMovement = "relative";
|
|
399
422
|
this.restAPIPromise = null;
|
|
400
423
|
this.isIPCamera = false;
|
|
424
|
+
this.playerEvents = WebPlayer.PLAYER_EVENTS
|
|
425
|
+
this.backupStreamId = null;
|
|
401
426
|
}
|
|
402
427
|
|
|
403
428
|
initializeFromUrlParams() {
|
|
@@ -456,6 +481,8 @@ export class WebPlayer {
|
|
|
456
481
|
|
|
457
482
|
this.ptzMovement = getUrlParameter("ptzMovement", this.window.location.search) || this.ptzMovement;
|
|
458
483
|
|
|
484
|
+
this.backupStreamId = getUrlParameter("backupStreamId", this.window.location.search) || this.backupStreamId;
|
|
485
|
+
|
|
459
486
|
}
|
|
460
487
|
|
|
461
488
|
loadWebRTCComponents() {
|
|
@@ -633,7 +660,7 @@ export class WebPlayer {
|
|
|
633
660
|
limitRenditionByPlayerDimensions: false
|
|
634
661
|
}
|
|
635
662
|
},
|
|
636
|
-
controls:
|
|
663
|
+
controls: this.controls,
|
|
637
664
|
class: 'video-js vjs-default-skin vjs-big-play-centered',
|
|
638
665
|
muted: this.mute,
|
|
639
666
|
preload: "auto",
|
|
@@ -641,22 +668,6 @@ export class WebPlayer {
|
|
|
641
668
|
|
|
642
669
|
});
|
|
643
670
|
|
|
644
|
-
this.videojsPlayer.on('error', (e) => {
|
|
645
|
-
Logger.warn("There is an error in playback: ", e);
|
|
646
|
-
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
647
|
-
if (!this.errorCalled) {
|
|
648
|
-
this.errorCalled = true;
|
|
649
|
-
setTimeout(() => {
|
|
650
|
-
this.tryNextTech();
|
|
651
|
-
this.errorCalled = false;
|
|
652
|
-
}, 2500)
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
if (this.playerListener != null) {
|
|
656
|
-
this.playerListener("error", e);
|
|
657
|
-
}
|
|
658
|
-
});
|
|
659
|
-
|
|
660
671
|
//webrtc specific events
|
|
661
672
|
if (extension == "webrtc") {
|
|
662
673
|
|
|
@@ -687,7 +698,7 @@ export class WebPlayer {
|
|
|
687
698
|
* If getting codec incompatible or remote description error, it will redirect HLS player.
|
|
688
699
|
*/
|
|
689
700
|
Logger.warn("notSetRemoteDescription error. Redirecting to HLS player.");
|
|
690
|
-
this.playIfExists("hls");
|
|
701
|
+
this.playIfExists("hls", this.activeStreamId);
|
|
691
702
|
}
|
|
692
703
|
if (this.playerListener != null) {
|
|
693
704
|
this.playerListener("webrtc-error", errors);
|
|
@@ -762,82 +773,7 @@ export class WebPlayer {
|
|
|
762
773
|
this.makeVideoJSVisibleWhenReady();
|
|
763
774
|
}
|
|
764
775
|
|
|
765
|
-
this.
|
|
766
|
-
//reinit to play after it ends
|
|
767
|
-
Logger.warn("stream is ended")
|
|
768
|
-
this.setPlayerVisible(false);
|
|
769
|
-
//for webrtc, this event can be called by two reasons
|
|
770
|
-
//1. ice connection is not established, it means that there is a networking issug
|
|
771
|
-
//2. stream is ended
|
|
772
|
-
if (this.currentPlayType != "vod") {
|
|
773
|
-
//if it's vod, it means that stream is ended and no need to replay
|
|
774
|
-
|
|
775
|
-
if (this.iceConnected) {
|
|
776
|
-
//if iceConnected is true, it means that stream is really ended for webrtc
|
|
777
|
-
|
|
778
|
-
//initialize to play again if the publishing starts again
|
|
779
|
-
this.playIfExists(this.playOrder[0]);
|
|
780
|
-
}
|
|
781
|
-
else if (this.currentPlayType == "hls") {
|
|
782
|
-
//if it's hls, it means that stream is ended
|
|
783
|
-
|
|
784
|
-
this.setPlayerVisible(false);
|
|
785
|
-
if (this.playOrder[0] = "hls")
|
|
786
|
-
{
|
|
787
|
-
//do not play again if it's hls because it play last seconds again, let the server clear it
|
|
788
|
-
setTimeout(() => {
|
|
789
|
-
this.playIfExists(this.playOrder[0]);
|
|
790
|
-
}, 10000);
|
|
791
|
-
}
|
|
792
|
-
else
|
|
793
|
-
{
|
|
794
|
-
this.playIfExists(this.playOrder[0]);
|
|
795
|
-
}
|
|
796
|
-
//TODO: what if the stream is hls vod then it always re-play
|
|
797
|
-
}
|
|
798
|
-
else {
|
|
799
|
-
//if iceConnected is false, it means that there is a networking issue for webrtc
|
|
800
|
-
this.tryNextTech();
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
if (this.playerListener != null) {
|
|
804
|
-
this.playerListener("ended");
|
|
805
|
-
}
|
|
806
|
-
});
|
|
807
|
-
|
|
808
|
-
//webrtc plugin sends play event. On the other hand, webrtc plugin sends ready event for every scenario.
|
|
809
|
-
//so no need to trust ready event for webrt play
|
|
810
|
-
this.videojsPlayer.on("play", () => {
|
|
811
|
-
this.setPlayerVisible(true);
|
|
812
|
-
if (this.playerListener != null) {
|
|
813
|
-
this.playerListener("play");
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
if(this.restJwt){
|
|
817
|
-
this.isIpCameraBroadcast();
|
|
818
|
-
}
|
|
819
|
-
else if (this.isIPCamera){
|
|
820
|
-
this.injectPtzElements();
|
|
821
|
-
}
|
|
822
|
-
});
|
|
823
|
-
|
|
824
|
-
this.videojsPlayer.on("playing", () => {
|
|
825
|
-
if (this.playerListener != null) {
|
|
826
|
-
this.playerListener("playing");
|
|
827
|
-
}
|
|
828
|
-
});
|
|
829
|
-
|
|
830
|
-
this.videojsPlayer.on("timeupdate", () => {
|
|
831
|
-
if (this.playerListener != null) {
|
|
832
|
-
this.playerListener("timeupdate");
|
|
833
|
-
}
|
|
834
|
-
});
|
|
835
|
-
|
|
836
|
-
this.videojsPlayer.on("pause", () => {
|
|
837
|
-
if (this.playerListener != null) {
|
|
838
|
-
this.playerListener("pause");
|
|
839
|
-
}
|
|
840
|
-
});
|
|
776
|
+
this.listenPlayerEvents()
|
|
841
777
|
|
|
842
778
|
this.iceConnected = false;
|
|
843
779
|
|
|
@@ -867,6 +803,111 @@ export class WebPlayer {
|
|
|
867
803
|
}
|
|
868
804
|
}
|
|
869
805
|
|
|
806
|
+
listenPlayerEvents() {
|
|
807
|
+
this.playerEvents.forEach(event => {
|
|
808
|
+
this.videojsPlayer.on(event, (eventData) => {
|
|
809
|
+
switch (event) {
|
|
810
|
+
case 'play':
|
|
811
|
+
this.setPlayerVisible(true);
|
|
812
|
+
if (this.playerListener != null) {
|
|
813
|
+
this.playerListener("play");
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if(this.restJwt){
|
|
817
|
+
this.isIpCameraBroadcast();
|
|
818
|
+
}
|
|
819
|
+
else if (this.isIPCamera){
|
|
820
|
+
this.injectPtzElements();
|
|
821
|
+
}
|
|
822
|
+
break;
|
|
823
|
+
case 'ended':
|
|
824
|
+
//reinit to play after it ends
|
|
825
|
+
Logger.warn("stream is ended")
|
|
826
|
+
this.setPlayerVisible(false);
|
|
827
|
+
//for webrtc, this event can be called by two reasons
|
|
828
|
+
//1. ice connection is not established, it means that there is a networking issug
|
|
829
|
+
//2. stream is ended
|
|
830
|
+
if (this.currentPlayType != "vod") {
|
|
831
|
+
//if it's vod, it means that stream is ended and no need to replay
|
|
832
|
+
|
|
833
|
+
if (this.iceConnected) {
|
|
834
|
+
//if iceConnected is true, it means that stream is really ended for webrtc
|
|
835
|
+
|
|
836
|
+
//initialize to play again if the publishing starts again
|
|
837
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
838
|
+
}
|
|
839
|
+
else if (this.currentPlayType == "hls") {
|
|
840
|
+
//if it's hls, it means that stream is ended
|
|
841
|
+
|
|
842
|
+
this.setPlayerVisible(false);
|
|
843
|
+
if (this.playOrder[0] = "hls")
|
|
844
|
+
{
|
|
845
|
+
//do not play again if it's hls because it play last seconds again, let the server clear it
|
|
846
|
+
setTimeout(() => {
|
|
847
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
848
|
+
}, 10000);
|
|
849
|
+
}
|
|
850
|
+
else
|
|
851
|
+
{
|
|
852
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
853
|
+
}
|
|
854
|
+
//TODO: what if the stream is hls vod then it always re-play
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
//if iceConnected is false, it means that there is a networking issue for webrtc
|
|
858
|
+
this.tryNextTech();
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
if (this.playerListener != null) {
|
|
862
|
+
this.playerListener(event);
|
|
863
|
+
}
|
|
864
|
+
break;
|
|
865
|
+
case 'timeupdate':
|
|
866
|
+
if (this.playerListener != null) {
|
|
867
|
+
this.playerListener(event, eventData, { currentTime: this.videojsPlayer.currentTime() });
|
|
868
|
+
}
|
|
869
|
+
break;
|
|
870
|
+
case 'progress':
|
|
871
|
+
if (this.playerListener != null) {
|
|
872
|
+
this.playerListener(event, eventData, { bufferedPercent: this.videojsPlayer.bufferedPercent() });
|
|
873
|
+
}
|
|
874
|
+
break;
|
|
875
|
+
case 'volumechange':
|
|
876
|
+
if (this.playerListener != null) {
|
|
877
|
+
this.playerListener(event, eventData, {
|
|
878
|
+
volume: this.videojsPlayer.volume(),
|
|
879
|
+
muted: this.videojsPlayer.muted()
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
break;
|
|
883
|
+
case 'ratechange':
|
|
884
|
+
if (this.playerListener != null) {
|
|
885
|
+
this.playerListener(event, eventData, { playbackRate: this.videojsPlayer.playbackRate() });
|
|
886
|
+
}
|
|
887
|
+
break;
|
|
888
|
+
case 'error':
|
|
889
|
+
Logger.warn("There is an error in playback: ", eventData);
|
|
890
|
+
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
891
|
+
if (!this.errorCalled) {
|
|
892
|
+
this.errorCalled = true;
|
|
893
|
+
setTimeout(() => {
|
|
894
|
+
this.tryNextTech();
|
|
895
|
+
this.errorCalled = false;
|
|
896
|
+
}, 2500)
|
|
897
|
+
}
|
|
898
|
+
if(this.playerListener != null){
|
|
899
|
+
this.playerListener("error", eventData)
|
|
900
|
+
}
|
|
901
|
+
break;
|
|
902
|
+
default:
|
|
903
|
+
if (this.playerListener != null) {
|
|
904
|
+
this.playerListener(event, eventData);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
});
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
|
|
870
911
|
listenForID3MetaData() {
|
|
871
912
|
this.videojsPlayer.textTracks().on('addtrack', e => {
|
|
872
913
|
const metadataTrack = Array.from(this.videojsPlayer.textTracks()).find(t => t.label === 'Timed Metadata');
|
|
@@ -969,17 +1010,30 @@ export class WebPlayer {
|
|
|
969
1010
|
this.destroyDashPlayer();
|
|
970
1011
|
this.destroyVideoJSPlayer();
|
|
971
1012
|
this.setPlayerVisible(false);
|
|
972
|
-
var index = this.playOrder.indexOf(this.currentPlayType);
|
|
973
|
-
if (index == -1 || index == (this.playOrder.length - 1)) {
|
|
974
|
-
index = 0;
|
|
975
|
-
}
|
|
976
|
-
else {
|
|
977
|
-
index++;
|
|
978
|
-
}
|
|
979
1013
|
|
|
1014
|
+
//before changing play type, let's check if there is any backup stream
|
|
1015
|
+
var playTypeIndex = this.playOrder.indexOf(this.currentPlayType);
|
|
1016
|
+
if (this.activeStreamId == this.streamId && this.backupStreamId != null)
|
|
1017
|
+
{
|
|
1018
|
+
//update active stream id to backup stream id
|
|
1019
|
+
this.activeStreamId = this.backupStreamId;
|
|
1020
|
+
//don't update playTypeIndex because we're trying backup stream with the same play type
|
|
1021
|
+
}
|
|
1022
|
+
else
|
|
1023
|
+
{
|
|
1024
|
+
//reset the activeStreamId back to streamId
|
|
1025
|
+
this.activeStreamId = this.streamId;
|
|
1026
|
+
//update the playTypeIndex to try next tech
|
|
1027
|
+
if (playTypeIndex == -1 || playTypeIndex == (this.playOrder.length - 1)) {
|
|
1028
|
+
playTypeIndex = 0;
|
|
1029
|
+
}
|
|
1030
|
+
else {
|
|
1031
|
+
playTypeIndex++;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
980
1034
|
this.tryNextTechTimer = setTimeout(() => {
|
|
981
1035
|
this.tryNextTechTimer = -1;
|
|
982
|
-
this.playIfExists(this.playOrder[
|
|
1036
|
+
this.playIfExists(this.playOrder[playTypeIndex], this.activeStreamId);
|
|
983
1037
|
}, 3000);
|
|
984
1038
|
}
|
|
985
1039
|
else
|
|
@@ -1063,11 +1117,11 @@ export class WebPlayer {
|
|
|
1063
1117
|
{
|
|
1064
1118
|
//do not play again if it's dash because it play last seconds again, let the server clear it
|
|
1065
1119
|
setTimeout(() => {
|
|
1066
|
-
this.playIfExists(this.playOrder[0]);
|
|
1120
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1067
1121
|
}, 10000);
|
|
1068
1122
|
}
|
|
1069
1123
|
else {
|
|
1070
|
-
this.playIfExists(this.playOrder[0]);
|
|
1124
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1071
1125
|
}
|
|
1072
1126
|
if (this.playerListener != null) {
|
|
1073
1127
|
this.playerListener("ended");
|
|
@@ -1163,7 +1217,7 @@ export class WebPlayer {
|
|
|
1163
1217
|
* play the stream with the given tech
|
|
1164
1218
|
* @param {string} tech
|
|
1165
1219
|
*/
|
|
1166
|
-
async playIfExists(tech) {
|
|
1220
|
+
async playIfExists(tech, streamIdToPlay) {
|
|
1167
1221
|
this.currentPlayType = tech;
|
|
1168
1222
|
this.destroyVideoJSPlayer();
|
|
1169
1223
|
this.destroyDashPlayer();
|
|
@@ -1172,78 +1226,78 @@ export class WebPlayer {
|
|
|
1172
1226
|
this.containerElement.innerHTML = this.videoHTMLContent;
|
|
1173
1227
|
|
|
1174
1228
|
|
|
1175
|
-
Logger.warn("Try to play the stream " +
|
|
1229
|
+
Logger.warn("Try to play the stream " + streamIdToPlay + " with " + this.currentPlayType);
|
|
1176
1230
|
switch (this.currentPlayType) {
|
|
1177
1231
|
case "hls":
|
|
1178
1232
|
//TODO: Test case for hls
|
|
1179
1233
|
//1. Play stream with adaptive m3u8 for live and VoD
|
|
1180
1234
|
//2. Play stream with m3u8 for live and VoD
|
|
1181
1235
|
//3. if files are not available check nextTech is being called
|
|
1182
|
-
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1236
|
+
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, WebPlayer.HLS_EXTENSION).then((streamPath) => {
|
|
1183
1237
|
|
|
1184
1238
|
this.playWithVideoJS(streamPath, WebPlayer.HLS_EXTENSION);
|
|
1185
1239
|
Logger.warn("incoming stream path: " + streamPath);
|
|
1186
1240
|
|
|
1187
1241
|
}).catch((error) => {
|
|
1188
1242
|
|
|
1189
|
-
Logger.warn("HLS stream resource not available for stream:" +
|
|
1243
|
+
Logger.warn("HLS stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1190
1244
|
this.tryNextTech();
|
|
1191
1245
|
});
|
|
1192
1246
|
case "ll-hls":
|
|
1193
|
-
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER + "/" + WebPlayer.LL_HLS_FOLDER,
|
|
1247
|
+
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER + "/" + WebPlayer.LL_HLS_FOLDER, streamIdToPlay, WebPlayer.HLS_EXTENSION).then((streamPath) => {
|
|
1194
1248
|
|
|
1195
1249
|
this.playWithVideoJS(streamPath, WebPlayer.HLS_EXTENSION);
|
|
1196
1250
|
Logger.warn("incoming stream path: " + streamPath);
|
|
1197
1251
|
|
|
1198
1252
|
}).catch((error) => {
|
|
1199
1253
|
|
|
1200
|
-
Logger.warn("LL-HLS stream resource not available for stream:" +
|
|
1254
|
+
Logger.warn("LL-HLS stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1201
1255
|
this.tryNextTech();
|
|
1202
1256
|
});
|
|
1203
1257
|
case "dash":
|
|
1204
|
-
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1258
|
+
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay + "/" + streamIdToPlay, WebPlayer.DASH_EXTENSION).then((streamPath) => {
|
|
1205
1259
|
this.playViaDash(streamPath);
|
|
1206
1260
|
}).catch((error) => {
|
|
1207
|
-
Logger.warn("DASH stream resource not available for stream:" +
|
|
1261
|
+
Logger.warn("DASH stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1208
1262
|
this.tryNextTech();
|
|
1209
1263
|
});
|
|
1210
1264
|
|
|
1211
1265
|
case "webrtc":
|
|
1212
1266
|
|
|
1213
1267
|
|
|
1214
|
-
return this.playWithVideoJS(this.addSecurityParams(this.
|
|
1268
|
+
return this.playWithVideoJS(this.addSecurityParams(this.getWebsocketURLForStream(streamIdToPlay)), WebPlayer.WEBRTC_EXTENSION);
|
|
1215
1269
|
case "vod":
|
|
1216
1270
|
//TODO: Test case for vod
|
|
1217
1271
|
//1. Play stream with mp4 for VoD
|
|
1218
1272
|
//2. Play stream with webm for VoD
|
|
1219
1273
|
//3. Play stream with playOrder type
|
|
1220
1274
|
|
|
1221
|
-
var lastIndexOfDot =
|
|
1275
|
+
var lastIndexOfDot = streamIdToPlay.lastIndexOf(".");
|
|
1222
1276
|
var extension;
|
|
1223
1277
|
if (lastIndexOfDot != -1)
|
|
1224
1278
|
{
|
|
1225
1279
|
//if there is a dot in the streamId, it means that this is extension, use it. make the extension empty
|
|
1226
1280
|
this.playType[0] = "";
|
|
1227
|
-
extension =
|
|
1281
|
+
extension = streamIdToPlay.substring(lastIndexOfDot + 1);
|
|
1228
1282
|
}
|
|
1229
1283
|
else {
|
|
1230
1284
|
//we need to give extension to playWithVideoJS
|
|
1231
1285
|
extension = this.playType[0];
|
|
1232
1286
|
}
|
|
1233
1287
|
|
|
1234
|
-
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1288
|
+
return this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, this.playType[0]).then((streamPath) => {
|
|
1235
1289
|
|
|
1236
1290
|
//we need to give extension to playWithVideoJS
|
|
1237
1291
|
this.playWithVideoJS(streamPath, extension);
|
|
1238
1292
|
|
|
1239
1293
|
}).catch((error) => {
|
|
1240
|
-
Logger.warn("VOD stream resource not available for stream:" +
|
|
1294
|
+
Logger.warn("VOD stream resource not available for stream:" + streamIdToPlay + " and play type " + this.playType[0] + ". Error is " + error);
|
|
1241
1295
|
if (this.playType.length > 1) {
|
|
1242
1296
|
Logger.warn("Try next play type which is " + this.playType[1] + ".")
|
|
1243
|
-
this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1297
|
+
this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, this.playType[1]).then((streamPath) => {
|
|
1244
1298
|
this.playWithVideoJS(streamPath, this.playType[1]);
|
|
1245
1299
|
}).catch((error) => {
|
|
1246
|
-
Logger.warn("VOD stream resource not available for stream:" +
|
|
1300
|
+
Logger.warn("VOD stream resource not available for stream:" + streamIdToPlay + " and play type error is " + error);
|
|
1247
1301
|
});
|
|
1248
1302
|
}
|
|
1249
1303
|
|
|
@@ -1251,6 +1305,11 @@ export class WebPlayer {
|
|
|
1251
1305
|
}
|
|
1252
1306
|
}
|
|
1253
1307
|
|
|
1308
|
+
|
|
1309
|
+
getWebsocketURLForStream(streamIdToPlay) {
|
|
1310
|
+
return this.websocketBaseURL + streamIdToPlay + ".webrtc";
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1254
1313
|
/**
|
|
1255
1314
|
*
|
|
1256
1315
|
* @returns {String} query string for security
|
|
@@ -1273,11 +1332,13 @@ export class WebPlayer {
|
|
|
1273
1332
|
* play the stream with videojs player or dash player
|
|
1274
1333
|
*/
|
|
1275
1334
|
play() {
|
|
1276
|
-
if
|
|
1335
|
+
//if there is a request to play, try original stream first
|
|
1336
|
+
this.activeStreamId = this.streamId;
|
|
1337
|
+
if (this.activeStreamId.startsWith(WebPlayer.STREAMS_FOLDER)) {
|
|
1277
1338
|
|
|
1278
1339
|
//start videojs player because it directly try to play stream from streams folder
|
|
1279
|
-
var lastIndexOfDot = this.
|
|
1280
|
-
var extension = this.
|
|
1340
|
+
var lastIndexOfDot = this.activeStreamId.lastIndexOf(".");
|
|
1341
|
+
var extension = this.activeStreamId.substring(lastIndexOfDot + 1);
|
|
1281
1342
|
|
|
1282
1343
|
this.playOrder= ["vod"];
|
|
1283
1344
|
this.currentPlayType = this.playOrder[0];
|
|
@@ -1289,14 +1350,14 @@ export class WebPlayer {
|
|
|
1289
1350
|
|
|
1290
1351
|
if (extension == WebPlayer.DASH_EXTENSION)
|
|
1291
1352
|
{
|
|
1292
|
-
this.playViaDash(this.httpBaseURL + this.addSecurityParams(this.
|
|
1353
|
+
this.playViaDash(this.httpBaseURL + this.addSecurityParams(this.activeStreamId), extension);
|
|
1293
1354
|
}
|
|
1294
1355
|
else {
|
|
1295
|
-
this.playWithVideoJS(this.httpBaseURL + this.addSecurityParams(this.
|
|
1356
|
+
this.playWithVideoJS(this.httpBaseURL + this.addSecurityParams(this.activeStreamId), extension);
|
|
1296
1357
|
}
|
|
1297
1358
|
}
|
|
1298
1359
|
else {
|
|
1299
|
-
this.playIfExists(this.playOrder[0]);
|
|
1360
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1300
1361
|
}
|
|
1301
1362
|
}
|
|
1302
1363
|
|
|
@@ -1391,11 +1452,11 @@ export class WebPlayer {
|
|
|
1391
1452
|
<span id="zoom-in-button" style="color: #bc1b22; font-size: 50px; font-weight: bold; cursor: pointer; margin-left: 5px; user-select: none;">+</span>
|
|
1392
1453
|
</div>
|
|
1393
1454
|
<div id="direction-arrow-container" class="direction-arrow-container">
|
|
1394
|
-
<img id="up-button" style="position: absolute; width: 50px; cursor: pointer; height: 50px; left: 50%; transform: translateX(-50%);" src="`+ UpArrow +`"/>
|
|
1455
|
+
<img id="up-button" style="position: absolute; width: 50px; cursor: pointer; height: 50px; left: 50%; transform: translateX(-50%);" src="`+ UpArrow.src +`"/>
|
|
1395
1456
|
|
|
1396
|
-
<img id="left-button" style="position: absolute; left: 0px; width: 50px; height: 50px; cursor: pointer; top: 50%; transform: translateY(-50%) rotate(-90deg);" src="`+UpArrow+`"/>
|
|
1397
|
-
<img id="right-button" style="position: absolute; right:0px; top: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateY(-50%) rotate(90deg);" src="`+UpArrow+`"/>
|
|
1398
|
-
<img id="down-button" style="position: absolute; bottom:0px;left: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateX(-50%) rotate(180deg);" src="`+UpArrow+`"/>
|
|
1457
|
+
<img id="left-button" style="position: absolute; left: 0px; width: 50px; height: 50px; cursor: pointer; top: 50%; transform: translateY(-50%) rotate(-90deg);" src="`+UpArrow.src+`"/>
|
|
1458
|
+
<img id="right-button" style="position: absolute; right:0px; top: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateY(-50%) rotate(90deg);" src="`+UpArrow.src+`"/>
|
|
1459
|
+
<img id="down-button" style="position: absolute; bottom:0px;left: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateX(-50%) rotate(180deg);" src="`+UpArrow.src+`"/>
|
|
1399
1460
|
|
|
1400
1461
|
</div>
|
|
1401
1462
|
|