@antmedia/web_player 2.8.2 → 2.8.3-ALPHA-29-03-2024
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 +2 -1
- package/README.md +47 -35
- package/dist/browser/web_player.js +49 -13
- package/dist/es/index.d.ts +6 -2
- package/dist/es/web_player.js +49 -13
- package/dist/index.d.ts +9 -3
- package/dist/web_player.js +49 -13
- package/package.json +1 -1
- package/src/web_player.js +65 -21
- package/test/embedded-player.test.js +113 -6
- package/.project +0 -17
- package/.settings/.jsdtscope +0 -7
- package/.settings/org.eclipse.wst.jsdt.ui.superType.container +0 -1
- package/.settings/org.eclipse.wst.jsdt.ui.superType.name +0 -1
|
@@ -22,7 +22,8 @@ jobs:
|
|
|
22
22
|
- run: npm install --include=dev
|
|
23
23
|
- run: npm run compile
|
|
24
24
|
- run: npm test
|
|
25
|
-
|
|
25
|
+
#Fix this versioning for the snapshots
|
|
26
|
+
- run: npm version 2.8.3-SNAPSHOT"-`date +"%Y-%b-%d-%I-%M"`" --no-git-tag-version
|
|
26
27
|
- run: npm publish --tag SNAPSHOT
|
|
27
28
|
env:
|
|
28
29
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
package/README.md
CHANGED
|
@@ -20,59 +20,71 @@ Install the Web Player package using npm:
|
|
|
20
20
|
npm i @antmedia/web_player
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
## Configuration Parameters
|
|
24
|
-
|
|
25
|
-
The player accepts several configuration parameters, either through the URL or directly in the code:
|
|
26
|
-
|
|
27
|
-
1. `id` (String): The stream ID to play. This parameter is mandatory.
|
|
28
|
-
2. `token` (String): The token for stream access. It's mandatory if token security is enabled on the server side.
|
|
29
|
-
3. `autoplay` (Boolean): Autoplay the stream if available. Optional. Default value is `true`.
|
|
30
|
-
4. `mute` (Boolean): Start playing in mute mode if the stream is available. Optional. Default value is `true`.
|
|
31
|
-
5. `playOrder` (String): The order of technologies used for playing. Optional. Default value is `"webrtc,hls"`. Possible values include `"hls,webrtc"`, `"webrtc"`, `"hls"`, `"vod"`, `"dash"`.
|
|
32
|
-
6. `playType` (String): The order of play types used for playing. Optional. Default value is `"mp4,webm"`. Possible values include `"webm,mp4"`, `"mp4"`, `"webm"`, `"mov"`.
|
|
33
|
-
7. `targetLatency` (Number): The target latency for the DASH player. Optional. Default value is `3`.
|
|
34
|
-
8. `is360` (Boolean): Enable playback in 360 mode. Optional. Default value is `false`.
|
|
35
|
-
|
|
36
23
|
## Usage
|
|
37
24
|
|
|
38
25
|
### Basic Usage
|
|
39
26
|
|
|
40
|
-
|
|
27
|
+
To use the Web Player, import it and initialize it with the parameters received from the URL. Refer to the Configuration Parameters section below for more details.
|
|
41
28
|
|
|
42
|
-
|
|
43
|
-
import { WebPlayer } from "@antmedia/web_player";
|
|
29
|
+
1. In your web application, create a div with the id video_container. This will serve as the container for the player.
|
|
44
30
|
|
|
45
|
-
|
|
31
|
+
```
|
|
32
|
+
<div id="video_container" ></div>
|
|
33
|
+
````
|
|
34
|
+
|
|
35
|
+
2. Initialize the player as follows:
|
|
36
|
+
```javascript
|
|
37
|
+
import { WebPlayer } from "@antmedia/web_player";
|
|
46
38
|
|
|
47
|
-
embeddedPlayer
|
|
39
|
+
var embeddedPlayer = new WebPlayer(window, document.getElementById("video_container"), null);
|
|
40
|
+
|
|
41
|
+
embeddedPlayer.initialize().then(() => {
|
|
48
42
|
embeddedPlayer.play();
|
|
49
|
-
});
|
|
50
|
-
```
|
|
43
|
+
});
|
|
44
|
+
```
|
|
51
45
|
|
|
52
46
|
The sample for this usage is available in [play.html in StreamApp](https://github.com/ant-media/StreamApp/blob/master/src/main/webapp/play.html)
|
|
53
47
|
|
|
54
48
|
### Advanced Usage
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
Alternatively, you can pass the parameters as an object to the WebPlayer constructor.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
1. In your web application, create a div with the id video_container. This will serve as the container for the player.
|
|
53
|
+
```
|
|
54
|
+
<div id="video_container" ></div>
|
|
55
|
+
````
|
|
56
|
+
|
|
57
|
+
2. Initialize the player as follows
|
|
58
|
+
```javascript
|
|
59
|
+
var player = new WebPlayer({
|
|
60
|
+
streamId: "myStreamId",
|
|
61
|
+
httpBaseURL: "http://example.antmedia.io:5080/WebRTCAppEE/", //Remember to add trailing slash(/)
|
|
62
|
+
}, document.getElementById("video_container"), null);
|
|
63
|
+
|
|
64
|
+
player.initialize().then(() => {
|
|
67
65
|
player.play();
|
|
68
|
-
}).catch((error) => {
|
|
66
|
+
}).catch((error) => {
|
|
69
67
|
console.error("Error while initializing embedded player: " + error);
|
|
70
|
-
});
|
|
71
|
-
```
|
|
68
|
+
});
|
|
69
|
+
```
|
|
72
70
|
|
|
73
71
|
The sample for this usage is available in [app.page.component.ts in Ant-Media-Management-Console](https://github.com/ant-media/Ant-Media-Management-Console/blob/master/src/app/app.page/app.page.component.ts)
|
|
74
72
|
|
|
75
73
|
|
|
74
|
+
## Configuration Parameters
|
|
75
|
+
|
|
76
|
+
The player accepts several configuration parameters, either through the URL or directly in the code:
|
|
77
|
+
|
|
78
|
+
1. `id` (String): The stream ID to play. This parameter is mandatory.
|
|
79
|
+
2. `token` (String): The token for stream access. It's mandatory if token security is enabled on the server side.
|
|
80
|
+
3. `autoplay` (Boolean): Autoplay the stream if available. Optional. Default value is `true`.
|
|
81
|
+
4. `mute` (Boolean): Start playing in mute mode if the stream is available. Optional. Default value is `true`.
|
|
82
|
+
5. `playOrder` (String): The order of technologies used for playing. Optional. Default value is `"webrtc,hls"`. Possible values include `"hls,webrtc"`, `"webrtc"`, `"hls"`, `"vod"`, `"dash"`.
|
|
83
|
+
6. `playType` (String): The order of play types used for playing. Optional. Default value is `"mp4,webm"`. Possible values include `"webm,mp4"`, `"mp4"`, `"webm"`, `"mov"`.
|
|
84
|
+
7. `targetLatency` (Number): The target latency for the DASH player. Optional. Default value is `3`.
|
|
85
|
+
8. `is360` (Boolean): Enable playback in 360 mode. Optional. Default value is `false`.
|
|
86
|
+
|
|
87
|
+
|
|
76
88
|
## Support
|
|
77
89
|
For support and further inquiries, please visit [Ant Media Server's community](https://github.com/orgs/ant-media/discussions). If you are an enterprise user, you can receive support by sending an email to support@antmedia.io.
|
|
78
90
|
|
|
@@ -112,11 +112,14 @@
|
|
|
112
112
|
*/
|
|
113
113
|
_defineProperty(this, "autoPlay", true);
|
|
114
114
|
/**
|
|
115
|
-
* mute: if
|
|
116
|
-
* default value is true because of browser's autoplay policy.
|
|
115
|
+
* mute: if false the player will try to auto play the stream with audio if it fails player will mute the audio and try again to autoplay it.
|
|
117
116
|
* It will be taken from url parameter "mute".
|
|
118
117
|
*/
|
|
119
|
-
_defineProperty(this, "mute",
|
|
118
|
+
_defineProperty(this, "mute", false);
|
|
119
|
+
/**
|
|
120
|
+
* Force the Player to play with audio Auto Play might not work.
|
|
121
|
+
*/
|
|
122
|
+
_defineProperty(this, "forcePlayWithAudio", false);
|
|
120
123
|
/**
|
|
121
124
|
* targetLatency: target latency in seconds. Optional. Default value is 3.
|
|
122
125
|
* It will be taken from url parameter "targetLatency".
|
|
@@ -293,7 +296,7 @@
|
|
|
293
296
|
this.playType = WebPlayer.DEFAULT_PLAY_TYPE;
|
|
294
297
|
this.token = null;
|
|
295
298
|
this.autoPlay = true;
|
|
296
|
-
this.mute =
|
|
299
|
+
this.mute = false;
|
|
297
300
|
this.targetLatency = 3;
|
|
298
301
|
this.subscriberId = null;
|
|
299
302
|
this.subscriberCode = null;
|
|
@@ -317,6 +320,7 @@
|
|
|
317
320
|
this.dashjsLoaded = false;
|
|
318
321
|
this.containerElementInitialDisplay = "block";
|
|
319
322
|
this.placeHolderElementInitialDisplay = "block";
|
|
323
|
+
this.forcePlayWithAudio = false;
|
|
320
324
|
}
|
|
321
325
|
initializeFromUrlParams() {
|
|
322
326
|
var _getUrlParameter;
|
|
@@ -342,7 +346,9 @@
|
|
|
342
346
|
var muteLocal = fetch_stream.getUrlParameter("mute", this.window.location.search);
|
|
343
347
|
if (muteLocal === "false") {
|
|
344
348
|
this.mute = false;
|
|
345
|
-
|
|
349
|
+
//user specifically asks to play with audio so if it fails in auto play, it will not try to play without audio
|
|
350
|
+
this.forcePlayWithAudio = true;
|
|
351
|
+
} else if (muteLocal === "true") {
|
|
346
352
|
this.mute = true;
|
|
347
353
|
}
|
|
348
354
|
var localTargetLatency = fetch_stream.getUrlParameter("targetLatency", this.window.location.search);
|
|
@@ -514,7 +520,7 @@
|
|
|
514
520
|
autoplay: this.autoPlay
|
|
515
521
|
});
|
|
516
522
|
this.videojsPlayer.on('error', e => {
|
|
517
|
-
loglevel_min.Logger.warn("There is an error in playback: "
|
|
523
|
+
loglevel_min.Logger.warn("There is an error in playback: ", e);
|
|
518
524
|
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
519
525
|
if (!this.errorCalled) {
|
|
520
526
|
this.errorCalled = true;
|
|
@@ -559,15 +565,21 @@
|
|
|
559
565
|
//hls specific calls
|
|
560
566
|
if (extension == "m3u8") {
|
|
561
567
|
videojs.Vhs.xhr.beforeRequest = options => {
|
|
562
|
-
var
|
|
563
|
-
if (!options.uri.includes(
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
+
var queryParams = [];
|
|
569
|
+
if (!options.uri.includes("subscriberId") && this.subscriberId != null) {
|
|
570
|
+
queryParams.push("subscriberId=".concat(this.subscriberId));
|
|
571
|
+
}
|
|
572
|
+
if (!options.uri.includes("subscriberCode") && this.subscriberCode != null) {
|
|
573
|
+
queryParams.push("subscriberCode=".concat(this.subscriberCode));
|
|
574
|
+
}
|
|
575
|
+
if (!options.uri.includes("token") && this.token != null) {
|
|
576
|
+
queryParams.push("token=".concat(this.token));
|
|
577
|
+
}
|
|
578
|
+
if (queryParams.length > 0) {
|
|
579
|
+
var queryString = queryParams.join("&");
|
|
580
|
+
options.uri += options.uri.includes("?") ? "&".concat(queryString) : "?".concat(queryString);
|
|
568
581
|
}
|
|
569
582
|
loglevel_min.Logger.debug("hls request: " + options.uri);
|
|
570
|
-
return options;
|
|
571
583
|
};
|
|
572
584
|
this.videojsPlayer.ready(() => {
|
|
573
585
|
// If it's already added to player, no need to add again
|
|
@@ -654,7 +666,16 @@
|
|
|
654
666
|
reconnect: false //webrtc adaptor has auto reconnect scenario, just disable it, we manage it here
|
|
655
667
|
});
|
|
656
668
|
if (this.autoPlay) {
|
|
669
|
+
//try to play directly
|
|
657
670
|
this.videojsPlayer.play().catch(e => {
|
|
671
|
+
//if it's not allowed error and default value are being used, try to play it muted
|
|
672
|
+
//if this.forcePlayWithAudio is true, it means user specifically ask to do.
|
|
673
|
+
// If it's false, it's default value so that we can proceed to try to play with muted
|
|
674
|
+
//This implementation is added because of auto play policy of the browsers
|
|
675
|
+
if (e.name === "NotAllowedError" && !this.forcePlayWithAudio) {
|
|
676
|
+
this.videojsPlayer.muted(true);
|
|
677
|
+
this.videojsPlayer.play();
|
|
678
|
+
}
|
|
658
679
|
loglevel_min.Logger.warn("Problem in playback. The error is " + e);
|
|
659
680
|
});
|
|
660
681
|
}
|
|
@@ -814,11 +835,26 @@
|
|
|
814
835
|
}
|
|
815
836
|
});
|
|
816
837
|
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, event => {
|
|
838
|
+
loglevel_min.Logger.warn("dash playback error: " + event);
|
|
817
839
|
this.tryNextTech();
|
|
818
840
|
});
|
|
819
841
|
this.dashPlayer.on(dashjs.MediaPlayer.events.ERROR, event => {
|
|
842
|
+
loglevel_min.Logger.warn("error: " + event);
|
|
820
843
|
this.tryNextTech();
|
|
821
844
|
});
|
|
845
|
+
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_NOT_ALLOWED, event => {
|
|
846
|
+
loglevel_min.Logger.warn("dash playback not allowed: " + event);
|
|
847
|
+
this.handleDashPlayBackNotAllowed();
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
handleDashPlayBackNotAllowed() {
|
|
851
|
+
if (!this.forcePlayWithAudio) {
|
|
852
|
+
loglevel_min.Logger.info("Try to play with muted audio");
|
|
853
|
+
this.dashPlayer.setMute(true);
|
|
854
|
+
this.dashPlayer.play();
|
|
855
|
+
} else {
|
|
856
|
+
this.tryNextTech();
|
|
857
|
+
}
|
|
822
858
|
}
|
|
823
859
|
makeDashPlayerVisibleWhenInitialized() {
|
|
824
860
|
this.dashPlayer.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, event => {
|
package/dist/es/index.d.ts
CHANGED
|
@@ -55,11 +55,14 @@ export declare class WebPlayer {
|
|
|
55
55
|
*/
|
|
56
56
|
autoPlay: boolean;
|
|
57
57
|
/**
|
|
58
|
-
* mute: if
|
|
59
|
-
* default value is true because of browser's autoplay policy.
|
|
58
|
+
* mute: if false the player will try to auto play the stream with audio if it fails player will mute the audio and try again to autoplay it.
|
|
60
59
|
* It will be taken from url parameter "mute".
|
|
61
60
|
*/
|
|
62
61
|
mute: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Force the Player to play with audio Auto Play might not work.
|
|
64
|
+
*/
|
|
65
|
+
forcePlayWithAudio: boolean;
|
|
63
66
|
/**
|
|
64
67
|
* targetLatency: target latency in seconds. Optional. Default value is 3.
|
|
65
68
|
* It will be taken from url parameter "targetLatency".
|
|
@@ -176,6 +179,7 @@ export declare class WebPlayer {
|
|
|
176
179
|
*/
|
|
177
180
|
playViaDash(streamUrl: any): void;
|
|
178
181
|
dashLatencyTimer: NodeJS.Timeout | undefined;
|
|
182
|
+
handleDashPlayBackNotAllowed(): void;
|
|
179
183
|
makeDashPlayerVisibleWhenInitialized(): void;
|
|
180
184
|
/**
|
|
181
185
|
* destroy the dash player
|
package/dist/es/web_player.js
CHANGED
|
@@ -400,11 +400,14 @@ class WebPlayer {
|
|
|
400
400
|
*/
|
|
401
401
|
_defineProperty(this, "autoPlay", true);
|
|
402
402
|
/**
|
|
403
|
-
* mute: if
|
|
404
|
-
* default value is true because of browser's autoplay policy.
|
|
403
|
+
* mute: if false the player will try to auto play the stream with audio if it fails player will mute the audio and try again to autoplay it.
|
|
405
404
|
* It will be taken from url parameter "mute".
|
|
406
405
|
*/
|
|
407
|
-
_defineProperty(this, "mute",
|
|
406
|
+
_defineProperty(this, "mute", false);
|
|
407
|
+
/**
|
|
408
|
+
* Force the Player to play with audio Auto Play might not work.
|
|
409
|
+
*/
|
|
410
|
+
_defineProperty(this, "forcePlayWithAudio", false);
|
|
408
411
|
/**
|
|
409
412
|
* targetLatency: target latency in seconds. Optional. Default value is 3.
|
|
410
413
|
* It will be taken from url parameter "targetLatency".
|
|
@@ -581,7 +584,7 @@ class WebPlayer {
|
|
|
581
584
|
this.playType = WebPlayer.DEFAULT_PLAY_TYPE;
|
|
582
585
|
this.token = null;
|
|
583
586
|
this.autoPlay = true;
|
|
584
|
-
this.mute =
|
|
587
|
+
this.mute = false;
|
|
585
588
|
this.targetLatency = 3;
|
|
586
589
|
this.subscriberId = null;
|
|
587
590
|
this.subscriberCode = null;
|
|
@@ -605,6 +608,7 @@ class WebPlayer {
|
|
|
605
608
|
this.dashjsLoaded = false;
|
|
606
609
|
this.containerElementInitialDisplay = "block";
|
|
607
610
|
this.placeHolderElementInitialDisplay = "block";
|
|
611
|
+
this.forcePlayWithAudio = false;
|
|
608
612
|
}
|
|
609
613
|
initializeFromUrlParams() {
|
|
610
614
|
var _getUrlParameter;
|
|
@@ -630,7 +634,9 @@ class WebPlayer {
|
|
|
630
634
|
var muteLocal = getUrlParameter_1("mute", this.window.location.search);
|
|
631
635
|
if (muteLocal === "false") {
|
|
632
636
|
this.mute = false;
|
|
633
|
-
|
|
637
|
+
//user specifically asks to play with audio so if it fails in auto play, it will not try to play without audio
|
|
638
|
+
this.forcePlayWithAudio = true;
|
|
639
|
+
} else if (muteLocal === "true") {
|
|
634
640
|
this.mute = true;
|
|
635
641
|
}
|
|
636
642
|
var localTargetLatency = getUrlParameter_1("targetLatency", this.window.location.search);
|
|
@@ -802,7 +808,7 @@ class WebPlayer {
|
|
|
802
808
|
autoplay: this.autoPlay
|
|
803
809
|
});
|
|
804
810
|
this.videojsPlayer.on('error', e => {
|
|
805
|
-
Logger_1.warn("There is an error in playback: "
|
|
811
|
+
Logger_1.warn("There is an error in playback: ", e);
|
|
806
812
|
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
807
813
|
if (!this.errorCalled) {
|
|
808
814
|
this.errorCalled = true;
|
|
@@ -847,15 +853,21 @@ class WebPlayer {
|
|
|
847
853
|
//hls specific calls
|
|
848
854
|
if (extension == "m3u8") {
|
|
849
855
|
videojs.Vhs.xhr.beforeRequest = options => {
|
|
850
|
-
var
|
|
851
|
-
if (!options.uri.includes(
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
+
var queryParams = [];
|
|
857
|
+
if (!options.uri.includes("subscriberId") && this.subscriberId != null) {
|
|
858
|
+
queryParams.push("subscriberId=".concat(this.subscriberId));
|
|
859
|
+
}
|
|
860
|
+
if (!options.uri.includes("subscriberCode") && this.subscriberCode != null) {
|
|
861
|
+
queryParams.push("subscriberCode=".concat(this.subscriberCode));
|
|
862
|
+
}
|
|
863
|
+
if (!options.uri.includes("token") && this.token != null) {
|
|
864
|
+
queryParams.push("token=".concat(this.token));
|
|
865
|
+
}
|
|
866
|
+
if (queryParams.length > 0) {
|
|
867
|
+
var queryString = queryParams.join("&");
|
|
868
|
+
options.uri += options.uri.includes("?") ? "&".concat(queryString) : "?".concat(queryString);
|
|
856
869
|
}
|
|
857
870
|
Logger_1.debug("hls request: " + options.uri);
|
|
858
|
-
return options;
|
|
859
871
|
};
|
|
860
872
|
this.videojsPlayer.ready(() => {
|
|
861
873
|
// If it's already added to player, no need to add again
|
|
@@ -942,7 +954,16 @@ class WebPlayer {
|
|
|
942
954
|
reconnect: false //webrtc adaptor has auto reconnect scenario, just disable it, we manage it here
|
|
943
955
|
});
|
|
944
956
|
if (this.autoPlay) {
|
|
957
|
+
//try to play directly
|
|
945
958
|
this.videojsPlayer.play().catch(e => {
|
|
959
|
+
//if it's not allowed error and default value are being used, try to play it muted
|
|
960
|
+
//if this.forcePlayWithAudio is true, it means user specifically ask to do.
|
|
961
|
+
// If it's false, it's default value so that we can proceed to try to play with muted
|
|
962
|
+
//This implementation is added because of auto play policy of the browsers
|
|
963
|
+
if (e.name === "NotAllowedError" && !this.forcePlayWithAudio) {
|
|
964
|
+
this.videojsPlayer.muted(true);
|
|
965
|
+
this.videojsPlayer.play();
|
|
966
|
+
}
|
|
946
967
|
Logger_1.warn("Problem in playback. The error is " + e);
|
|
947
968
|
});
|
|
948
969
|
}
|
|
@@ -1102,11 +1123,26 @@ class WebPlayer {
|
|
|
1102
1123
|
}
|
|
1103
1124
|
});
|
|
1104
1125
|
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, event => {
|
|
1126
|
+
Logger_1.warn("dash playback error: " + event);
|
|
1105
1127
|
this.tryNextTech();
|
|
1106
1128
|
});
|
|
1107
1129
|
this.dashPlayer.on(dashjs.MediaPlayer.events.ERROR, event => {
|
|
1130
|
+
Logger_1.warn("error: " + event);
|
|
1108
1131
|
this.tryNextTech();
|
|
1109
1132
|
});
|
|
1133
|
+
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_NOT_ALLOWED, event => {
|
|
1134
|
+
Logger_1.warn("dash playback not allowed: " + event);
|
|
1135
|
+
this.handleDashPlayBackNotAllowed();
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
handleDashPlayBackNotAllowed() {
|
|
1139
|
+
if (!this.forcePlayWithAudio) {
|
|
1140
|
+
Logger_1.info("Try to play with muted audio");
|
|
1141
|
+
this.dashPlayer.setMute(true);
|
|
1142
|
+
this.dashPlayer.play();
|
|
1143
|
+
} else {
|
|
1144
|
+
this.tryNextTech();
|
|
1145
|
+
}
|
|
1110
1146
|
}
|
|
1111
1147
|
makeDashPlayerVisibleWhenInitialized() {
|
|
1112
1148
|
this.dashPlayer.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, event => {
|
package/dist/index.d.ts
CHANGED
|
@@ -55,11 +55,14 @@ export declare class WebPlayer {
|
|
|
55
55
|
*/
|
|
56
56
|
autoPlay: boolean;
|
|
57
57
|
/**
|
|
58
|
-
* mute: if
|
|
59
|
-
* default value is true because of browser's autoplay policy.
|
|
58
|
+
* mute: if false the player will try to auto play the stream with audio if it fails player will mute the audio and try again to autoplay it.
|
|
60
59
|
* It will be taken from url parameter "mute".
|
|
61
60
|
*/
|
|
62
61
|
mute: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Force the Player to play with audio Auto Play might not work.
|
|
64
|
+
*/
|
|
65
|
+
forcePlayWithAudio: boolean;
|
|
63
66
|
/**
|
|
64
67
|
* targetLatency: target latency in seconds. Optional. Default value is 3.
|
|
65
68
|
* It will be taken from url parameter "targetLatency".
|
|
@@ -122,8 +125,10 @@ export declare class WebPlayer {
|
|
|
122
125
|
* Field to keep if tryNextMethod is already called
|
|
123
126
|
*/
|
|
124
127
|
tryNextTechTimer: any;
|
|
125
|
-
|
|
128
|
+
containerElementInitialDisplay: any;
|
|
129
|
+
placeHolderElementInitialDisplay: any;
|
|
126
130
|
httpBaseURL: string;
|
|
131
|
+
websocketURL: any;
|
|
127
132
|
dom: any;
|
|
128
133
|
isWindow(configOrWindow: any): any;
|
|
129
134
|
initialize(): Promise<any>;
|
|
@@ -174,6 +179,7 @@ export declare class WebPlayer {
|
|
|
174
179
|
*/
|
|
175
180
|
playViaDash(streamUrl: any): void;
|
|
176
181
|
dashLatencyTimer: NodeJS.Timeout | undefined;
|
|
182
|
+
handleDashPlayBackNotAllowed(): void;
|
|
177
183
|
makeDashPlayerVisibleWhenInitialized(): void;
|
|
178
184
|
/**
|
|
179
185
|
* destroy the dash player
|
package/dist/web_player.js
CHANGED
|
@@ -402,11 +402,14 @@ class WebPlayer {
|
|
|
402
402
|
*/
|
|
403
403
|
_defineProperty(this, "autoPlay", true);
|
|
404
404
|
/**
|
|
405
|
-
* mute: if
|
|
406
|
-
* default value is true because of browser's autoplay policy.
|
|
405
|
+
* mute: if false the player will try to auto play the stream with audio if it fails player will mute the audio and try again to autoplay it.
|
|
407
406
|
* It will be taken from url parameter "mute".
|
|
408
407
|
*/
|
|
409
|
-
_defineProperty(this, "mute",
|
|
408
|
+
_defineProperty(this, "mute", false);
|
|
409
|
+
/**
|
|
410
|
+
* Force the Player to play with audio Auto Play might not work.
|
|
411
|
+
*/
|
|
412
|
+
_defineProperty(this, "forcePlayWithAudio", false);
|
|
410
413
|
/**
|
|
411
414
|
* targetLatency: target latency in seconds. Optional. Default value is 3.
|
|
412
415
|
* It will be taken from url parameter "targetLatency".
|
|
@@ -583,7 +586,7 @@ class WebPlayer {
|
|
|
583
586
|
this.playType = WebPlayer.DEFAULT_PLAY_TYPE;
|
|
584
587
|
this.token = null;
|
|
585
588
|
this.autoPlay = true;
|
|
586
|
-
this.mute =
|
|
589
|
+
this.mute = false;
|
|
587
590
|
this.targetLatency = 3;
|
|
588
591
|
this.subscriberId = null;
|
|
589
592
|
this.subscriberCode = null;
|
|
@@ -607,6 +610,7 @@ class WebPlayer {
|
|
|
607
610
|
this.dashjsLoaded = false;
|
|
608
611
|
this.containerElementInitialDisplay = "block";
|
|
609
612
|
this.placeHolderElementInitialDisplay = "block";
|
|
613
|
+
this.forcePlayWithAudio = false;
|
|
610
614
|
}
|
|
611
615
|
initializeFromUrlParams() {
|
|
612
616
|
var _getUrlParameter;
|
|
@@ -632,7 +636,9 @@ class WebPlayer {
|
|
|
632
636
|
var muteLocal = getUrlParameter_1("mute", this.window.location.search);
|
|
633
637
|
if (muteLocal === "false") {
|
|
634
638
|
this.mute = false;
|
|
635
|
-
|
|
639
|
+
//user specifically asks to play with audio so if it fails in auto play, it will not try to play without audio
|
|
640
|
+
this.forcePlayWithAudio = true;
|
|
641
|
+
} else if (muteLocal === "true") {
|
|
636
642
|
this.mute = true;
|
|
637
643
|
}
|
|
638
644
|
var localTargetLatency = getUrlParameter_1("targetLatency", this.window.location.search);
|
|
@@ -804,7 +810,7 @@ class WebPlayer {
|
|
|
804
810
|
autoplay: this.autoPlay
|
|
805
811
|
});
|
|
806
812
|
this.videojsPlayer.on('error', e => {
|
|
807
|
-
Logger_1.warn("There is an error in playback: "
|
|
813
|
+
Logger_1.warn("There is an error in playback: ", e);
|
|
808
814
|
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
809
815
|
if (!this.errorCalled) {
|
|
810
816
|
this.errorCalled = true;
|
|
@@ -849,15 +855,21 @@ class WebPlayer {
|
|
|
849
855
|
//hls specific calls
|
|
850
856
|
if (extension == "m3u8") {
|
|
851
857
|
videojs.Vhs.xhr.beforeRequest = options => {
|
|
852
|
-
var
|
|
853
|
-
if (!options.uri.includes(
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
+
var queryParams = [];
|
|
859
|
+
if (!options.uri.includes("subscriberId") && this.subscriberId != null) {
|
|
860
|
+
queryParams.push("subscriberId=".concat(this.subscriberId));
|
|
861
|
+
}
|
|
862
|
+
if (!options.uri.includes("subscriberCode") && this.subscriberCode != null) {
|
|
863
|
+
queryParams.push("subscriberCode=".concat(this.subscriberCode));
|
|
864
|
+
}
|
|
865
|
+
if (!options.uri.includes("token") && this.token != null) {
|
|
866
|
+
queryParams.push("token=".concat(this.token));
|
|
867
|
+
}
|
|
868
|
+
if (queryParams.length > 0) {
|
|
869
|
+
var queryString = queryParams.join("&");
|
|
870
|
+
options.uri += options.uri.includes("?") ? "&".concat(queryString) : "?".concat(queryString);
|
|
858
871
|
}
|
|
859
872
|
Logger_1.debug("hls request: " + options.uri);
|
|
860
|
-
return options;
|
|
861
873
|
};
|
|
862
874
|
this.videojsPlayer.ready(() => {
|
|
863
875
|
// If it's already added to player, no need to add again
|
|
@@ -944,7 +956,16 @@ class WebPlayer {
|
|
|
944
956
|
reconnect: false //webrtc adaptor has auto reconnect scenario, just disable it, we manage it here
|
|
945
957
|
});
|
|
946
958
|
if (this.autoPlay) {
|
|
959
|
+
//try to play directly
|
|
947
960
|
this.videojsPlayer.play().catch(e => {
|
|
961
|
+
//if it's not allowed error and default value are being used, try to play it muted
|
|
962
|
+
//if this.forcePlayWithAudio is true, it means user specifically ask to do.
|
|
963
|
+
// If it's false, it's default value so that we can proceed to try to play with muted
|
|
964
|
+
//This implementation is added because of auto play policy of the browsers
|
|
965
|
+
if (e.name === "NotAllowedError" && !this.forcePlayWithAudio) {
|
|
966
|
+
this.videojsPlayer.muted(true);
|
|
967
|
+
this.videojsPlayer.play();
|
|
968
|
+
}
|
|
948
969
|
Logger_1.warn("Problem in playback. The error is " + e);
|
|
949
970
|
});
|
|
950
971
|
}
|
|
@@ -1104,11 +1125,26 @@ class WebPlayer {
|
|
|
1104
1125
|
}
|
|
1105
1126
|
});
|
|
1106
1127
|
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, event => {
|
|
1128
|
+
Logger_1.warn("dash playback error: " + event);
|
|
1107
1129
|
this.tryNextTech();
|
|
1108
1130
|
});
|
|
1109
1131
|
this.dashPlayer.on(dashjs.MediaPlayer.events.ERROR, event => {
|
|
1132
|
+
Logger_1.warn("error: " + event);
|
|
1110
1133
|
this.tryNextTech();
|
|
1111
1134
|
});
|
|
1135
|
+
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_NOT_ALLOWED, event => {
|
|
1136
|
+
Logger_1.warn("dash playback not allowed: " + event);
|
|
1137
|
+
this.handleDashPlayBackNotAllowed();
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
handleDashPlayBackNotAllowed() {
|
|
1141
|
+
if (!this.forcePlayWithAudio) {
|
|
1142
|
+
Logger_1.info("Try to play with muted audio");
|
|
1143
|
+
this.dashPlayer.setMute(true);
|
|
1144
|
+
this.dashPlayer.play();
|
|
1145
|
+
} else {
|
|
1146
|
+
this.tryNextTech();
|
|
1147
|
+
}
|
|
1112
1148
|
}
|
|
1113
1149
|
makeDashPlayerVisibleWhenInitialized() {
|
|
1114
1150
|
this.dashPlayer.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, event => {
|
package/package.json
CHANGED
package/src/web_player.js
CHANGED
|
@@ -78,17 +78,22 @@ export class WebPlayer {
|
|
|
78
78
|
autoPlay = true;
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* mute: if
|
|
82
|
-
* default value is true because of browser's autoplay policy.
|
|
81
|
+
* mute: if false the player will try to auto play the stream with audio if it fails player will mute the audio and try again to autoplay it.
|
|
83
82
|
* It will be taken from url parameter "mute".
|
|
84
83
|
*/
|
|
85
|
-
mute =
|
|
84
|
+
mute = false;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Force the Player to play with audio Auto Play might not work.
|
|
88
|
+
*/
|
|
89
|
+
forcePlayWithAudio = false;
|
|
86
90
|
|
|
87
91
|
/**
|
|
88
92
|
* targetLatency: target latency in seconds. Optional. Default value is 3.
|
|
89
93
|
* It will be taken from url parameter "targetLatency".
|
|
90
94
|
* It's used for dash(cmaf) playback.
|
|
91
95
|
*/
|
|
96
|
+
|
|
92
97
|
targetLatency = 3;
|
|
93
98
|
|
|
94
99
|
/**
|
|
@@ -161,6 +166,7 @@ export class WebPlayer {
|
|
|
161
166
|
*/
|
|
162
167
|
tryNextTechTimer;
|
|
163
168
|
|
|
169
|
+
|
|
164
170
|
constructor(configOrWindow, containerElement, placeHolderElement) {
|
|
165
171
|
|
|
166
172
|
WebPlayer.DEFAULT_PLAY_ORDER = ["webrtc", "hls"];;
|
|
@@ -312,7 +318,7 @@ export class WebPlayer {
|
|
|
312
318
|
this.playType = WebPlayer.DEFAULT_PLAY_TYPE;
|
|
313
319
|
this.token = null;
|
|
314
320
|
this.autoPlay = true;
|
|
315
|
-
this.mute =
|
|
321
|
+
this.mute = false;
|
|
316
322
|
this.targetLatency = 3;
|
|
317
323
|
this.subscriberId = null;
|
|
318
324
|
this.subscriberCode = null;
|
|
@@ -336,6 +342,7 @@ export class WebPlayer {
|
|
|
336
342
|
this.dashjsLoaded = false;
|
|
337
343
|
this.containerElementInitialDisplay = "block";
|
|
338
344
|
this.placeHolderElementInitialDisplay = "block";
|
|
345
|
+
this.forcePlayWithAudio = false;
|
|
339
346
|
}
|
|
340
347
|
|
|
341
348
|
initializeFromUrlParams() {
|
|
@@ -365,11 +372,13 @@ export class WebPlayer {
|
|
|
365
372
|
|
|
366
373
|
let muteLocal = getUrlParameter("mute", this.window.location.search);
|
|
367
374
|
if (muteLocal === "false") {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
375
|
+
this.mute = false;
|
|
376
|
+
//user specifically asks to play with audio so if it fails in auto play, it will not try to play without audio
|
|
377
|
+
this.forcePlayWithAudio = true;
|
|
378
|
+
}else if(muteLocal === "true"){
|
|
379
|
+
this.mute = true;
|
|
380
|
+
}
|
|
381
|
+
|
|
373
382
|
|
|
374
383
|
let localTargetLatency = getUrlParameter("targetLatency", this.window.location.search);
|
|
375
384
|
if (localTargetLatency != null) {
|
|
@@ -571,7 +580,7 @@ export class WebPlayer {
|
|
|
571
580
|
});
|
|
572
581
|
|
|
573
582
|
this.videojsPlayer.on('error', (e) => {
|
|
574
|
-
Logger.warn("There is an error in playback: "
|
|
583
|
+
Logger.warn("There is an error in playback: ", e);
|
|
575
584
|
// We need to add this kind of check. If we don't add this kind of checkpoint, it will create an infinite loop
|
|
576
585
|
if (!this.errorCalled) {
|
|
577
586
|
this.errorCalled = true;
|
|
@@ -627,19 +636,26 @@ export class WebPlayer {
|
|
|
627
636
|
//hls specific calls
|
|
628
637
|
if (extension == "m3u8") {
|
|
629
638
|
videojs.Vhs.xhr.beforeRequest = (options) => {
|
|
639
|
+
const queryParams = [];
|
|
630
640
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
{
|
|
634
|
-
if (!options.uri.endsWith("?"))
|
|
635
|
-
{
|
|
636
|
-
options.uri = options.uri + "?";
|
|
637
|
-
}
|
|
638
|
-
options.uri += securityParams;
|
|
641
|
+
if (!options.uri.includes("subscriberId") && this.subscriberId != null) {
|
|
642
|
+
queryParams.push(`subscriberId=${this.subscriberId}`);
|
|
639
643
|
}
|
|
640
644
|
|
|
645
|
+
if (!options.uri.includes("subscriberCode") && this.subscriberCode != null) {
|
|
646
|
+
queryParams.push(`subscriberCode=${this.subscriberCode}`);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (!options.uri.includes("token") && this.token != null) {
|
|
650
|
+
queryParams.push(`token=${this.token}`);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (queryParams.length > 0) {
|
|
654
|
+
const queryString = queryParams.join("&");
|
|
655
|
+
options.uri += options.uri.includes("?") ? `&${queryString}` : `?${queryString}`;
|
|
656
|
+
}
|
|
641
657
|
Logger.debug("hls request: " + options.uri);
|
|
642
|
-
|
|
658
|
+
|
|
643
659
|
};
|
|
644
660
|
|
|
645
661
|
|
|
@@ -739,9 +755,19 @@ export class WebPlayer {
|
|
|
739
755
|
});
|
|
740
756
|
|
|
741
757
|
if (this.autoPlay) {
|
|
758
|
+
//try to play directly
|
|
742
759
|
this.videojsPlayer.play().catch((e) => {
|
|
743
|
-
|
|
744
|
-
|
|
760
|
+
|
|
761
|
+
//if it's not allowed error and default value are being used, try to play it muted
|
|
762
|
+
//if this.forcePlayWithAudio is true, it means user specifically ask to do.
|
|
763
|
+
// If it's false, it's default value so that we can proceed to try to play with muted
|
|
764
|
+
//This implementation is added because of auto play policy of the browsers
|
|
765
|
+
if (e.name === "NotAllowedError" && !this.forcePlayWithAudio) {
|
|
766
|
+
this.videojsPlayer.muted(true);
|
|
767
|
+
this.videojsPlayer.play();
|
|
768
|
+
}
|
|
769
|
+
Logger.warn("Problem in playback. The error is " + e);
|
|
770
|
+
});
|
|
745
771
|
}
|
|
746
772
|
}
|
|
747
773
|
|
|
@@ -926,11 +952,29 @@ export class WebPlayer {
|
|
|
926
952
|
}
|
|
927
953
|
});
|
|
928
954
|
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, (event) => {
|
|
955
|
+
Logger.warn("dash playback error: " + event);
|
|
929
956
|
this.tryNextTech();
|
|
930
957
|
});
|
|
931
958
|
this.dashPlayer.on(dashjs.MediaPlayer.events.ERROR, (event) => {
|
|
959
|
+
Logger.warn("error: " + event);
|
|
932
960
|
this.tryNextTech();
|
|
933
961
|
});
|
|
962
|
+
|
|
963
|
+
this.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_NOT_ALLOWED, (event) => {
|
|
964
|
+
Logger.warn("dash playback not allowed: " + event);
|
|
965
|
+
this.handleDashPlayBackNotAllowed();
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
handleDashPlayBackNotAllowed() {
|
|
970
|
+
if (!this.forcePlayWithAudio) {
|
|
971
|
+
Logger.info("Try to play with muted audio");
|
|
972
|
+
this.dashPlayer.setMute(true);
|
|
973
|
+
this.dashPlayer.play();
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
this.tryNextTech();
|
|
977
|
+
}
|
|
934
978
|
}
|
|
935
979
|
|
|
936
980
|
makeDashPlayerVisibleWhenInitialized() {
|
|
@@ -45,8 +45,8 @@ describe("WebPlayer", function() {
|
|
|
45
45
|
//the following is a test autoPlay is still true in mobile. We just try to play the stream if mobile browser can play or not
|
|
46
46
|
//in autoPlay mode
|
|
47
47
|
expect(player.autoPlay).to.true;
|
|
48
|
-
expect(player.mute).to.
|
|
49
|
-
expect(player.isMuted()).to.be.
|
|
48
|
+
expect(player.mute).to.false;
|
|
49
|
+
expect(player.isMuted()).to.be.false;
|
|
50
50
|
expect(player.targetLatency).to.equal(3);
|
|
51
51
|
expect(player.subscriberId).to.be.null;
|
|
52
52
|
expect(player.subscriberCode).to.be.null;
|
|
@@ -164,8 +164,8 @@ describe("WebPlayer", function() {
|
|
|
164
164
|
//the following is a test autoPlay is still true in mobile. We just try to play the stream if mobile browser can play or not
|
|
165
165
|
//in autoPlay mode
|
|
166
166
|
expect(player.autoPlay).to.true;
|
|
167
|
-
expect(player.mute).to.
|
|
168
|
-
expect(player.isMuted()).to.be.
|
|
167
|
+
expect(player.mute).to.false;
|
|
168
|
+
expect(player.isMuted()).to.be.false;
|
|
169
169
|
expect(player.targetLatency).to.equal(3);
|
|
170
170
|
expect(player.subscriberId).to.be.null;
|
|
171
171
|
expect(player.subscriberCode).to.be.null;
|
|
@@ -786,6 +786,70 @@ describe("WebPlayer", function() {
|
|
|
786
786
|
|
|
787
787
|
|
|
788
788
|
});
|
|
789
|
+
|
|
790
|
+
it("testAutoPlay",async function(){
|
|
791
|
+
var videoContainer = document.createElement("video_container");
|
|
792
|
+
|
|
793
|
+
var placeHolder = document.createElement("place_holder");
|
|
794
|
+
|
|
795
|
+
var locationComponent = { href: 'http://example.com?id=stream123.mp4', search: "?id=stream123.mp4", pathname: "/", protocol: "http:" };
|
|
796
|
+
var windowComponent = { location : locationComponent,
|
|
797
|
+
document: document,
|
|
798
|
+
addEventListener: window.addEventListener};
|
|
799
|
+
|
|
800
|
+
var player = new WebPlayer(windowComponent, videoContainer, placeHolder);
|
|
801
|
+
let vjsMock = videojs(WebPlayer.VIDEO_PLAYER_ID, {
|
|
802
|
+
poster: "test",
|
|
803
|
+
liveui:true ,
|
|
804
|
+
liveTracker: {
|
|
805
|
+
trackingThreshold: 0
|
|
806
|
+
},
|
|
807
|
+
html5: {
|
|
808
|
+
vhs: {
|
|
809
|
+
limitRenditionByPlayerDimensions: false
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
controls: true,
|
|
813
|
+
class: 'video-js vjs-default-skin vjs-big-play-centered',
|
|
814
|
+
muted: false,
|
|
815
|
+
preload: "auto",
|
|
816
|
+
autoplay: true
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
const mockVideoJS = sinon.stub(window, 'videojs').callsFake(()=>{return vjsMock});
|
|
820
|
+
var muted = sinon.replace(vjsMock, "muted", sinon.fake());
|
|
821
|
+
let play = sinon.stub(vjsMock, 'play').callsFake(()=>{
|
|
822
|
+
return Promise.resolve();
|
|
823
|
+
});
|
|
824
|
+
await player.playIfExists("webrtc"); // autoplay worked with audio
|
|
825
|
+
expect(play.calledOnce).to.be.true;
|
|
826
|
+
expect(muted.notCalled).to.be.true;
|
|
827
|
+
|
|
828
|
+
play.restore();
|
|
829
|
+
|
|
830
|
+
play = sinon.stub(vjsMock, 'play').callsFake(()=>{
|
|
831
|
+
return Promise.reject(new DOMException("NotAllowedError","NotAllowedError"));
|
|
832
|
+
});
|
|
833
|
+
player.forcePlayWithAudio = true;
|
|
834
|
+
|
|
835
|
+
await player.playIfExists("webrtc"); // autoplay failed force play with audio
|
|
836
|
+
expect(play.calledOnce).to.be.true;
|
|
837
|
+
expect(muted.notCalled).to.be.true;
|
|
838
|
+
|
|
839
|
+
play.restore();
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
play = sinon.stub(vjsMock, 'play').callsFake(()=>{
|
|
843
|
+
return Promise.reject(new DOMException("NotAllowedError","NotAllowedError"));
|
|
844
|
+
});
|
|
845
|
+
player.forcePlayWithAudio = false;
|
|
846
|
+
await player.playIfExists("webrtc"); // autoplay failed try to play without audio
|
|
847
|
+
|
|
848
|
+
expect(play.calledTwice).to.be.true;
|
|
849
|
+
expect(muted.calledWithMatch(true)).to.be.true;
|
|
850
|
+
|
|
851
|
+
sinon.restore();
|
|
852
|
+
})
|
|
789
853
|
|
|
790
854
|
|
|
791
855
|
it("webrtc-info-event", async function() {
|
|
@@ -885,9 +949,52 @@ describe("WebPlayer", function() {
|
|
|
885
949
|
result = player.sendWebRTCData("data");
|
|
886
950
|
expect(result).to.be.false;
|
|
887
951
|
expect(sendDataViaWebRTC.callCount).to.be.equal(1);
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
it("handleDashPlayBackNotAllowed", async function(){
|
|
956
|
+
|
|
957
|
+
this.timeout(10000);
|
|
958
|
+
var videoContainer = document.createElement("video_container");
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
var player = new WebPlayer({
|
|
963
|
+
streamId:"streamConfig",
|
|
964
|
+
}, videoContainer, null);
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
{
|
|
968
|
+
player.playOrder = ["dash"];
|
|
969
|
+
await player.initialize().then(()=> {
|
|
970
|
+
|
|
971
|
+
}).catch((err) => {
|
|
972
|
+
expect.fail("it should not fail because we skip videojs and dash is already loaded");
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
player.dashPlayer = window.dashjs.MediaPlayer().create();
|
|
977
|
+
|
|
978
|
+
var setMute = sinon.replace(player.dashPlayer, "setMute", sinon.fake());
|
|
979
|
+
var play = sinon.replace(player.dashPlayer, "play", sinon.fake());
|
|
980
|
+
var nextTech = sinon.replace(player, "tryNextTech", sinon.fake());
|
|
981
|
+
|
|
982
|
+
expect(player.forcePlayWithAudio).to.be.false;
|
|
983
|
+
player.handleDashPlayBackNotAllowed();
|
|
984
|
+
expect(setMute.calledOnce).to.be.true;
|
|
985
|
+
expect(play.calledOnce).to.be.true;
|
|
986
|
+
expect(nextTech.notCalled).to.be.true;
|
|
987
|
+
|
|
988
|
+
expect(setMute.calledWithExactly(true)).to.be.true;
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
player.forcePlayWithAudio = true;
|
|
992
|
+
player.handleDashPlayBackNotAllowed();
|
|
993
|
+
expect(setMute.calledOnce).to.be.true;
|
|
994
|
+
expect(play.calledOnce).to.be.true;
|
|
995
|
+
expect(nextTech.calledOnce).to.be.true;
|
|
996
|
+
|
|
888
997
|
|
|
889
|
-
|
|
890
|
-
|
|
891
998
|
|
|
892
999
|
});
|
|
893
1000
|
|
package/.project
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<projectDescription>
|
|
3
|
-
<name>Embedded-Player</name>
|
|
4
|
-
<comment></comment>
|
|
5
|
-
<projects>
|
|
6
|
-
</projects>
|
|
7
|
-
<buildSpec>
|
|
8
|
-
<buildCommand>
|
|
9
|
-
<name>org.eclipse.wst.validation.validationbuilder</name>
|
|
10
|
-
<arguments>
|
|
11
|
-
</arguments>
|
|
12
|
-
</buildCommand>
|
|
13
|
-
</buildSpec>
|
|
14
|
-
<natures>
|
|
15
|
-
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
|
16
|
-
</natures>
|
|
17
|
-
</projectDescription>
|
package/.settings/.jsdtscope
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<classpath>
|
|
3
|
-
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
|
4
|
-
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
|
5
|
-
<classpathentry kind="src" path=""/>
|
|
6
|
-
<classpathentry kind="output" path=""/>
|
|
7
|
-
</classpath>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
org.eclipse.wst.jsdt.launching.JRE_CONTAINER
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Global
|