@antmedia/web_player 2.11.10 → 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-snapshot.yml +1 -1
- package/dist/browser/web_player.js +176 -117
- package/dist/es/index.d.ts +19 -2
- package/dist/es/{videojs-webrtc-plugin-f56e1f9e.js → videojs-webrtc-plugin-7e293bd2.js} +1 -1
- package/dist/es/{videojs-webrtc-plugin.es-a1f9d342.js → videojs-webrtc-plugin.es-0f1490f6.js} +6 -2
- package/dist/es/web_player.js +178 -119
- package/dist/index.d.ts +19 -2
- package/dist/{videojs-webrtc-plugin-77a9860b.js → videojs-webrtc-plugin-5dd8808d.js} +1 -1
- package/dist/{videojs-webrtc-plugin.es-e643c42a.js → videojs-webrtc-plugin.es-812e1a77.js} +6 -2
- package/dist/web_player.js +178 -119
- package/package.json +2 -2
- package/src/web_player.js +197 -136
- package/test/embedded-player.test.js +136 -28
package/dist/es/web_player.js
CHANGED
|
@@ -413,6 +413,10 @@ class WebPlayer {
|
|
|
413
413
|
* It will be taken from url parameter "mute".
|
|
414
414
|
*/
|
|
415
415
|
_defineProperty(this, "mute", false);
|
|
416
|
+
/**
|
|
417
|
+
* controls: Toggles the visibility of player controls.
|
|
418
|
+
*/
|
|
419
|
+
_defineProperty(this, "controls", true);
|
|
416
420
|
/**
|
|
417
421
|
* Force the Player to play with audio Auto Play might not work.
|
|
418
422
|
*/
|
|
@@ -507,6 +511,15 @@ class WebPlayer {
|
|
|
507
511
|
* Is IP Camera
|
|
508
512
|
*/
|
|
509
513
|
_defineProperty(this, "isIPCamera", void 0);
|
|
514
|
+
/**
|
|
515
|
+
* Stream id of backup stream.
|
|
516
|
+
*/
|
|
517
|
+
_defineProperty(this, "backupStreamId", void 0);
|
|
518
|
+
/**
|
|
519
|
+
* activeStreamId: is the stream id that is being played currently
|
|
520
|
+
* It can be streamID or backupStreamId
|
|
521
|
+
*/
|
|
522
|
+
_defineProperty(this, "activeStreamId", void 0);
|
|
510
523
|
WebPlayer.DEFAULT_PLAY_ORDER = ["webrtc", "hls"];
|
|
511
524
|
WebPlayer.DEFAULT_PLAY_TYPE = ["mp4", "webm"];
|
|
512
525
|
WebPlayer.HLS_EXTENSION = "m3u8";
|
|
@@ -519,6 +532,7 @@ class WebPlayer {
|
|
|
519
532
|
WebPlayer.STREAMS_FOLDER = "streams";
|
|
520
533
|
WebPlayer.LL_HLS_Folder = "ll-hls";
|
|
521
534
|
WebPlayer.VIDEO_PLAYER_ID = "video-player";
|
|
535
|
+
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'];
|
|
522
536
|
|
|
523
537
|
// Initialize default values
|
|
524
538
|
this.setDefaults();
|
|
@@ -552,6 +566,8 @@ class WebPlayer {
|
|
|
552
566
|
alert(message);
|
|
553
567
|
throw new Error(message);
|
|
554
568
|
}
|
|
569
|
+
//set the active stream id as stream id
|
|
570
|
+
this.activeStreamId = this.streamId;
|
|
555
571
|
if (!this.httpBaseURL) {
|
|
556
572
|
//this is the case where web player gets everything from url
|
|
557
573
|
var appName = "/";
|
|
@@ -570,17 +586,16 @@ class WebPlayer {
|
|
|
570
586
|
}
|
|
571
587
|
path += appName;
|
|
572
588
|
this.httpBaseURL = this.window.location.protocol + "//" + path;
|
|
573
|
-
this.
|
|
589
|
+
this.websocketBaseURL = "ws://" + path;
|
|
574
590
|
if (this.window.location.protocol.startsWith("https")) {
|
|
575
|
-
this.
|
|
591
|
+
this.websocketBaseURL = this.websocketBaseURL.replace("ws", "wss");
|
|
576
592
|
}
|
|
577
|
-
} else if (!this.
|
|
593
|
+
} else if (!this.websocketBaseURL) {
|
|
578
594
|
//this is the case where web player gets inputs from config object
|
|
579
595
|
if (!this.httpBaseURL.endsWith("/")) {
|
|
580
596
|
this.httpBaseURL += "/";
|
|
581
597
|
}
|
|
582
|
-
this.
|
|
583
|
-
this.websocketURL += this.streamId + ".webrtc";
|
|
598
|
+
this.websocketBaseURL = this.httpBaseURL.replace("http", "ws");
|
|
584
599
|
}
|
|
585
600
|
this.dom = this.window.document;
|
|
586
601
|
this.containerElement.innerHTML = this.videoHTMLContent;
|
|
@@ -638,7 +653,7 @@ class WebPlayer {
|
|
|
638
653
|
this.aScene = null;
|
|
639
654
|
this.playerListener = null;
|
|
640
655
|
this.webRTCDataListener = null;
|
|
641
|
-
this.
|
|
656
|
+
this.websocketBaseURL = null;
|
|
642
657
|
this.httpBaseURL = null;
|
|
643
658
|
this.videoHTMLContent = STATIC_VIDEO_HTML;
|
|
644
659
|
this.videoPlayerId = "video-player";
|
|
@@ -654,6 +669,8 @@ class WebPlayer {
|
|
|
654
669
|
this.ptzMovement = "relative";
|
|
655
670
|
this.restAPIPromise = null;
|
|
656
671
|
this.isIPCamera = false;
|
|
672
|
+
this.playerEvents = WebPlayer.PLAYER_EVENTS;
|
|
673
|
+
this.backupStreamId = null;
|
|
657
674
|
}
|
|
658
675
|
initializeFromUrlParams() {
|
|
659
676
|
var _getUrlParameter;
|
|
@@ -701,15 +718,16 @@ class WebPlayer {
|
|
|
701
718
|
this.restJwt = getUrlParameter_1("restJwt", this.window.location.search) || this.restJwt;
|
|
702
719
|
this.ptzValueStep = getUrlParameter_1("ptzValueStep", this.window.location.search) || this.ptzValueStep;
|
|
703
720
|
this.ptzMovement = getUrlParameter_1("ptzMovement", this.window.location.search) || this.ptzMovement;
|
|
721
|
+
this.backupStreamId = getUrlParameter_1("backupStreamId", this.window.location.search) || this.backupStreamId;
|
|
704
722
|
}
|
|
705
723
|
loadWebRTCComponents() {
|
|
706
724
|
if (this.playOrder.includes("webrtc")) {
|
|
707
|
-
return import('./videojs-webrtc-plugin-
|
|
725
|
+
return import('./videojs-webrtc-plugin-7e293bd2.js').then(css => {
|
|
708
726
|
Logger_1.info("videojs-webrtc-plugin.css is loaded");
|
|
709
727
|
var styleElement = this.dom.createElement('style');
|
|
710
728
|
styleElement.textContent = css.default.toString(); // Assuming css module exports a string
|
|
711
729
|
this.dom.head.appendChild(styleElement);
|
|
712
|
-
return import('./videojs-webrtc-plugin.es-
|
|
730
|
+
return import('./videojs-webrtc-plugin.es-0f1490f6.js').then(videojsWebrtcPluginLocal => {
|
|
713
731
|
Logger_1.info("videojs-webrtc-plugin is loaded");
|
|
714
732
|
});
|
|
715
733
|
});
|
|
@@ -849,26 +867,12 @@ class WebPlayer {
|
|
|
849
867
|
limitRenditionByPlayerDimensions: false
|
|
850
868
|
}
|
|
851
869
|
},
|
|
852
|
-
controls:
|
|
870
|
+
controls: this.controls,
|
|
853
871
|
class: 'video-js vjs-default-skin vjs-big-play-centered',
|
|
854
872
|
muted: this.mute,
|
|
855
873
|
preload: "auto",
|
|
856
874
|
autoplay: this.autoPlay
|
|
857
875
|
});
|
|
858
|
-
this.videojsPlayer.on('error', e => {
|
|
859
|
-
Logger_1.warn("There is an error in playback: ", e);
|
|
860
|
-
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
861
|
-
if (!this.errorCalled) {
|
|
862
|
-
this.errorCalled = true;
|
|
863
|
-
setTimeout(() => {
|
|
864
|
-
this.tryNextTech();
|
|
865
|
-
this.errorCalled = false;
|
|
866
|
-
}, 2500);
|
|
867
|
-
}
|
|
868
|
-
if (this.playerListener != null) {
|
|
869
|
-
this.playerListener("error", e);
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
876
|
|
|
873
877
|
//webrtc specific events
|
|
874
878
|
if (extension == "webrtc") {
|
|
@@ -890,7 +894,7 @@ class WebPlayer {
|
|
|
890
894
|
* If getting codec incompatible or remote description error, it will redirect HLS player.
|
|
891
895
|
*/
|
|
892
896
|
Logger_1.warn("notSetRemoteDescription error. Redirecting to HLS player.");
|
|
893
|
-
this.playIfExists("hls");
|
|
897
|
+
this.playIfExists("hls", this.activeStreamId);
|
|
894
898
|
}
|
|
895
899
|
if (this.playerListener != null) {
|
|
896
900
|
this.playerListener("webrtc-error", errors);
|
|
@@ -954,72 +958,7 @@ class WebPlayer {
|
|
|
954
958
|
if (extension == "mp4" || extension == "webm" || extension == "m3u8") {
|
|
955
959
|
this.makeVideoJSVisibleWhenReady();
|
|
956
960
|
}
|
|
957
|
-
this.
|
|
958
|
-
//reinit to play after it ends
|
|
959
|
-
Logger_1.warn("stream is ended");
|
|
960
|
-
this.setPlayerVisible(false);
|
|
961
|
-
//for webrtc, this event can be called by two reasons
|
|
962
|
-
//1. ice connection is not established, it means that there is a networking issug
|
|
963
|
-
//2. stream is ended
|
|
964
|
-
if (this.currentPlayType != "vod") {
|
|
965
|
-
//if it's vod, it means that stream is ended and no need to replay
|
|
966
|
-
|
|
967
|
-
if (this.iceConnected) {
|
|
968
|
-
//if iceConnected is true, it means that stream is really ended for webrtc
|
|
969
|
-
|
|
970
|
-
//initialize to play again if the publishing starts again
|
|
971
|
-
this.playIfExists(this.playOrder[0]);
|
|
972
|
-
} else if (this.currentPlayType == "hls") {
|
|
973
|
-
//if it's hls, it means that stream is ended
|
|
974
|
-
|
|
975
|
-
this.setPlayerVisible(false);
|
|
976
|
-
if (this.playOrder[0] = "hls") {
|
|
977
|
-
//do not play again if it's hls because it play last seconds again, let the server clear it
|
|
978
|
-
setTimeout(() => {
|
|
979
|
-
this.playIfExists(this.playOrder[0]);
|
|
980
|
-
}, 10000);
|
|
981
|
-
} else {
|
|
982
|
-
this.playIfExists(this.playOrder[0]);
|
|
983
|
-
}
|
|
984
|
-
//TODO: what if the stream is hls vod then it always re-play
|
|
985
|
-
} else {
|
|
986
|
-
//if iceConnected is false, it means that there is a networking issue for webrtc
|
|
987
|
-
this.tryNextTech();
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
if (this.playerListener != null) {
|
|
991
|
-
this.playerListener("ended");
|
|
992
|
-
}
|
|
993
|
-
});
|
|
994
|
-
|
|
995
|
-
//webrtc plugin sends play event. On the other hand, webrtc plugin sends ready event for every scenario.
|
|
996
|
-
//so no need to trust ready event for webrt play
|
|
997
|
-
this.videojsPlayer.on("play", () => {
|
|
998
|
-
this.setPlayerVisible(true);
|
|
999
|
-
if (this.playerListener != null) {
|
|
1000
|
-
this.playerListener("play");
|
|
1001
|
-
}
|
|
1002
|
-
if (this.restJwt) {
|
|
1003
|
-
this.isIpCameraBroadcast();
|
|
1004
|
-
} else if (this.isIPCamera) {
|
|
1005
|
-
this.injectPtzElements();
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
this.videojsPlayer.on("playing", () => {
|
|
1009
|
-
if (this.playerListener != null) {
|
|
1010
|
-
this.playerListener("playing");
|
|
1011
|
-
}
|
|
1012
|
-
});
|
|
1013
|
-
this.videojsPlayer.on("timeupdate", () => {
|
|
1014
|
-
if (this.playerListener != null) {
|
|
1015
|
-
this.playerListener("timeupdate");
|
|
1016
|
-
}
|
|
1017
|
-
});
|
|
1018
|
-
this.videojsPlayer.on("pause", () => {
|
|
1019
|
-
if (this.playerListener != null) {
|
|
1020
|
-
this.playerListener("pause");
|
|
1021
|
-
}
|
|
1022
|
-
});
|
|
961
|
+
this.listenPlayerEvents();
|
|
1023
962
|
this.iceConnected = false;
|
|
1024
963
|
this.videojsPlayer.src({
|
|
1025
964
|
src: streamUrl,
|
|
@@ -1043,6 +982,109 @@ class WebPlayer {
|
|
|
1043
982
|
});
|
|
1044
983
|
}
|
|
1045
984
|
}
|
|
985
|
+
listenPlayerEvents() {
|
|
986
|
+
this.playerEvents.forEach(event => {
|
|
987
|
+
this.videojsPlayer.on(event, eventData => {
|
|
988
|
+
switch (event) {
|
|
989
|
+
case 'play':
|
|
990
|
+
this.setPlayerVisible(true);
|
|
991
|
+
if (this.playerListener != null) {
|
|
992
|
+
this.playerListener("play");
|
|
993
|
+
}
|
|
994
|
+
if (this.restJwt) {
|
|
995
|
+
this.isIpCameraBroadcast();
|
|
996
|
+
} else if (this.isIPCamera) {
|
|
997
|
+
this.injectPtzElements();
|
|
998
|
+
}
|
|
999
|
+
break;
|
|
1000
|
+
case 'ended':
|
|
1001
|
+
//reinit to play after it ends
|
|
1002
|
+
Logger_1.warn("stream is ended");
|
|
1003
|
+
this.setPlayerVisible(false);
|
|
1004
|
+
//for webrtc, this event can be called by two reasons
|
|
1005
|
+
//1. ice connection is not established, it means that there is a networking issug
|
|
1006
|
+
//2. stream is ended
|
|
1007
|
+
if (this.currentPlayType != "vod") {
|
|
1008
|
+
//if it's vod, it means that stream is ended and no need to replay
|
|
1009
|
+
|
|
1010
|
+
if (this.iceConnected) {
|
|
1011
|
+
//if iceConnected is true, it means that stream is really ended for webrtc
|
|
1012
|
+
|
|
1013
|
+
//initialize to play again if the publishing starts again
|
|
1014
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1015
|
+
} else if (this.currentPlayType == "hls") {
|
|
1016
|
+
//if it's hls, it means that stream is ended
|
|
1017
|
+
|
|
1018
|
+
this.setPlayerVisible(false);
|
|
1019
|
+
if (this.playOrder[0] = "hls") {
|
|
1020
|
+
//do not play again if it's hls because it play last seconds again, let the server clear it
|
|
1021
|
+
setTimeout(() => {
|
|
1022
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1023
|
+
}, 10000);
|
|
1024
|
+
} else {
|
|
1025
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1026
|
+
}
|
|
1027
|
+
//TODO: what if the stream is hls vod then it always re-play
|
|
1028
|
+
} else {
|
|
1029
|
+
//if iceConnected is false, it means that there is a networking issue for webrtc
|
|
1030
|
+
this.tryNextTech();
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
if (this.playerListener != null) {
|
|
1034
|
+
this.playerListener(event);
|
|
1035
|
+
}
|
|
1036
|
+
break;
|
|
1037
|
+
case 'timeupdate':
|
|
1038
|
+
if (this.playerListener != null) {
|
|
1039
|
+
this.playerListener(event, eventData, {
|
|
1040
|
+
currentTime: this.videojsPlayer.currentTime()
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
break;
|
|
1044
|
+
case 'progress':
|
|
1045
|
+
if (this.playerListener != null) {
|
|
1046
|
+
this.playerListener(event, eventData, {
|
|
1047
|
+
bufferedPercent: this.videojsPlayer.bufferedPercent()
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
break;
|
|
1051
|
+
case 'volumechange':
|
|
1052
|
+
if (this.playerListener != null) {
|
|
1053
|
+
this.playerListener(event, eventData, {
|
|
1054
|
+
volume: this.videojsPlayer.volume(),
|
|
1055
|
+
muted: this.videojsPlayer.muted()
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
break;
|
|
1059
|
+
case 'ratechange':
|
|
1060
|
+
if (this.playerListener != null) {
|
|
1061
|
+
this.playerListener(event, eventData, {
|
|
1062
|
+
playbackRate: this.videojsPlayer.playbackRate()
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
break;
|
|
1066
|
+
case 'error':
|
|
1067
|
+
Logger_1.warn("There is an error in playback: ", eventData);
|
|
1068
|
+
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
1069
|
+
if (!this.errorCalled) {
|
|
1070
|
+
this.errorCalled = true;
|
|
1071
|
+
setTimeout(() => {
|
|
1072
|
+
this.tryNextTech();
|
|
1073
|
+
this.errorCalled = false;
|
|
1074
|
+
}, 2500);
|
|
1075
|
+
}
|
|
1076
|
+
if (this.playerListener != null) {
|
|
1077
|
+
this.playerListener("error", eventData);
|
|
1078
|
+
}
|
|
1079
|
+
break;
|
|
1080
|
+
default:
|
|
1081
|
+
if (this.playerListener != null) {
|
|
1082
|
+
this.playerListener(event, eventData);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1046
1088
|
listenForID3MetaData() {
|
|
1047
1089
|
this.videojsPlayer.textTracks().on('addtrack', e => {
|
|
1048
1090
|
var metadataTrack = Array.from(this.videojsPlayer.textTracks()).find(t => t.label === 'Timed Metadata');
|
|
@@ -1135,15 +1177,26 @@ class WebPlayer {
|
|
|
1135
1177
|
this.destroyDashPlayer();
|
|
1136
1178
|
this.destroyVideoJSPlayer();
|
|
1137
1179
|
this.setPlayerVisible(false);
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1180
|
+
|
|
1181
|
+
//before changing play type, let's check if there is any backup stream
|
|
1182
|
+
var playTypeIndex = this.playOrder.indexOf(this.currentPlayType);
|
|
1183
|
+
if (this.activeStreamId == this.streamId && this.backupStreamId != null) {
|
|
1184
|
+
//update active stream id to backup stream id
|
|
1185
|
+
this.activeStreamId = this.backupStreamId;
|
|
1186
|
+
//don't update playTypeIndex because we're trying backup stream with the same play type
|
|
1141
1187
|
} else {
|
|
1142
|
-
|
|
1188
|
+
//reset the activeStreamId back to streamId
|
|
1189
|
+
this.activeStreamId = this.streamId;
|
|
1190
|
+
//update the playTypeIndex to try next tech
|
|
1191
|
+
if (playTypeIndex == -1 || playTypeIndex == this.playOrder.length - 1) {
|
|
1192
|
+
playTypeIndex = 0;
|
|
1193
|
+
} else {
|
|
1194
|
+
playTypeIndex++;
|
|
1195
|
+
}
|
|
1143
1196
|
}
|
|
1144
1197
|
this.tryNextTechTimer = setTimeout(() => {
|
|
1145
1198
|
this.tryNextTechTimer = -1;
|
|
1146
|
-
this.playIfExists(this.playOrder[
|
|
1199
|
+
this.playIfExists(this.playOrder[playTypeIndex], this.activeStreamId);
|
|
1147
1200
|
}, 3000);
|
|
1148
1201
|
} else {
|
|
1149
1202
|
Logger_1.debug("tryNextTech is already scheduled no need to schedule again");
|
|
@@ -1211,10 +1264,10 @@ class WebPlayer {
|
|
|
1211
1264
|
if (this.playOrder[0] = "dash") {
|
|
1212
1265
|
//do not play again if it's dash because it play last seconds again, let the server clear it
|
|
1213
1266
|
setTimeout(() => {
|
|
1214
|
-
this.playIfExists(this.playOrder[0]);
|
|
1267
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1215
1268
|
}, 10000);
|
|
1216
1269
|
} else {
|
|
1217
|
-
this.playIfExists(this.playOrder[0]);
|
|
1270
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1218
1271
|
}
|
|
1219
1272
|
if (this.playerListener != null) {
|
|
1220
1273
|
this.playerListener("ended");
|
|
@@ -1301,7 +1354,7 @@ class WebPlayer {
|
|
|
1301
1354
|
* play the stream with the given tech
|
|
1302
1355
|
* @param {string} tech
|
|
1303
1356
|
*/
|
|
1304
|
-
playIfExists(tech) {
|
|
1357
|
+
playIfExists(tech, streamIdToPlay) {
|
|
1305
1358
|
var _this = this;
|
|
1306
1359
|
return _asyncToGenerator(function* () {
|
|
1307
1360
|
_this.currentPlayType = tech;
|
|
@@ -1309,70 +1362,73 @@ class WebPlayer {
|
|
|
1309
1362
|
_this.destroyDashPlayer();
|
|
1310
1363
|
_this.setPlayerVisible(false);
|
|
1311
1364
|
_this.containerElement.innerHTML = _this.videoHTMLContent;
|
|
1312
|
-
Logger_1.warn("Try to play the stream " +
|
|
1365
|
+
Logger_1.warn("Try to play the stream " + streamIdToPlay + " with " + _this.currentPlayType);
|
|
1313
1366
|
switch (_this.currentPlayType) {
|
|
1314
1367
|
case "hls":
|
|
1315
1368
|
//TODO: Test case for hls
|
|
1316
1369
|
//1. Play stream with adaptive m3u8 for live and VoD
|
|
1317
1370
|
//2. Play stream with m3u8 for live and VoD
|
|
1318
1371
|
//3. if files are not available check nextTech is being called
|
|
1319
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1372
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, WebPlayer.HLS_EXTENSION).then(streamPath => {
|
|
1320
1373
|
_this.playWithVideoJS(streamPath, WebPlayer.HLS_EXTENSION);
|
|
1321
1374
|
Logger_1.warn("incoming stream path: " + streamPath);
|
|
1322
1375
|
}).catch(error => {
|
|
1323
|
-
Logger_1.warn("HLS stream resource not available for stream:" +
|
|
1376
|
+
Logger_1.warn("HLS stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1324
1377
|
_this.tryNextTech();
|
|
1325
1378
|
});
|
|
1326
1379
|
case "ll-hls":
|
|
1327
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER + "/" + WebPlayer.LL_HLS_FOLDER,
|
|
1380
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER + "/" + WebPlayer.LL_HLS_FOLDER, streamIdToPlay, WebPlayer.HLS_EXTENSION).then(streamPath => {
|
|
1328
1381
|
_this.playWithVideoJS(streamPath, WebPlayer.HLS_EXTENSION);
|
|
1329
1382
|
Logger_1.warn("incoming stream path: " + streamPath);
|
|
1330
1383
|
}).catch(error => {
|
|
1331
|
-
Logger_1.warn("LL-HLS stream resource not available for stream:" +
|
|
1384
|
+
Logger_1.warn("LL-HLS stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1332
1385
|
_this.tryNextTech();
|
|
1333
1386
|
});
|
|
1334
1387
|
case "dash":
|
|
1335
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1388
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay + "/" + streamIdToPlay, WebPlayer.DASH_EXTENSION).then(streamPath => {
|
|
1336
1389
|
_this.playViaDash(streamPath);
|
|
1337
1390
|
}).catch(error => {
|
|
1338
|
-
Logger_1.warn("DASH stream resource not available for stream:" +
|
|
1391
|
+
Logger_1.warn("DASH stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1339
1392
|
_this.tryNextTech();
|
|
1340
1393
|
});
|
|
1341
1394
|
case "webrtc":
|
|
1342
|
-
return _this.playWithVideoJS(_this.addSecurityParams(_this.
|
|
1395
|
+
return _this.playWithVideoJS(_this.addSecurityParams(_this.getWebsocketURLForStream(streamIdToPlay)), WebPlayer.WEBRTC_EXTENSION);
|
|
1343
1396
|
case "vod":
|
|
1344
1397
|
//TODO: Test case for vod
|
|
1345
1398
|
//1. Play stream with mp4 for VoD
|
|
1346
1399
|
//2. Play stream with webm for VoD
|
|
1347
1400
|
//3. Play stream with playOrder type
|
|
1348
1401
|
|
|
1349
|
-
var lastIndexOfDot =
|
|
1402
|
+
var lastIndexOfDot = streamIdToPlay.lastIndexOf(".");
|
|
1350
1403
|
var extension;
|
|
1351
1404
|
if (lastIndexOfDot != -1) {
|
|
1352
1405
|
//if there is a dot in the streamId, it means that this is extension, use it. make the extension empty
|
|
1353
1406
|
_this.playType[0] = "";
|
|
1354
|
-
extension =
|
|
1407
|
+
extension = streamIdToPlay.substring(lastIndexOfDot + 1);
|
|
1355
1408
|
} else {
|
|
1356
1409
|
//we need to give extension to playWithVideoJS
|
|
1357
1410
|
extension = _this.playType[0];
|
|
1358
1411
|
}
|
|
1359
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1412
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, _this.playType[0]).then(streamPath => {
|
|
1360
1413
|
//we need to give extension to playWithVideoJS
|
|
1361
1414
|
_this.playWithVideoJS(streamPath, extension);
|
|
1362
1415
|
}).catch(error => {
|
|
1363
|
-
Logger_1.warn("VOD stream resource not available for stream:" +
|
|
1416
|
+
Logger_1.warn("VOD stream resource not available for stream:" + streamIdToPlay + " and play type " + _this.playType[0] + ". Error is " + error);
|
|
1364
1417
|
if (_this.playType.length > 1) {
|
|
1365
1418
|
Logger_1.warn("Try next play type which is " + _this.playType[1] + ".");
|
|
1366
|
-
_this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1419
|
+
_this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, _this.playType[1]).then(streamPath => {
|
|
1367
1420
|
_this.playWithVideoJS(streamPath, _this.playType[1]);
|
|
1368
1421
|
}).catch(error => {
|
|
1369
|
-
Logger_1.warn("VOD stream resource not available for stream:" +
|
|
1422
|
+
Logger_1.warn("VOD stream resource not available for stream:" + streamIdToPlay + " and play type error is " + error);
|
|
1370
1423
|
});
|
|
1371
1424
|
}
|
|
1372
1425
|
});
|
|
1373
1426
|
}
|
|
1374
1427
|
})();
|
|
1375
1428
|
}
|
|
1429
|
+
getWebsocketURLForStream(streamIdToPlay) {
|
|
1430
|
+
return this.websocketBaseURL + streamIdToPlay + ".webrtc";
|
|
1431
|
+
}
|
|
1376
1432
|
|
|
1377
1433
|
/**
|
|
1378
1434
|
*
|
|
@@ -1396,10 +1452,12 @@ class WebPlayer {
|
|
|
1396
1452
|
* play the stream with videojs player or dash player
|
|
1397
1453
|
*/
|
|
1398
1454
|
play() {
|
|
1399
|
-
if
|
|
1455
|
+
//if there is a request to play, try original stream first
|
|
1456
|
+
this.activeStreamId = this.streamId;
|
|
1457
|
+
if (this.activeStreamId.startsWith(WebPlayer.STREAMS_FOLDER)) {
|
|
1400
1458
|
//start videojs player because it directly try to play stream from streams folder
|
|
1401
|
-
var lastIndexOfDot = this.
|
|
1402
|
-
var extension = this.
|
|
1459
|
+
var lastIndexOfDot = this.activeStreamId.lastIndexOf(".");
|
|
1460
|
+
var extension = this.activeStreamId.substring(lastIndexOfDot + 1);
|
|
1403
1461
|
this.playOrder = ["vod"];
|
|
1404
1462
|
this.currentPlayType = this.playOrder[0];
|
|
1405
1463
|
if (!this.httpBaseURL.endsWith("/")) {
|
|
@@ -1407,12 +1465,12 @@ class WebPlayer {
|
|
|
1407
1465
|
}
|
|
1408
1466
|
this.containerElement.innerHTML = this.videoHTMLContent;
|
|
1409
1467
|
if (extension == WebPlayer.DASH_EXTENSION) {
|
|
1410
|
-
this.playViaDash(this.httpBaseURL + this.addSecurityParams(this.
|
|
1468
|
+
this.playViaDash(this.httpBaseURL + this.addSecurityParams(this.activeStreamId), extension);
|
|
1411
1469
|
} else {
|
|
1412
|
-
this.playWithVideoJS(this.httpBaseURL + this.addSecurityParams(this.
|
|
1470
|
+
this.playWithVideoJS(this.httpBaseURL + this.addSecurityParams(this.activeStreamId), extension);
|
|
1413
1471
|
}
|
|
1414
1472
|
} else {
|
|
1415
|
-
this.playIfExists(this.playOrder[0]);
|
|
1473
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1416
1474
|
}
|
|
1417
1475
|
}
|
|
1418
1476
|
|
|
@@ -1476,7 +1534,7 @@ class WebPlayer {
|
|
|
1476
1534
|
return false;
|
|
1477
1535
|
}
|
|
1478
1536
|
injectPtzElements() {
|
|
1479
|
-
var ptzControlsHtmlContent = "\n <style>\n .ptz-camera-container {\n display: none;\n position: absolute;\n flex-direction: row;\n align-items: center;\n bottom: 30px;\n right: 10px;\n z-index:999;\n }\n .direction-arrow-container {\n display: flex;\n width: 200px;\n height: 200px;\n position: relative;\n }\n \n </style>\n <div id=\"ptz-camera-container\" class=\"ptz-camera-container\">\n \n <div style=\"display: flex; flex-direction: column;\">\n <div style=\"margin-bottom:5px\">\n <span id=\"zoom-out-button\" style=\"color: #bc1b22; font-size: 50px; font-weight: bold; user-select: none; cursor: pointer; margin-right: 5px;\">-</span>\n <span id=\"zoom-in-button\" style=\"color: #bc1b22; font-size: 50px; font-weight: bold; cursor: pointer; margin-left: 5px; user-select: none;\">+</span>\n </div>\n <div id=\"direction-arrow-container\" class=\"direction-arrow-container\">\n <img id=\"up-button\" style=\"position: absolute; width: 50px; cursor: pointer; height: 50px; left: 50%; transform: translateX(-50%);\" src=\"" + img + "\"/>\n \n <img id=\"left-button\" style=\"position: absolute; left: 0px; width: 50px; height: 50px; cursor: pointer; top: 50%; transform: translateY(-50%) rotate(-90deg);\" src=\"" + img + "\"/>\n <img id=\"right-button\" style=\"position: absolute; right:0px; top: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateY(-50%) rotate(90deg);\" src=\"" + img + "\"/>\n <img id=\"down-button\" style=\"position: absolute; bottom:0px;left: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateX(-50%) rotate(180deg);\" src=\"" + img + "\"/>\n \n </div>\n \n \n </div>\n </div>\n </div>\n ";
|
|
1537
|
+
var ptzControlsHtmlContent = "\n <style>\n .ptz-camera-container {\n display: none;\n position: absolute;\n flex-direction: row;\n align-items: center;\n bottom: 30px;\n right: 10px;\n z-index:999;\n }\n .direction-arrow-container {\n display: flex;\n width: 200px;\n height: 200px;\n position: relative;\n }\n \n </style>\n <div id=\"ptz-camera-container\" class=\"ptz-camera-container\">\n \n <div style=\"display: flex; flex-direction: column;\">\n <div style=\"margin-bottom:5px\">\n <span id=\"zoom-out-button\" style=\"color: #bc1b22; font-size: 50px; font-weight: bold; user-select: none; cursor: pointer; margin-right: 5px;\">-</span>\n <span id=\"zoom-in-button\" style=\"color: #bc1b22; font-size: 50px; font-weight: bold; cursor: pointer; margin-left: 5px; user-select: none;\">+</span>\n </div>\n <div id=\"direction-arrow-container\" class=\"direction-arrow-container\">\n <img id=\"up-button\" style=\"position: absolute; width: 50px; cursor: pointer; height: 50px; left: 50%; transform: translateX(-50%);\" src=\"" + img.src + "\"/>\n \n <img id=\"left-button\" style=\"position: absolute; left: 0px; width: 50px; height: 50px; cursor: pointer; top: 50%; transform: translateY(-50%) rotate(-90deg);\" src=\"" + img.src + "\"/>\n <img id=\"right-button\" style=\"position: absolute; right:0px; top: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateY(-50%) rotate(90deg);\" src=\"" + img.src + "\"/>\n <img id=\"down-button\" style=\"position: absolute; bottom:0px;left: 50%; width: 50px; cursor: pointer; height: 50px; transform: translateX(-50%) rotate(180deg);\" src=\"" + img.src + "\"/>\n \n </div>\n \n \n </div>\n </div>\n </div>\n ";
|
|
1480
1538
|
var ptzCameraContainer = document.getElementById("ptz-camera-container");
|
|
1481
1539
|
if (ptzCameraContainer) {
|
|
1482
1540
|
Logger_1.info("PTZ controls are already injected");
|
|
@@ -1603,6 +1661,7 @@ class WebPlayer {
|
|
|
1603
1661
|
}
|
|
1604
1662
|
}
|
|
1605
1663
|
}
|
|
1664
|
+
_defineProperty(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']);
|
|
1606
1665
|
_defineProperty(WebPlayer, "DEFAULT_PLAY_ORDER", ["webrtc", "hls"]);
|
|
1607
1666
|
_defineProperty(WebPlayer, "DEFAULT_PLAY_TYPE", ["mp4", "webm"]);
|
|
1608
1667
|
_defineProperty(WebPlayer, "HLS_EXTENSION", "m3u8");
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare class WebPlayer {
|
|
2
|
+
static PLAYER_EVENTS: string[];
|
|
2
3
|
static DEFAULT_PLAY_ORDER: string[];
|
|
3
4
|
static DEFAULT_PLAY_TYPE: string[];
|
|
4
5
|
static HLS_EXTENSION: string;
|
|
@@ -63,6 +64,10 @@ export declare class WebPlayer {
|
|
|
63
64
|
* It will be taken from url parameter "mute".
|
|
64
65
|
*/
|
|
65
66
|
mute: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* controls: Toggles the visibility of player controls.
|
|
69
|
+
*/
|
|
70
|
+
controls: boolean;
|
|
66
71
|
/**
|
|
67
72
|
* Force the Player to play with audio Auto Play might not work.
|
|
68
73
|
*/
|
|
@@ -157,10 +162,19 @@ export declare class WebPlayer {
|
|
|
157
162
|
* Is IP Camera
|
|
158
163
|
*/
|
|
159
164
|
isIPCamera: any;
|
|
165
|
+
/**
|
|
166
|
+
* Stream id of backup stream.
|
|
167
|
+
*/
|
|
168
|
+
backupStreamId: any;
|
|
169
|
+
/**
|
|
170
|
+
* activeStreamId: is the stream id that is being played currently
|
|
171
|
+
* It can be streamID or backupStreamId
|
|
172
|
+
*/
|
|
173
|
+
activeStreamId: never;
|
|
160
174
|
containerElementInitialDisplay: any;
|
|
161
175
|
placeHolderElementInitialDisplay: any;
|
|
162
176
|
httpBaseURL: string;
|
|
163
|
-
|
|
177
|
+
websocketBaseURL: any;
|
|
164
178
|
dom: any;
|
|
165
179
|
isWindow(configOrWindow: any): any;
|
|
166
180
|
initialize(): Promise<any>;
|
|
@@ -168,6 +182,7 @@ export declare class WebPlayer {
|
|
|
168
182
|
dashjsLoaded: boolean | undefined;
|
|
169
183
|
setDefaults(): void;
|
|
170
184
|
videojsLoaded: boolean | undefined;
|
|
185
|
+
playerEvents: string[] | undefined;
|
|
171
186
|
initializeFromUrlParams(): void;
|
|
172
187
|
loadWebRTCComponents(): Promise<void>;
|
|
173
188
|
/**
|
|
@@ -191,6 +206,7 @@ export declare class WebPlayer {
|
|
|
191
206
|
* @returns
|
|
192
207
|
*/
|
|
193
208
|
playWithVideoJS(streamUrl: any, extension: any): void;
|
|
209
|
+
listenPlayerEvents(): void;
|
|
194
210
|
listenForID3MetaData(): void;
|
|
195
211
|
makeVideoJSVisibleWhenReady(): void;
|
|
196
212
|
/**
|
|
@@ -230,7 +246,8 @@ export declare class WebPlayer {
|
|
|
230
246
|
* play the stream with the given tech
|
|
231
247
|
* @param {string} tech
|
|
232
248
|
*/
|
|
233
|
-
playIfExists(tech: string): Promise<void>;
|
|
249
|
+
playIfExists(tech: string, streamIdToPlay: any): Promise<void>;
|
|
250
|
+
getWebsocketURLForStream(streamIdToPlay: any): string;
|
|
234
251
|
/**
|
|
235
252
|
*
|
|
236
253
|
* @returns {String} query string for security
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var videojsWebrtcPlugin = "/*! @name @antmedia/videojs-webrtc-plugin @version 1.3.
|
|
3
|
+
var videojsWebrtcPlugin = "/*! @name @antmedia/videojs-webrtc-plugin @version 1.3.2 @license MIT */\n.vjs-custom-spinner{position:absolute;top:50%;transform:translateY(-50%) translateX(-50%);left:50%;width:80px;height:80px}.vjs-custom-spinner:after{content:\" \";display:block;width:64px;height:64px;margin:8px;border-radius:50%;border:6px solid #fff;border-color:#fff transparent;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}";
|
|
4
4
|
|
|
5
5
|
exports.default = videojsWebrtcPlugin;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var video_es = require('./video.es-474303e7.js');
|
|
4
4
|
require('./_commonjsHelpers-ed042b00.js');
|
|
5
5
|
|
|
6
|
-
/*! @name @antmedia/videojs-webrtc-plugin @version 1.3.
|
|
6
|
+
/*! @name @antmedia/videojs-webrtc-plugin @version 1.3.2 @license MIT */
|
|
7
7
|
const ANT_CALLBACKS = {
|
|
8
8
|
INITIALIZED: 'initialized',
|
|
9
9
|
PLAY_STARTED: 'play_started',
|
|
@@ -7579,7 +7579,11 @@ class WebRTCHandler {
|
|
|
7579
7579
|
leaveStreamHandler() {
|
|
7580
7580
|
// reset stream resolutions in dropdown
|
|
7581
7581
|
this.player.resolutions = [];
|
|
7582
|
-
|
|
7582
|
+
// eslint-disable-next-line newline-after-var
|
|
7583
|
+
const resolutionButton = this.player.controlBar.getChild('ResolutionMenuButton');
|
|
7584
|
+
if (resolutionButton) {
|
|
7585
|
+
resolutionButton.update();
|
|
7586
|
+
}
|
|
7583
7587
|
}
|
|
7584
7588
|
/**
|
|
7585
7589
|
* stream information handler.
|