@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
|
@@ -10,23 +10,40 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
12
|
- uses: actions/checkout@v3
|
|
13
|
+
|
|
13
14
|
- uses: actions/setup-node@v3
|
|
14
15
|
with:
|
|
15
16
|
node-version: '16.x'
|
|
16
|
-
# Setup .npmrc file to publish to npm
|
|
17
17
|
registry-url: 'https://registry.npmjs.org'
|
|
18
|
+
|
|
18
19
|
- uses: actions/setup-java@v3
|
|
19
20
|
with:
|
|
20
21
|
java-version: '11'
|
|
21
22
|
distribution: 'adopt'
|
|
23
|
+
|
|
22
24
|
- name: Get the version
|
|
23
25
|
id: get_version
|
|
24
26
|
run: echo "VERSION=$(echo ${GITHUB_REF##*/} | cut -d v -f 2)" >> $GITHUB_OUTPUT
|
|
27
|
+
|
|
25
28
|
- run: npm install
|
|
29
|
+
|
|
26
30
|
- run: npm run compile
|
|
31
|
+
|
|
27
32
|
- run: npm test
|
|
28
|
-
|
|
33
|
+
|
|
29
34
|
- run: npm publish
|
|
30
35
|
env:
|
|
31
|
-
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}
|
|
36
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
37
|
+
|
|
38
|
+
- name: Update Embedded Player
|
|
39
|
+
if: success()
|
|
40
|
+
run: |
|
|
41
|
+
curl -L \
|
|
42
|
+
-X POST \
|
|
43
|
+
-H "Accept: application/vnd.github.v3+json" \
|
|
44
|
+
-H "Authorization: Bearer ${{ secrets.REPO_COMMUNICATION }}" \
|
|
45
|
+
https://api.github.com/repos/ant-media/StreamApp/actions/workflows/update-embedded-player.yml/dispatches \
|
|
46
|
+
-d '{"ref":"master"}'
|
|
47
|
+
|
|
48
|
+
|
|
32
49
|
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
- run: npm run compile
|
|
24
24
|
- run: npm test
|
|
25
25
|
#Fix this versioning for the snapshots
|
|
26
|
-
- run: npm version
|
|
26
|
+
- run: npm version 3.0.0-SNAPSHOT"-`date +"%Y-%b-%d-%I-%M"`" --no-git-tag-version
|
|
27
27
|
- run: npm publish --tag SNAPSHOT
|
|
28
28
|
env:
|
|
29
29
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
|
@@ -125,6 +125,10 @@
|
|
|
125
125
|
* It will be taken from url parameter "mute".
|
|
126
126
|
*/
|
|
127
127
|
_defineProperty(this, "mute", false);
|
|
128
|
+
/**
|
|
129
|
+
* controls: Toggles the visibility of player controls.
|
|
130
|
+
*/
|
|
131
|
+
_defineProperty(this, "controls", true);
|
|
128
132
|
/**
|
|
129
133
|
* Force the Player to play with audio Auto Play might not work.
|
|
130
134
|
*/
|
|
@@ -219,6 +223,15 @@
|
|
|
219
223
|
* Is IP Camera
|
|
220
224
|
*/
|
|
221
225
|
_defineProperty(this, "isIPCamera", void 0);
|
|
226
|
+
/**
|
|
227
|
+
* Stream id of backup stream.
|
|
228
|
+
*/
|
|
229
|
+
_defineProperty(this, "backupStreamId", void 0);
|
|
230
|
+
/**
|
|
231
|
+
* activeStreamId: is the stream id that is being played currently
|
|
232
|
+
* It can be streamID or backupStreamId
|
|
233
|
+
*/
|
|
234
|
+
_defineProperty(this, "activeStreamId", void 0);
|
|
222
235
|
WebPlayer.DEFAULT_PLAY_ORDER = ["webrtc", "hls"];
|
|
223
236
|
WebPlayer.DEFAULT_PLAY_TYPE = ["mp4", "webm"];
|
|
224
237
|
WebPlayer.HLS_EXTENSION = "m3u8";
|
|
@@ -231,6 +244,7 @@
|
|
|
231
244
|
WebPlayer.STREAMS_FOLDER = "streams";
|
|
232
245
|
WebPlayer.LL_HLS_Folder = "ll-hls";
|
|
233
246
|
WebPlayer.VIDEO_PLAYER_ID = "video-player";
|
|
247
|
+
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'];
|
|
234
248
|
|
|
235
249
|
// Initialize default values
|
|
236
250
|
this.setDefaults();
|
|
@@ -264,6 +278,8 @@
|
|
|
264
278
|
alert(message);
|
|
265
279
|
throw new Error(message);
|
|
266
280
|
}
|
|
281
|
+
//set the active stream id as stream id
|
|
282
|
+
this.activeStreamId = this.streamId;
|
|
267
283
|
if (!this.httpBaseURL) {
|
|
268
284
|
//this is the case where web player gets everything from url
|
|
269
285
|
var appName = "/";
|
|
@@ -282,17 +298,16 @@
|
|
|
282
298
|
}
|
|
283
299
|
path += appName;
|
|
284
300
|
this.httpBaseURL = this.window.location.protocol + "//" + path;
|
|
285
|
-
this.
|
|
301
|
+
this.websocketBaseURL = "ws://" + path;
|
|
286
302
|
if (this.window.location.protocol.startsWith("https")) {
|
|
287
|
-
this.
|
|
303
|
+
this.websocketBaseURL = this.websocketBaseURL.replace("ws", "wss");
|
|
288
304
|
}
|
|
289
|
-
} else if (!this.
|
|
305
|
+
} else if (!this.websocketBaseURL) {
|
|
290
306
|
//this is the case where web player gets inputs from config object
|
|
291
307
|
if (!this.httpBaseURL.endsWith("/")) {
|
|
292
308
|
this.httpBaseURL += "/";
|
|
293
309
|
}
|
|
294
|
-
this.
|
|
295
|
-
this.websocketURL += this.streamId + ".webrtc";
|
|
310
|
+
this.websocketBaseURL = this.httpBaseURL.replace("http", "ws");
|
|
296
311
|
}
|
|
297
312
|
this.dom = this.window.document;
|
|
298
313
|
this.containerElement.innerHTML = this.videoHTMLContent;
|
|
@@ -350,7 +365,7 @@
|
|
|
350
365
|
this.aScene = null;
|
|
351
366
|
this.playerListener = null;
|
|
352
367
|
this.webRTCDataListener = null;
|
|
353
|
-
this.
|
|
368
|
+
this.websocketBaseURL = null;
|
|
354
369
|
this.httpBaseURL = null;
|
|
355
370
|
this.videoHTMLContent = STATIC_VIDEO_HTML;
|
|
356
371
|
this.videoPlayerId = "video-player";
|
|
@@ -366,6 +381,8 @@
|
|
|
366
381
|
this.ptzMovement = "relative";
|
|
367
382
|
this.restAPIPromise = null;
|
|
368
383
|
this.isIPCamera = false;
|
|
384
|
+
this.playerEvents = WebPlayer.PLAYER_EVENTS;
|
|
385
|
+
this.backupStreamId = null;
|
|
369
386
|
}
|
|
370
387
|
initializeFromUrlParams() {
|
|
371
388
|
var _getUrlParameter;
|
|
@@ -413,6 +430,7 @@
|
|
|
413
430
|
this.restJwt = fetch_stream.getUrlParameter("restJwt", this.window.location.search) || this.restJwt;
|
|
414
431
|
this.ptzValueStep = fetch_stream.getUrlParameter("ptzValueStep", this.window.location.search) || this.ptzValueStep;
|
|
415
432
|
this.ptzMovement = fetch_stream.getUrlParameter("ptzMovement", this.window.location.search) || this.ptzMovement;
|
|
433
|
+
this.backupStreamId = fetch_stream.getUrlParameter("backupStreamId", this.window.location.search) || this.backupStreamId;
|
|
416
434
|
}
|
|
417
435
|
loadWebRTCComponents() {
|
|
418
436
|
if (this.playOrder.includes("webrtc")) {
|
|
@@ -561,26 +579,12 @@
|
|
|
561
579
|
limitRenditionByPlayerDimensions: false
|
|
562
580
|
}
|
|
563
581
|
},
|
|
564
|
-
controls:
|
|
582
|
+
controls: this.controls,
|
|
565
583
|
class: 'video-js vjs-default-skin vjs-big-play-centered',
|
|
566
584
|
muted: this.mute,
|
|
567
585
|
preload: "auto",
|
|
568
586
|
autoplay: this.autoPlay
|
|
569
587
|
});
|
|
570
|
-
this.videojsPlayer.on('error', e => {
|
|
571
|
-
loglevel_min.Logger.warn("There is an error in playback: ", e);
|
|
572
|
-
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
573
|
-
if (!this.errorCalled) {
|
|
574
|
-
this.errorCalled = true;
|
|
575
|
-
setTimeout(() => {
|
|
576
|
-
this.tryNextTech();
|
|
577
|
-
this.errorCalled = false;
|
|
578
|
-
}, 2500);
|
|
579
|
-
}
|
|
580
|
-
if (this.playerListener != null) {
|
|
581
|
-
this.playerListener("error", e);
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
588
|
|
|
585
589
|
//webrtc specific events
|
|
586
590
|
if (extension == "webrtc") {
|
|
@@ -602,7 +606,7 @@
|
|
|
602
606
|
* If getting codec incompatible or remote description error, it will redirect HLS player.
|
|
603
607
|
*/
|
|
604
608
|
loglevel_min.Logger.warn("notSetRemoteDescription error. Redirecting to HLS player.");
|
|
605
|
-
this.playIfExists("hls");
|
|
609
|
+
this.playIfExists("hls", this.activeStreamId);
|
|
606
610
|
}
|
|
607
611
|
if (this.playerListener != null) {
|
|
608
612
|
this.playerListener("webrtc-error", errors);
|
|
@@ -666,72 +670,7 @@
|
|
|
666
670
|
if (extension == "mp4" || extension == "webm" || extension == "m3u8") {
|
|
667
671
|
this.makeVideoJSVisibleWhenReady();
|
|
668
672
|
}
|
|
669
|
-
this.
|
|
670
|
-
//reinit to play after it ends
|
|
671
|
-
loglevel_min.Logger.warn("stream is ended");
|
|
672
|
-
this.setPlayerVisible(false);
|
|
673
|
-
//for webrtc, this event can be called by two reasons
|
|
674
|
-
//1. ice connection is not established, it means that there is a networking issug
|
|
675
|
-
//2. stream is ended
|
|
676
|
-
if (this.currentPlayType != "vod") {
|
|
677
|
-
//if it's vod, it means that stream is ended and no need to replay
|
|
678
|
-
|
|
679
|
-
if (this.iceConnected) {
|
|
680
|
-
//if iceConnected is true, it means that stream is really ended for webrtc
|
|
681
|
-
|
|
682
|
-
//initialize to play again if the publishing starts again
|
|
683
|
-
this.playIfExists(this.playOrder[0]);
|
|
684
|
-
} else if (this.currentPlayType == "hls") {
|
|
685
|
-
//if it's hls, it means that stream is ended
|
|
686
|
-
|
|
687
|
-
this.setPlayerVisible(false);
|
|
688
|
-
if (this.playOrder[0] = "hls") {
|
|
689
|
-
//do not play again if it's hls because it play last seconds again, let the server clear it
|
|
690
|
-
setTimeout(() => {
|
|
691
|
-
this.playIfExists(this.playOrder[0]);
|
|
692
|
-
}, 10000);
|
|
693
|
-
} else {
|
|
694
|
-
this.playIfExists(this.playOrder[0]);
|
|
695
|
-
}
|
|
696
|
-
//TODO: what if the stream is hls vod then it always re-play
|
|
697
|
-
} else {
|
|
698
|
-
//if iceConnected is false, it means that there is a networking issue for webrtc
|
|
699
|
-
this.tryNextTech();
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
if (this.playerListener != null) {
|
|
703
|
-
this.playerListener("ended");
|
|
704
|
-
}
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
//webrtc plugin sends play event. On the other hand, webrtc plugin sends ready event for every scenario.
|
|
708
|
-
//so no need to trust ready event for webrt play
|
|
709
|
-
this.videojsPlayer.on("play", () => {
|
|
710
|
-
this.setPlayerVisible(true);
|
|
711
|
-
if (this.playerListener != null) {
|
|
712
|
-
this.playerListener("play");
|
|
713
|
-
}
|
|
714
|
-
if (this.restJwt) {
|
|
715
|
-
this.isIpCameraBroadcast();
|
|
716
|
-
} else if (this.isIPCamera) {
|
|
717
|
-
this.injectPtzElements();
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
this.videojsPlayer.on("playing", () => {
|
|
721
|
-
if (this.playerListener != null) {
|
|
722
|
-
this.playerListener("playing");
|
|
723
|
-
}
|
|
724
|
-
});
|
|
725
|
-
this.videojsPlayer.on("timeupdate", () => {
|
|
726
|
-
if (this.playerListener != null) {
|
|
727
|
-
this.playerListener("timeupdate");
|
|
728
|
-
}
|
|
729
|
-
});
|
|
730
|
-
this.videojsPlayer.on("pause", () => {
|
|
731
|
-
if (this.playerListener != null) {
|
|
732
|
-
this.playerListener("pause");
|
|
733
|
-
}
|
|
734
|
-
});
|
|
673
|
+
this.listenPlayerEvents();
|
|
735
674
|
this.iceConnected = false;
|
|
736
675
|
this.videojsPlayer.src({
|
|
737
676
|
src: streamUrl,
|
|
@@ -755,6 +694,109 @@
|
|
|
755
694
|
});
|
|
756
695
|
}
|
|
757
696
|
}
|
|
697
|
+
listenPlayerEvents() {
|
|
698
|
+
this.playerEvents.forEach(event => {
|
|
699
|
+
this.videojsPlayer.on(event, eventData => {
|
|
700
|
+
switch (event) {
|
|
701
|
+
case 'play':
|
|
702
|
+
this.setPlayerVisible(true);
|
|
703
|
+
if (this.playerListener != null) {
|
|
704
|
+
this.playerListener("play");
|
|
705
|
+
}
|
|
706
|
+
if (this.restJwt) {
|
|
707
|
+
this.isIpCameraBroadcast();
|
|
708
|
+
} else if (this.isIPCamera) {
|
|
709
|
+
this.injectPtzElements();
|
|
710
|
+
}
|
|
711
|
+
break;
|
|
712
|
+
case 'ended':
|
|
713
|
+
//reinit to play after it ends
|
|
714
|
+
loglevel_min.Logger.warn("stream is ended");
|
|
715
|
+
this.setPlayerVisible(false);
|
|
716
|
+
//for webrtc, this event can be called by two reasons
|
|
717
|
+
//1. ice connection is not established, it means that there is a networking issug
|
|
718
|
+
//2. stream is ended
|
|
719
|
+
if (this.currentPlayType != "vod") {
|
|
720
|
+
//if it's vod, it means that stream is ended and no need to replay
|
|
721
|
+
|
|
722
|
+
if (this.iceConnected) {
|
|
723
|
+
//if iceConnected is true, it means that stream is really ended for webrtc
|
|
724
|
+
|
|
725
|
+
//initialize to play again if the publishing starts again
|
|
726
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
727
|
+
} else if (this.currentPlayType == "hls") {
|
|
728
|
+
//if it's hls, it means that stream is ended
|
|
729
|
+
|
|
730
|
+
this.setPlayerVisible(false);
|
|
731
|
+
if (this.playOrder[0] = "hls") {
|
|
732
|
+
//do not play again if it's hls because it play last seconds again, let the server clear it
|
|
733
|
+
setTimeout(() => {
|
|
734
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
735
|
+
}, 10000);
|
|
736
|
+
} else {
|
|
737
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
738
|
+
}
|
|
739
|
+
//TODO: what if the stream is hls vod then it always re-play
|
|
740
|
+
} else {
|
|
741
|
+
//if iceConnected is false, it means that there is a networking issue for webrtc
|
|
742
|
+
this.tryNextTech();
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (this.playerListener != null) {
|
|
746
|
+
this.playerListener(event);
|
|
747
|
+
}
|
|
748
|
+
break;
|
|
749
|
+
case 'timeupdate':
|
|
750
|
+
if (this.playerListener != null) {
|
|
751
|
+
this.playerListener(event, eventData, {
|
|
752
|
+
currentTime: this.videojsPlayer.currentTime()
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
break;
|
|
756
|
+
case 'progress':
|
|
757
|
+
if (this.playerListener != null) {
|
|
758
|
+
this.playerListener(event, eventData, {
|
|
759
|
+
bufferedPercent: this.videojsPlayer.bufferedPercent()
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
break;
|
|
763
|
+
case 'volumechange':
|
|
764
|
+
if (this.playerListener != null) {
|
|
765
|
+
this.playerListener(event, eventData, {
|
|
766
|
+
volume: this.videojsPlayer.volume(),
|
|
767
|
+
muted: this.videojsPlayer.muted()
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
break;
|
|
771
|
+
case 'ratechange':
|
|
772
|
+
if (this.playerListener != null) {
|
|
773
|
+
this.playerListener(event, eventData, {
|
|
774
|
+
playbackRate: this.videojsPlayer.playbackRate()
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
break;
|
|
778
|
+
case 'error':
|
|
779
|
+
loglevel_min.Logger.warn("There is an error in playback: ", eventData);
|
|
780
|
+
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
781
|
+
if (!this.errorCalled) {
|
|
782
|
+
this.errorCalled = true;
|
|
783
|
+
setTimeout(() => {
|
|
784
|
+
this.tryNextTech();
|
|
785
|
+
this.errorCalled = false;
|
|
786
|
+
}, 2500);
|
|
787
|
+
}
|
|
788
|
+
if (this.playerListener != null) {
|
|
789
|
+
this.playerListener("error", eventData);
|
|
790
|
+
}
|
|
791
|
+
break;
|
|
792
|
+
default:
|
|
793
|
+
if (this.playerListener != null) {
|
|
794
|
+
this.playerListener(event, eventData);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
});
|
|
799
|
+
}
|
|
758
800
|
listenForID3MetaData() {
|
|
759
801
|
this.videojsPlayer.textTracks().on('addtrack', e => {
|
|
760
802
|
var metadataTrack = Array.from(this.videojsPlayer.textTracks()).find(t => t.label === 'Timed Metadata');
|
|
@@ -847,15 +889,26 @@
|
|
|
847
889
|
this.destroyDashPlayer();
|
|
848
890
|
this.destroyVideoJSPlayer();
|
|
849
891
|
this.setPlayerVisible(false);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
892
|
+
|
|
893
|
+
//before changing play type, let's check if there is any backup stream
|
|
894
|
+
var playTypeIndex = this.playOrder.indexOf(this.currentPlayType);
|
|
895
|
+
if (this.activeStreamId == this.streamId && this.backupStreamId != null) {
|
|
896
|
+
//update active stream id to backup stream id
|
|
897
|
+
this.activeStreamId = this.backupStreamId;
|
|
898
|
+
//don't update playTypeIndex because we're trying backup stream with the same play type
|
|
853
899
|
} else {
|
|
854
|
-
|
|
900
|
+
//reset the activeStreamId back to streamId
|
|
901
|
+
this.activeStreamId = this.streamId;
|
|
902
|
+
//update the playTypeIndex to try next tech
|
|
903
|
+
if (playTypeIndex == -1 || playTypeIndex == this.playOrder.length - 1) {
|
|
904
|
+
playTypeIndex = 0;
|
|
905
|
+
} else {
|
|
906
|
+
playTypeIndex++;
|
|
907
|
+
}
|
|
855
908
|
}
|
|
856
909
|
this.tryNextTechTimer = setTimeout(() => {
|
|
857
910
|
this.tryNextTechTimer = -1;
|
|
858
|
-
this.playIfExists(this.playOrder[
|
|
911
|
+
this.playIfExists(this.playOrder[playTypeIndex], this.activeStreamId);
|
|
859
912
|
}, 3000);
|
|
860
913
|
} else {
|
|
861
914
|
loglevel_min.Logger.debug("tryNextTech is already scheduled no need to schedule again");
|
|
@@ -923,10 +976,10 @@
|
|
|
923
976
|
if (this.playOrder[0] = "dash") {
|
|
924
977
|
//do not play again if it's dash because it play last seconds again, let the server clear it
|
|
925
978
|
setTimeout(() => {
|
|
926
|
-
this.playIfExists(this.playOrder[0]);
|
|
979
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
927
980
|
}, 10000);
|
|
928
981
|
} else {
|
|
929
|
-
this.playIfExists(this.playOrder[0]);
|
|
982
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
930
983
|
}
|
|
931
984
|
if (this.playerListener != null) {
|
|
932
985
|
this.playerListener("ended");
|
|
@@ -1013,7 +1066,7 @@
|
|
|
1013
1066
|
* play the stream with the given tech
|
|
1014
1067
|
* @param {string} tech
|
|
1015
1068
|
*/
|
|
1016
|
-
playIfExists(tech) {
|
|
1069
|
+
playIfExists(tech, streamIdToPlay) {
|
|
1017
1070
|
var _this = this;
|
|
1018
1071
|
return _asyncToGenerator(function* () {
|
|
1019
1072
|
_this.currentPlayType = tech;
|
|
@@ -1021,70 +1074,73 @@
|
|
|
1021
1074
|
_this.destroyDashPlayer();
|
|
1022
1075
|
_this.setPlayerVisible(false);
|
|
1023
1076
|
_this.containerElement.innerHTML = _this.videoHTMLContent;
|
|
1024
|
-
loglevel_min.Logger.warn("Try to play the stream " +
|
|
1077
|
+
loglevel_min.Logger.warn("Try to play the stream " + streamIdToPlay + " with " + _this.currentPlayType);
|
|
1025
1078
|
switch (_this.currentPlayType) {
|
|
1026
1079
|
case "hls":
|
|
1027
1080
|
//TODO: Test case for hls
|
|
1028
1081
|
//1. Play stream with adaptive m3u8 for live and VoD
|
|
1029
1082
|
//2. Play stream with m3u8 for live and VoD
|
|
1030
1083
|
//3. if files are not available check nextTech is being called
|
|
1031
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1084
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, WebPlayer.HLS_EXTENSION).then(streamPath => {
|
|
1032
1085
|
_this.playWithVideoJS(streamPath, WebPlayer.HLS_EXTENSION);
|
|
1033
1086
|
loglevel_min.Logger.warn("incoming stream path: " + streamPath);
|
|
1034
1087
|
}).catch(error => {
|
|
1035
|
-
loglevel_min.Logger.warn("HLS stream resource not available for stream:" +
|
|
1088
|
+
loglevel_min.Logger.warn("HLS stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1036
1089
|
_this.tryNextTech();
|
|
1037
1090
|
});
|
|
1038
1091
|
case "ll-hls":
|
|
1039
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER + "/" + WebPlayer.LL_HLS_FOLDER,
|
|
1092
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER + "/" + WebPlayer.LL_HLS_FOLDER, streamIdToPlay, WebPlayer.HLS_EXTENSION).then(streamPath => {
|
|
1040
1093
|
_this.playWithVideoJS(streamPath, WebPlayer.HLS_EXTENSION);
|
|
1041
1094
|
loglevel_min.Logger.warn("incoming stream path: " + streamPath);
|
|
1042
1095
|
}).catch(error => {
|
|
1043
|
-
loglevel_min.Logger.warn("LL-HLS stream resource not available for stream:" +
|
|
1096
|
+
loglevel_min.Logger.warn("LL-HLS stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1044
1097
|
_this.tryNextTech();
|
|
1045
1098
|
});
|
|
1046
1099
|
case "dash":
|
|
1047
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1100
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay + "/" + streamIdToPlay, WebPlayer.DASH_EXTENSION).then(streamPath => {
|
|
1048
1101
|
_this.playViaDash(streamPath);
|
|
1049
1102
|
}).catch(error => {
|
|
1050
|
-
loglevel_min.Logger.warn("DASH stream resource not available for stream:" +
|
|
1103
|
+
loglevel_min.Logger.warn("DASH stream resource not available for stream:" + streamIdToPlay + " error is " + error + ". Try next play tech");
|
|
1051
1104
|
_this.tryNextTech();
|
|
1052
1105
|
});
|
|
1053
1106
|
case "webrtc":
|
|
1054
|
-
return _this.playWithVideoJS(_this.addSecurityParams(_this.
|
|
1107
|
+
return _this.playWithVideoJS(_this.addSecurityParams(_this.getWebsocketURLForStream(streamIdToPlay)), WebPlayer.WEBRTC_EXTENSION);
|
|
1055
1108
|
case "vod":
|
|
1056
1109
|
//TODO: Test case for vod
|
|
1057
1110
|
//1. Play stream with mp4 for VoD
|
|
1058
1111
|
//2. Play stream with webm for VoD
|
|
1059
1112
|
//3. Play stream with playOrder type
|
|
1060
1113
|
|
|
1061
|
-
var lastIndexOfDot =
|
|
1114
|
+
var lastIndexOfDot = streamIdToPlay.lastIndexOf(".");
|
|
1062
1115
|
var extension;
|
|
1063
1116
|
if (lastIndexOfDot != -1) {
|
|
1064
1117
|
//if there is a dot in the streamId, it means that this is extension, use it. make the extension empty
|
|
1065
1118
|
_this.playType[0] = "";
|
|
1066
|
-
extension =
|
|
1119
|
+
extension = streamIdToPlay.substring(lastIndexOfDot + 1);
|
|
1067
1120
|
} else {
|
|
1068
1121
|
//we need to give extension to playWithVideoJS
|
|
1069
1122
|
extension = _this.playType[0];
|
|
1070
1123
|
}
|
|
1071
|
-
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1124
|
+
return _this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, _this.playType[0]).then(streamPath => {
|
|
1072
1125
|
//we need to give extension to playWithVideoJS
|
|
1073
1126
|
_this.playWithVideoJS(streamPath, extension);
|
|
1074
1127
|
}).catch(error => {
|
|
1075
|
-
loglevel_min.Logger.warn("VOD stream resource not available for stream:" +
|
|
1128
|
+
loglevel_min.Logger.warn("VOD stream resource not available for stream:" + streamIdToPlay + " and play type " + _this.playType[0] + ". Error is " + error);
|
|
1076
1129
|
if (_this.playType.length > 1) {
|
|
1077
1130
|
loglevel_min.Logger.warn("Try next play type which is " + _this.playType[1] + ".");
|
|
1078
|
-
_this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER,
|
|
1131
|
+
_this.checkStreamExistsViaHttp(WebPlayer.STREAMS_FOLDER, streamIdToPlay, _this.playType[1]).then(streamPath => {
|
|
1079
1132
|
_this.playWithVideoJS(streamPath, _this.playType[1]);
|
|
1080
1133
|
}).catch(error => {
|
|
1081
|
-
loglevel_min.Logger.warn("VOD stream resource not available for stream:" +
|
|
1134
|
+
loglevel_min.Logger.warn("VOD stream resource not available for stream:" + streamIdToPlay + " and play type error is " + error);
|
|
1082
1135
|
});
|
|
1083
1136
|
}
|
|
1084
1137
|
});
|
|
1085
1138
|
}
|
|
1086
1139
|
})();
|
|
1087
1140
|
}
|
|
1141
|
+
getWebsocketURLForStream(streamIdToPlay) {
|
|
1142
|
+
return this.websocketBaseURL + streamIdToPlay + ".webrtc";
|
|
1143
|
+
}
|
|
1088
1144
|
|
|
1089
1145
|
/**
|
|
1090
1146
|
*
|
|
@@ -1108,10 +1164,12 @@
|
|
|
1108
1164
|
* play the stream with videojs player or dash player
|
|
1109
1165
|
*/
|
|
1110
1166
|
play() {
|
|
1111
|
-
if
|
|
1167
|
+
//if there is a request to play, try original stream first
|
|
1168
|
+
this.activeStreamId = this.streamId;
|
|
1169
|
+
if (this.activeStreamId.startsWith(WebPlayer.STREAMS_FOLDER)) {
|
|
1112
1170
|
//start videojs player because it directly try to play stream from streams folder
|
|
1113
|
-
var lastIndexOfDot = this.
|
|
1114
|
-
var extension = this.
|
|
1171
|
+
var lastIndexOfDot = this.activeStreamId.lastIndexOf(".");
|
|
1172
|
+
var extension = this.activeStreamId.substring(lastIndexOfDot + 1);
|
|
1115
1173
|
this.playOrder = ["vod"];
|
|
1116
1174
|
this.currentPlayType = this.playOrder[0];
|
|
1117
1175
|
if (!this.httpBaseURL.endsWith("/")) {
|
|
@@ -1119,12 +1177,12 @@
|
|
|
1119
1177
|
}
|
|
1120
1178
|
this.containerElement.innerHTML = this.videoHTMLContent;
|
|
1121
1179
|
if (extension == WebPlayer.DASH_EXTENSION) {
|
|
1122
|
-
this.playViaDash(this.httpBaseURL + this.addSecurityParams(this.
|
|
1180
|
+
this.playViaDash(this.httpBaseURL + this.addSecurityParams(this.activeStreamId), extension);
|
|
1123
1181
|
} else {
|
|
1124
|
-
this.playWithVideoJS(this.httpBaseURL + this.addSecurityParams(this.
|
|
1182
|
+
this.playWithVideoJS(this.httpBaseURL + this.addSecurityParams(this.activeStreamId), extension);
|
|
1125
1183
|
}
|
|
1126
1184
|
} else {
|
|
1127
|
-
this.playIfExists(this.playOrder[0]);
|
|
1185
|
+
this.playIfExists(this.playOrder[0], this.activeStreamId);
|
|
1128
1186
|
}
|
|
1129
1187
|
}
|
|
1130
1188
|
|
|
@@ -1188,7 +1246,7 @@
|
|
|
1188
1246
|
return false;
|
|
1189
1247
|
}
|
|
1190
1248
|
injectPtzElements() {
|
|
1191
|
-
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 ";
|
|
1249
|
+
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 ";
|
|
1192
1250
|
var ptzCameraContainer = document.getElementById("ptz-camera-container");
|
|
1193
1251
|
if (ptzCameraContainer) {
|
|
1194
1252
|
loglevel_min.Logger.info("PTZ controls are already injected");
|
|
@@ -1315,6 +1373,7 @@
|
|
|
1315
1373
|
}
|
|
1316
1374
|
}
|
|
1317
1375
|
}
|
|
1376
|
+
_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']);
|
|
1318
1377
|
_defineProperty(WebPlayer, "DEFAULT_PLAY_ORDER", ["webrtc", "hls"]);
|
|
1319
1378
|
_defineProperty(WebPlayer, "DEFAULT_PLAY_TYPE", ["mp4", "webm"]);
|
|
1320
1379
|
_defineProperty(WebPlayer, "HLS_EXTENSION", "m3u8");
|
package/dist/es/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
|