@gcorevideo/player 2.22.0 → 2.22.2

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.
Files changed (125) hide show
  1. package/assets/bottom-gear/bottomgear copy.ejs +10 -0
  2. package/assets/bottom-gear/bottomgear.ejs +4 -8
  3. package/assets/bottom-gear/gear-sub-menu.scss +0 -1
  4. package/assets/bottom-gear/gear.scss +0 -1
  5. package/assets/clappr-nerd-stats/button.ejs +3 -3
  6. package/assets/level-selector/button.ejs +2 -4
  7. package/assets/level-selector/list.ejs +14 -10
  8. package/assets/level-selector/style.scss +9 -4
  9. package/assets/media-control/container.scss +1 -1
  10. package/assets/playback-rate/list.ejs +5 -5
  11. package/assets/spinner-three-bounce/spinner.scss +1 -1
  12. package/dist/core.js +1 -2
  13. package/dist/index.css +885 -884
  14. package/dist/index.js +3938 -3779
  15. package/dist/player.d.ts +246 -108
  16. package/dist/plugins/index.css +1230 -1229
  17. package/dist/plugins/index.js +4036 -3878
  18. package/docs/api/player.bottomgear.additem.md +95 -0
  19. package/docs/api/player.bottomgear.md +63 -19
  20. package/docs/api/player.bottomgear.refresh.md +5 -1
  21. package/docs/api/player.clapprnerdstats.md +0 -2
  22. package/docs/api/player.clicktopause.md +1 -1
  23. package/docs/api/player.closedcaptions.md +2 -2
  24. package/docs/api/player.closedcaptionspluginsettings.md +5 -0
  25. package/docs/api/player.errorscreen.md +18 -4
  26. package/docs/api/player.errorscreenpluginsettings.md +1 -4
  27. package/docs/api/player.errorscreensettings.md +15 -0
  28. package/docs/api/{player.mediacontrolevents.md → player.gearevents.md} +7 -7
  29. package/docs/api/player.levelselector.events.md +0 -1
  30. package/docs/api/player.levelselector.md +1 -1
  31. package/docs/api/player.md +33 -36
  32. package/docs/api/{player.bottomgear.setcontent.md → player.mediacontrol.handlecustomarea.md} +5 -9
  33. package/docs/api/player.mediacontrol.md +10 -24
  34. package/docs/api/player.mediacontrol.putelement.md +2 -2
  35. package/docs/api/{player.bottomgear.getelement.md → player.mediacontrol.toggleelement.md} +23 -9
  36. package/docs/api/player.mediacontrolelement.md +1 -1
  37. package/docs/api/player.playbackrate.md +22 -3
  38. package/docs/api/{player.gearoptionsitem.md → player.playbackrateoption.md} +6 -4
  39. package/docs/api/{player.mediacontrol.getcenterpanel.md → player.playbackratesettings.md} +8 -6
  40. package/docs/api/player.sourcecontroller._constructor_.md +49 -0
  41. package/docs/api/player.sourcecontroller.md +70 -7
  42. package/docs/api/player.spinnerevents.md +1 -4
  43. package/docs/api/player.spinnerthreebounce._constructor_.md +0 -3
  44. package/docs/api/player.spinnerthreebounce.hide.md +0 -3
  45. package/docs/api/player.spinnerthreebounce.md +5 -8
  46. package/docs/api/player.spinnerthreebounce.show.md +2 -5
  47. package/lib/internal.types.d.ts +5 -0
  48. package/lib/internal.types.d.ts.map +1 -1
  49. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  50. package/lib/playback/dash-playback/DashPlayback.js +0 -1
  51. package/lib/playback.types.d.ts +0 -5
  52. package/lib/playback.types.d.ts.map +1 -1
  53. package/lib/plugins/bottom-gear/BottomGear.d.ts +93 -20
  54. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  55. package/lib/plugins/bottom-gear/BottomGear.js +145 -37
  56. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +2 -3
  57. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  58. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +18 -15
  59. package/lib/plugins/click-to-pause/ClickToPause.d.ts +1 -1
  60. package/lib/plugins/click-to-pause/ClickToPause.d.ts.map +1 -1
  61. package/lib/plugins/click-to-pause/ClickToPause.js +3 -2
  62. package/lib/plugins/dvr-controls/DvrControls.js +1 -1
  63. package/lib/plugins/error-screen/ErrorScreen.d.ts +29 -4
  64. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
  65. package/lib/plugins/error-screen/ErrorScreen.js +17 -2
  66. package/lib/plugins/level-selector/LevelSelector.d.ts +8 -11
  67. package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
  68. package/lib/plugins/level-selector/LevelSelector.js +66 -102
  69. package/lib/plugins/media-control/MediaControl.d.ts +6 -15
  70. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  71. package/lib/plugins/media-control/MediaControl.js +36 -30
  72. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
  73. package/lib/plugins/picture-in-picture/PictureInPicture.js +7 -2
  74. package/lib/plugins/playback-rate/PlaybackRate.d.ts +42 -14
  75. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  76. package/lib/plugins/playback-rate/PlaybackRate.js +101 -83
  77. package/lib/plugins/source-controller/SourceController.d.ts +40 -4
  78. package/lib/plugins/source-controller/SourceController.d.ts.map +1 -1
  79. package/lib/plugins/source-controller/SourceController.js +41 -4
  80. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts +8 -6
  81. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts.map +1 -1
  82. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +10 -6
  83. package/lib/plugins/subtitles/ClosedCaptions.d.ts +7 -7
  84. package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
  85. package/lib/plugins/subtitles/ClosedCaptions.js +3 -3
  86. package/lib/testUtils.d.ts +1 -0
  87. package/lib/testUtils.d.ts.map +1 -1
  88. package/lib/testUtils.js +13 -0
  89. package/package.json +1 -1
  90. package/src/internal.types.ts +6 -0
  91. package/src/playback/dash-playback/DashPlayback.ts +0 -1
  92. package/src/playback.types.ts +0 -5
  93. package/src/plugins/bottom-gear/BottomGear.ts +186 -77
  94. package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +21 -5
  95. package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +5 -12
  96. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +27 -25
  97. package/src/plugins/click-to-pause/ClickToPause.ts +3 -2
  98. package/src/plugins/dvr-controls/DvrControls.ts +1 -1
  99. package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +1 -1
  100. package/src/plugins/error-screen/ErrorScreen.ts +30 -4
  101. package/src/plugins/level-selector/LevelSelector.ts +80 -120
  102. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +69 -79
  103. package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +38 -71
  104. package/src/plugins/media-control/MediaControl.ts +50 -36
  105. package/src/plugins/media-control/__tests__/MediaControl.test.ts +4 -4
  106. package/src/plugins/picture-in-picture/PictureInPicture.ts +7 -2
  107. package/src/plugins/playback-rate/PlaybackRate.ts +136 -108
  108. package/src/plugins/playback-rate/__tests__/PlaybackRate.test.ts +84 -37
  109. package/src/plugins/playback-rate/__tests__/__snapshots__/PlaybackRate.test.ts.snap +55 -6
  110. package/src/plugins/source-controller/SourceController.ts +41 -4
  111. package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +10 -6
  112. package/src/plugins/subtitles/ClosedCaptions.ts +9 -10
  113. package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
  114. package/src/testUtils.ts +14 -0
  115. package/src/typings/vitest.d.ts +1 -0
  116. package/temp/player.api.json +303 -370
  117. package/tsconfig.tsbuildinfo +1 -1
  118. package/docs/api/player.gearitemelement.md +0 -18
  119. package/docs/api/player.mediacontrol.getleftpanel.md +0 -22
  120. package/docs/api/player.mediacontrol.getrightpanel.md +0 -22
  121. package/docs/api/player.subtitlespluginsettings.md +0 -18
  122. package/docs/api/player.texttrackitem.id.md +0 -11
  123. package/docs/api/player.texttrackitem.md +0 -87
  124. package/docs/api/player.texttrackitem.name.md +0 -11
  125. package/docs/api/player.texttrackitem.track.md +0 -11
@@ -1,4 +1,18 @@
1
1
  import { UICorePlugin, Core } from '@clappr/core';
2
+ /**
3
+ * @beta
4
+ */
5
+ export type PlaybackRateOption = {
6
+ value: number;
7
+ label: string;
8
+ };
9
+ /**
10
+ * @beta
11
+ */
12
+ export type PlaybackRateSettings = {
13
+ options?: PlaybackRateOption[];
14
+ defaultValue?: number;
15
+ };
2
16
  /**
3
17
  * `PLUGIN` that allows changing the playback speed of the video.
4
18
  * @beta
@@ -6,17 +20,32 @@ import { UICorePlugin, Core } from '@clappr/core';
6
20
  * @remarks
7
21
  * Depends on:
8
22
  *
9
- * - {@link MediaControl | media_control}
23
+ * - {@link MediaControl}
24
+ *
25
+ * - {@link BottomGear}
26
+ *
27
+ * It renders an option in the gear menu, which opens a dropdown with the options to change the playback rate.
28
+ * Note that the playback rate change is supported only for VOD or DVR-enabled live streams.
10
29
  *
11
- * - {@link BottomGear | bottom_gear}
30
+ * Plugin settings - {@link PlaybackRateSettings}
12
31
  *
13
- * It renders a button in the gear menu, which opens a dropdown with the options to change the playback rate.
14
- * Note that the playback rate change is supported only for VOD or DVR enabled live streams.
32
+ * @example
33
+ * ```ts
34
+ * import { Player, PlaybackRateSettings } from '@gcorevideo/player'
35
+ * Player.registerPlugin(PlaybackRate)
36
+ * const player = new Player({
37
+ * playbackRate: {
38
+ * options: [
39
+ * { value: 0.5, label: '0.5x' },
40
+ * { value: 1, label: '1x' },
41
+ * ],
42
+ * defaultValue: 1,
43
+ * } as PlaybackRateSettings,
44
+ * })
45
+ * ```
15
46
  */
16
47
  export declare class PlaybackRate extends UICorePlugin {
17
48
  private playbackRates;
18
- private prevSelectedRate;
19
- private rendered;
20
49
  private selectedRate;
21
50
  /**
22
51
  * @internal
@@ -41,9 +70,8 @@ export declare class PlaybackRate extends UICorePlugin {
41
70
  * @internal
42
71
  */
43
72
  get events(): {
44
- 'click .gear-sub-menu_btn': string;
45
- 'click .gear-option': string;
46
- 'click .go-back': string;
73
+ 'click [data-rate]': string;
74
+ 'click #playback-rate-back-button': string;
47
75
  };
48
76
  /**
49
77
  * @internal
@@ -51,8 +79,10 @@ export declare class PlaybackRate extends UICorePlugin {
51
79
  bindEvents(): void;
52
80
  private onCoreReady;
53
81
  private onActiveContainerChange;
82
+ private onMediaControlRendered;
54
83
  private onGearRendered;
55
- private onDvrStateChanged;
84
+ private addGearItem;
85
+ private onMetaDataLoaded;
56
86
  private allRateElements;
57
87
  private rateElement;
58
88
  private onPlaybackRateChange;
@@ -61,16 +91,14 @@ export declare class PlaybackRate extends UICorePlugin {
61
91
  * @internal
62
92
  */
63
93
  render(): this;
64
- private onStartAd;
65
- private onFinishAd;
66
94
  private onPlay;
67
95
  private resetPlaybackRate;
68
96
  private onStop;
69
- private onRateSelect;
70
- private onShowMenu;
97
+ private onSelect;
71
98
  private goBack;
72
99
  private setSelectedRate;
73
100
  private getTitle;
74
101
  private highlightCurrentRate;
102
+ private updateGearOptionLabel;
75
103
  }
76
104
  //# sourceMappingURL=PlaybackRate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlaybackRate.d.ts","sourceRoot":"","sources":["../../../src/plugins/playback-rate/PlaybackRate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAsB,IAAI,EAAE,MAAM,cAAc,CAAA;AAuC7E;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,aAAa,CAA+C;IAGpE,OAAO,CAAC,gBAAgB,CAAoB;IAE5C,OAAO,CAAC,QAAQ,CAAQ;IAExB,OAAO,CAAC,YAAY,CAAgC;IAEpD;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAuB;IAE7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAE7C,IAAI,EAAE,IAAI;IAQtB;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;;MAMlB;IAED;;OAEG;IACM,UAAU;IASnB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,YAAY;IAepB;;OAEG;IACM,MAAM;IAgCf,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,oBAAoB;CAS7B"}
1
+ {"version":3,"file":"PlaybackRate.d.ts","sourceRoot":"","sources":["../../../src/plugins/playback-rate/PlaybackRate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAsB,IAAI,EAAK,MAAM,cAAc,CAAA;AAiBhF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,aAAa,CAA+C;IAKpE,OAAO,CAAC,YAAY,CAAwB;IAE5C;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAuB;IAE7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAE7C,IAAI,EAAE,IAAI;IAQtB;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;MAKlB;IAED;;OAEG;IACM,UAAU;IASnB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,YAAY;IAepB;;OAEG;IACM,MAAM;IAwCf,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,qBAAqB;CAI9B"}
@@ -1,4 +1,4 @@
1
- import { Events, UICorePlugin, Playback, template } from '@clappr/core';
1
+ import { Events, UICorePlugin, Playback, template, $ } from '@clappr/core';
2
2
  import { trace } from '@gcorevideo/utils';
3
3
  import assert from 'assert';
4
4
  import { CLAPPR_VERSION } from '../../build.js';
@@ -8,18 +8,18 @@ import speedIcon from '../../../assets/icons/new/speed.svg';
8
8
  import arrowRightIcon from '../../../assets/icons/new/arrow-right.svg';
9
9
  import arrowLeftIcon from '../../../assets/icons/new/arrow-left.svg';
10
10
  import checkIcon from '../../../assets/icons/new/check.svg';
11
+ import { GearEvents } from '../bottom-gear/BottomGear.js';
11
12
  import { PlaybackEvents } from '../../playback/types.js';
12
- import { MediaControlEvents, } from '../media-control/MediaControl.js';
13
13
  const DEFAULT_PLAYBACK_RATES = [
14
- { value: '0.5', label: '0.5x' },
15
- { value: '0.75', label: '0.75x' },
16
- { value: '1.0', label: '1x' },
17
- { value: '1.25', label: '1.25x' },
18
- { value: '1.5', label: '1.5x' },
19
- { value: '1.75', label: '1.75x' },
20
- { value: '2.0', label: '2x' },
14
+ { value: 0.5, label: '0.5x' },
15
+ { value: 0.75, label: '0.75x' },
16
+ { value: 1.0, label: '1x' },
17
+ { value: 1.25, label: '1.25x' },
18
+ { value: 1.5, label: '1.5x' },
19
+ { value: 1.75, label: '1.75x' },
20
+ { value: 2.0, label: '2x' },
21
21
  ];
22
- const DEFAULT_PLAYBACK_RATE = '1.0';
22
+ const DEFAULT_PLAYBACK_RATE = 1;
23
23
  const T = 'plugins.playback_rate';
24
24
  /**
25
25
  * `PLUGIN` that allows changing the playback speed of the video.
@@ -28,18 +28,34 @@ const T = 'plugins.playback_rate';
28
28
  * @remarks
29
29
  * Depends on:
30
30
  *
31
- * - {@link MediaControl | media_control}
31
+ * - {@link MediaControl}
32
32
  *
33
- * - {@link BottomGear | bottom_gear}
33
+ * - {@link BottomGear}
34
34
  *
35
- * It renders a button in the gear menu, which opens a dropdown with the options to change the playback rate.
36
- * Note that the playback rate change is supported only for VOD or DVR enabled live streams.
35
+ * It renders an option in the gear menu, which opens a dropdown with the options to change the playback rate.
36
+ * Note that the playback rate change is supported only for VOD or DVR-enabled live streams.
37
+ *
38
+ * Plugin settings - {@link PlaybackRateSettings}
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * import { Player, PlaybackRateSettings } from '@gcorevideo/player'
43
+ * Player.registerPlugin(PlaybackRate)
44
+ * const player = new Player({
45
+ * playbackRate: {
46
+ * options: [
47
+ * { value: 0.5, label: '0.5x' },
48
+ * { value: 1, label: '1x' },
49
+ * ],
50
+ * defaultValue: 1,
51
+ * } as PlaybackRateSettings,
52
+ * })
53
+ * ```
37
54
  */
38
55
  export class PlaybackRate extends UICorePlugin {
39
56
  playbackRates = DEFAULT_PLAYBACK_RATES;
40
57
  // Saved when an ad starts to restore after it finishes
41
- prevSelectedRate;
42
- rendered = false;
58
+ // private prevSelectedRate: string | undefined
43
59
  selectedRate = DEFAULT_PLAYBACK_RATE;
44
60
  /**
45
61
  * @internal
@@ -75,16 +91,15 @@ export class PlaybackRate extends UICorePlugin {
75
91
  */
76
92
  get events() {
77
93
  return {
78
- 'click .gear-sub-menu_btn': 'onRateSelect',
79
- 'click .gear-option': 'onShowMenu',
80
- 'click .go-back': 'goBack',
94
+ 'click [data-rate]': 'onSelect',
95
+ 'click #playback-rate-back-button': 'goBack',
81
96
  };
82
97
  }
83
98
  /**
84
99
  * @internal
85
100
  */
86
101
  bindEvents() {
87
- this.listenTo(this.core, Events.CORE_READY, this.onCoreReady);
102
+ this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
88
103
  this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChange);
89
104
  }
90
105
  onCoreReady() {
@@ -93,45 +108,56 @@ export class PlaybackRate extends UICorePlugin {
93
108
  assert(mediaControl, 'media_control plugin is required');
94
109
  const gear = this.core.getPlugin('bottom_gear');
95
110
  assert(gear, 'bottom_gear plugin is required');
96
- this.listenTo(mediaControl, MediaControlEvents.MEDIACONTROL_GEAR_RENDERED, this.onGearRendered);
111
+ this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.onMediaControlRendered);
112
+ this.listenTo(gear, GearEvents.RENDERED, this.onGearRendered);
97
113
  }
98
114
  onActiveContainerChange() {
99
115
  trace(`${T} onActiveContainerChange`);
100
116
  this.listenTo(this.core.activePlayback, Events.PLAYBACK_STOP, this.onStop);
101
117
  this.listenTo(this.core.activePlayback, Events.PLAYBACK_PLAY, this.onPlay);
102
118
  this.listenTo(this.core.activePlayback, PlaybackEvents.PLAYBACK_RATE_CHANGED, this.onPlaybackRateChange);
103
- this.listenTo(this.core.activeContainer, Events.CONTAINER_PLAYBACKDVRSTATECHANGED, this.onDvrStateChanged);
119
+ this.listenTo(this.core.activeContainer, Events.CONTAINER_LOADEDMETADATA, this.onMetaDataLoaded);
104
120
  }
105
- onGearRendered() {
106
- trace(`${T} onGearRendered`, {
107
- rendered: this.rendered,
108
- });
109
- this.rendered = false;
121
+ onMediaControlRendered() {
122
+ trace(`${T} onMediaControlRendered`);
110
123
  this.render();
111
124
  }
112
- onDvrStateChanged(dvrEnabled) {
113
- trace(`${T} onDvrStateChanged`, {
114
- dvrEnabled,
115
- });
116
- if (dvrEnabled) {
117
- this.render();
118
- }
125
+ onGearRendered() {
126
+ trace(`${T} onGearRendered`);
127
+ this.addGearItem();
128
+ }
129
+ addGearItem() {
130
+ trace(`${T} addGearItem`);
131
+ this.core
132
+ .getPlugin('bottom_gear')
133
+ ?.addItem('rate', this.$el)
134
+ .html($(PlaybackRate.buttonTemplate({
135
+ title: this.getTitle(),
136
+ speedIcon,
137
+ arrowRightIcon,
138
+ i18n: this.core.i18n,
139
+ })));
140
+ }
141
+ onMetaDataLoaded() {
142
+ trace(`${T} onMetaDataLoaded`);
143
+ this.render();
119
144
  }
120
145
  allRateElements() {
121
- return this.$('ul.gear-sub-menu li');
146
+ return this.$el.find('#playback-rate-menu li');
122
147
  }
123
- rateElement(rate = '1') {
124
- return this.$(`ul.gear-sub-menu a[data-rate="${rate}"]`).parent();
148
+ rateElement(rate) {
149
+ return this.$el.find(`#playback-rate-menu a[data-rate="${rate}"]`).parent();
125
150
  }
126
151
  onPlaybackRateChange(playbackRate) {
127
- const selectedRate = parseInt(this.selectedRate, 10);
128
152
  // TODO check it doesn't interfere with the DASH.js or HLS.js playback live catchup
129
- if (Math.abs(playbackRate - selectedRate) > 0.1) {
130
- trace(`${T} onPlaybackRateChange setting target rate`, {
153
+ if (Math.abs(playbackRate - this.selectedRate) > 0.1) {
154
+ this.core.activePlayback?.setPlaybackRate(this.selectedRate);
155
+ }
156
+ else {
157
+ trace(`${T} onPlaybackRateChange not steering to the selected rate, it is seemingly a catchup algorithm working`, {
131
158
  playbackRate,
132
- selectedRate,
159
+ selectedRate: this.selectedRate,
133
160
  });
134
- this.core.activePlayback?.setPlaybackRate(selectedRate);
135
161
  }
136
162
  }
137
163
  shouldRender() {
@@ -149,38 +175,35 @@ export class PlaybackRate extends UICorePlugin {
149
175
  */
150
176
  render() {
151
177
  trace(`${T} render`, {
152
- rendered: this.rendered,
153
178
  shouldRender: this.shouldRender(),
154
179
  });
155
180
  if (!this.shouldRender()) {
156
181
  return this;
157
182
  }
158
- if (this.rendered) {
159
- return this;
160
- }
161
- const button = PlaybackRate.buttonTemplate({
162
- title: this.getTitle(),
163
- speedIcon,
164
- arrowRightIcon,
183
+ this.$el.html(PlaybackRate.listTemplate({
184
+ arrowLeftIcon,
185
+ checkIcon,
186
+ current: this.selectedRate,
165
187
  i18n: this.core.i18n,
166
- });
167
- this.$el.html(button);
168
- this.core.getPlugin('bottom_gear')
169
- ?.getElement('rate')
170
- ?.html(this.el);
171
- this.rendered = true;
188
+ playbackRates: this.playbackRates,
189
+ }));
190
+ this.addGearItem();
172
191
  return this;
173
192
  }
174
- onStartAd() {
175
- this.prevSelectedRate = this.selectedRate;
176
- this.resetPlaybackRate();
177
- this.listenToOnce(this.core.activePlayback, Events.PLAYBACK_PLAY, this.onFinishAd);
178
- }
179
- onFinishAd() {
180
- if (this.prevSelectedRate) {
181
- this.setSelectedRate(this.prevSelectedRate);
182
- }
183
- }
193
+ // private onStartAd() {
194
+ // this.prevSelectedRate = this.selectedRate
195
+ // this.resetPlaybackRate()
196
+ // this.listenToOnce(
197
+ // this.core.activePlayback,
198
+ // Events.PLAYBACK_PLAY,
199
+ // this.onFinishAd,
200
+ // )
201
+ // }
202
+ // private onFinishAd() {
203
+ // if (this.prevSelectedRate) {
204
+ // this.setSelectedRate(this.prevSelectedRate)
205
+ // }
206
+ // }
184
207
  onPlay() {
185
208
  if (this.core.getPlaybackType() === Playback.LIVE &&
186
209
  !this.core.activePlayback.dvrEnabled) {
@@ -194,44 +217,39 @@ export class PlaybackRate extends UICorePlugin {
194
217
  this.setSelectedRate(DEFAULT_PLAYBACK_RATE);
195
218
  }
196
219
  onStop() { }
197
- onRateSelect(event) {
220
+ onSelect(event) {
198
221
  event.stopPropagation();
199
- const rate = event.currentTarget.dataset.rate;
222
+ const rate = parseFloat(event.currentTarget.dataset.rate || '');
200
223
  if (rate) {
201
224
  this.setSelectedRate(rate);
202
225
  this.highlightCurrentRate();
226
+ this.updateGearOptionLabel();
203
227
  }
204
228
  return false;
205
229
  }
206
- onShowMenu() {
207
- this.$el.html(PlaybackRate.listTemplate({
208
- playbackRates: this.playbackRates,
209
- arrowLeftIcon,
210
- checkIcon,
211
- i18n: this.core.i18n,
212
- }));
213
- this.core.getPlugin('bottom_gear')?.setContent(this.el);
214
- this.highlightCurrentRate();
215
- }
216
230
  goBack() {
217
231
  setTimeout(() => {
218
232
  this.core.getPlugin('bottom_gear').refresh();
219
233
  }, 0);
220
234
  }
221
235
  setSelectedRate(rate) {
222
- // Set <video playbackRate="..."
223
236
  this.core.activePlayback?.setPlaybackRate(rate);
224
237
  this.selectedRate = rate;
225
238
  }
226
239
  getTitle() {
227
240
  return (this.playbackRates.find((r) => r.value === this.selectedRate)?.label ||
228
- this.selectedRate);
241
+ `x${this.selectedRate}`);
229
242
  }
230
243
  highlightCurrentRate() {
231
244
  this.allRateElements().removeClass('current');
232
245
  this.allRateElements().find('a').removeClass('gcore-skin-active');
233
- const currentLevelElement = this.rateElement(this.selectedRate);
234
- currentLevelElement.addClass('current');
235
- currentLevelElement.find('a').addClass('gcore-skin-active');
246
+ this.rateElement(this.selectedRate)
247
+ .addClass('current')
248
+ .find('a')
249
+ .addClass('gcore-skin-active');
250
+ }
251
+ updateGearOptionLabel() {
252
+ trace(`${T} updateGearOptionLabel`);
253
+ this.addGearItem();
236
254
  }
237
255
  }
@@ -1,10 +1,46 @@
1
1
  import { CorePlugin, type Core as ClapprCore } from '@clappr/core';
2
2
  /**
3
- * `PLUGIN` that is responsible for managing the automatic failover between sources.
4
- * @beta
3
+ * `PLUGIN` that is managing the automatic failover between media sources.
4
+ * @public
5
5
  * @remarks
6
6
  * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
7
- * on how sources ordering and selection works.
7
+ * on how sources ordering and selection works. Below is a simplified diagram:
8
+ *
9
+ * ```markdown
10
+ * sources_list:
11
+ * - a.mpd | +--------------------+
12
+ * - b.m3u8 |--->| init |
13
+ * - ... | |--------------------|
14
+ * | current_source = 0 |
15
+ * +--------------------+
16
+ * |
17
+ * | source = a.mpd
18
+ * | playback = dash.js
19
+ * v
20
+ * +------------------+
21
+ * +-->| load source |
22
+ * | +---------|--------+
23
+ * | v
24
+ * | +------------------+
25
+ * | | play |
26
+ * | +---------|--------+
27
+ * | |
28
+ * | v
29
+ * | +-----------------------+
30
+ * | | on playback_error |
31
+ * | |-----------------------|
32
+ * | | current_source = |
33
+ * | | (current_source + 1) |
34
+ * | | % len sources_list |
35
+ * | | |
36
+ * | | delay 1..3s |
37
+ * | +---------------|-------+
38
+ * | |
39
+ * | source=b.m3u8 |
40
+ * | playback=hls.js |
41
+ * +-------------------+
42
+ *
43
+ * ```
8
44
  *
9
45
  * This plugin does not expose any public methods apart from required by the Clappr plugin interface.
10
46
  * It is supposed to work autonomously.
@@ -34,7 +70,7 @@ export declare class SourceController extends CorePlugin {
34
70
  min: string;
35
71
  };
36
72
  /**
37
- * @internal
73
+ * @param core - The Clappr core instance.
38
74
  */
39
75
  constructor(core: ClapprCore);
40
76
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SourceController.d.ts","sourceRoot":"","sources":["../../../src/plugins/source-controller/SourceController.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,KAAK,IAAI,IAAI,UAAU,EACxB,MAAM,cAAc,CAAA;AAwBrB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAuC9C,OAAO,CAAC,WAAW,CAA8B;IAEjD,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,YAAY,CAA6B;IAEjD,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,IAAI,CAAiB;IAE7B;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;gBACS,IAAI,EAAE,UAAU;IAW5B;;OAEG;IACM,UAAU;IAWnB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,2BAA2B;IAwCnC,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;CACF"}
1
+ {"version":3,"file":"SourceController.d.ts","sourceRoot":"","sources":["../../../src/plugins/source-controller/SourceController.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,KAAK,IAAI,IAAI,UAAU,EACxB,MAAM,cAAc,CAAA;AAwBrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAwC9C,OAAO,CAAC,WAAW,CAA8B;IAEjD,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,YAAY,CAA6B;IAEjD,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,IAAI,CAAiB;IAE7B;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;gBACS,IAAI,EAAE,UAAU;IAW5B;;OAEG;IACM,UAAU;IAWnB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,2BAA2B;IAwCnC,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;CACF"}
@@ -12,11 +12,47 @@ function noSync(cb) {
12
12
  queueMicrotask(cb);
13
13
  }
14
14
  /**
15
- * `PLUGIN` that is responsible for managing the automatic failover between sources.
16
- * @beta
15
+ * `PLUGIN` that is managing the automatic failover between media sources.
16
+ * @public
17
17
  * @remarks
18
18
  * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
19
- * on how sources ordering and selection works.
19
+ * on how sources ordering and selection works. Below is a simplified diagram:
20
+ *
21
+ * ```markdown
22
+ * sources_list:
23
+ * - a.mpd | +--------------------+
24
+ * - b.m3u8 |--->| init |
25
+ * - ... | |--------------------|
26
+ * | current_source = 0 |
27
+ * +--------------------+
28
+ * |
29
+ * | source = a.mpd
30
+ * | playback = dash.js
31
+ * v
32
+ * +------------------+
33
+ * +-->| load source |
34
+ * | +---------|--------+
35
+ * | v
36
+ * | +------------------+
37
+ * | | play |
38
+ * | +---------|--------+
39
+ * | |
40
+ * | v
41
+ * | +-----------------------+
42
+ * | | on playback_error |
43
+ * | |-----------------------|
44
+ * | | current_source = |
45
+ * | | (current_source + 1) |
46
+ * | | % len sources_list |
47
+ * | | |
48
+ * | | delay 1..3s |
49
+ * | +---------------|-------+
50
+ * | |
51
+ * | source=b.m3u8 |
52
+ * | playback=hls.js |
53
+ * +-------------------+
54
+ *
55
+ * ```
20
56
  *
21
57
  * This plugin does not expose any public methods apart from required by the Clappr plugin interface.
22
58
  * It is supposed to work autonomously.
@@ -66,6 +102,7 @@ export class SourceController extends CorePlugin {
66
102
  * | playback=hls.js |
67
103
  * +-------------------+
68
104
  *
105
+ * As can be seen from the diagram, the plugin will endless try to load the next sources rotating between them in round-robin manner.
69
106
  */
70
107
  sourcesList = [];
71
108
  currentSourceIndex = 0;
@@ -86,7 +123,7 @@ export class SourceController extends CorePlugin {
86
123
  return { min: CLAPPR_VERSION };
87
124
  }
88
125
  /**
89
- * @internal
126
+ * @param core - The Clappr core instance.
90
127
  */
91
128
  constructor(core) {
92
129
  super(core);
@@ -2,20 +2,20 @@ import { Container, UIContainerPlugin } from '@clappr/core';
2
2
  import '../../../assets/spinner-three-bounce/spinner.scss';
3
3
  /**
4
4
  * Custom events emitted by the plugin
5
- * @beta
5
+ * @public
6
6
  */
7
7
  export declare enum SpinnerEvents {
8
8
  /**
9
9
  * Emitted at the end of the spinner animation cycle to facilitate smooth UI updates,
10
- * e.g. {@link SourceController} listens to this event to reload the source when the spinner is hidden
10
+ * for instance, {@link SourceController} listens to this event to reload the source when the spinner is hidden
11
11
  */
12
12
  SYNC = "plugins:spinner:sync"
13
13
  }
14
14
  /**
15
- * `PLUGIN` that shows a pending operation indicator when playback is buffering or in a similar state
16
- * @beta
15
+ * `PLUGIN` that shows a pending operation indicator when playback is buffering or in a similar state.
16
+ * @public
17
17
  * @remarks
18
- * Events emitted- {@link SpinnerEvents}
18
+ * Events emitted - {@link SpinnerEvents}
19
19
  * Other plugins can use {@link SpinnerThreeBounce.show | show} and {@link SpinnerThreeBounce.hide | hide} methods to
20
20
  * implement custom pending/progress indication scenarios.
21
21
  */
@@ -51,7 +51,9 @@ export declare class SpinnerThreeBounce extends UIContainerPlugin {
51
51
  /**
52
52
  * Shows the spinner.
53
53
  *
54
- * When called, the spinner will not hide (due to its built-in logic) until {@link SpinnerThreeBounce.hide} is called
54
+ * The method call prevents spinner's built-in logic from automatically hiding it until {@link SpinnerThreeBounce.hide} is called
55
+ *
56
+ * @param delay - The delay in milliseconds before the spinner is shown.
55
57
  */
56
58
  show(delay?: number): void;
57
59
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SpinnerThreeBounce.d.ts","sourceRoot":"","sources":["../../../src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,SAAS,EAET,iBAAiB,EAElB,MAAM,cAAc,CAAA;AAKrB,OAAO,mDAAmD,CAAA;AAM1D;;;GAGG;AACH,oBAAY,aAAa;IACvB;;;OAGG;IACH,IAAI,yBAAyB;CAC9B;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,iBAAiB;IACvD,OAAO,CAAC,SAAS,CAAQ;IAEzB;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,IAAa,UAAU;;;MAKtB;IAED,OAAO,CAAC,WAAW,CAAuB;IAE1C,OAAO,CAAC,QAAQ,CAAwB;IAExC,OAAO,CAAC,aAAa,CAAQ;IAE7B,OAAO,CAAC,YAAY,CAAQ;gBAEhB,SAAS,EAAE,SAAS;IAmBhC,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,OAAO;IAUf;;;;OAIG;IACH,IAAI,CAAC,KAAK,SAAM;IAMhB;;OAEG;IACH,IAAI;IAKJ,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,KAAK;IAeb;;OAEG;IACM,MAAM;CAiBhB"}
1
+ {"version":3,"file":"SpinnerThreeBounce.d.ts","sourceRoot":"","sources":["../../../src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,SAAS,EAET,iBAAiB,EAElB,MAAM,cAAc,CAAA;AAKrB,OAAO,mDAAmD,CAAA;AAM1D;;;GAGG;AACH,oBAAY,aAAa;IACvB;;;OAGG;IACH,IAAI,yBAAyB;CAC9B;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,iBAAiB;IACvD,OAAO,CAAC,SAAS,CAAQ;IAEzB;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,IAAa,UAAU;;;MAKtB;IAED,OAAO,CAAC,WAAW,CAAuB;IAE1C,OAAO,CAAC,QAAQ,CAAwB;IAExC,OAAO,CAAC,aAAa,CAAQ;IAE7B,OAAO,CAAC,YAAY,CAAQ;gBAEhB,SAAS,EAAE,SAAS;IAmBhC,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,OAAO;IAUf;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,SAAM;IAMhB;;OAEG;IACH,IAAI;IAKJ,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,KAAK;IAeb;;OAEG;IACM,MAAM;CAiBhB"}
@@ -1,6 +1,8 @@
1
+ // This work is based on the original work of Globo.com
1
2
  // Copyright 2014 Globo.com Player authors. All rights reserved.
2
3
  // Use of this source code is governed by a BSD-style
3
4
  // license that can be found in the LICENSE file.
5
+ // https://github.com/clappr/clappr-plugins/blob/ffaa9d27005fa5a8a7c243ffc47eb5655b84b371/LICENSE
4
6
  import { Events as ClapprEvents, UIContainerPlugin, template, } from '@clappr/core';
5
7
  import { trace } from '@gcorevideo/utils';
6
8
  import { PlaybackErrorCode } from '../../playback.types.js';
@@ -10,21 +12,21 @@ import { CLAPPR_VERSION } from '../../build.js';
10
12
  const T = 'plugins.spinner';
11
13
  /**
12
14
  * Custom events emitted by the plugin
13
- * @beta
15
+ * @public
14
16
  */
15
17
  export var SpinnerEvents;
16
18
  (function (SpinnerEvents) {
17
19
  /**
18
20
  * Emitted at the end of the spinner animation cycle to facilitate smooth UI updates,
19
- * e.g. {@link SourceController} listens to this event to reload the source when the spinner is hidden
21
+ * for instance, {@link SourceController} listens to this event to reload the source when the spinner is hidden
20
22
  */
21
23
  SpinnerEvents["SYNC"] = "plugins:spinner:sync";
22
24
  })(SpinnerEvents || (SpinnerEvents = {}));
23
25
  /**
24
- * `PLUGIN` that shows a pending operation indicator when playback is buffering or in a similar state
25
- * @beta
26
+ * `PLUGIN` that shows a pending operation indicator when playback is buffering or in a similar state.
27
+ * @public
26
28
  * @remarks
27
- * Events emitted- {@link SpinnerEvents}
29
+ * Events emitted - {@link SpinnerEvents}
28
30
  * Other plugins can use {@link SpinnerThreeBounce.show | show} and {@link SpinnerThreeBounce.hide | hide} methods to
29
31
  * implement custom pending/progress indication scenarios.
30
32
  */
@@ -97,7 +99,9 @@ export class SpinnerThreeBounce extends UIContainerPlugin {
97
99
  /**
98
100
  * Shows the spinner.
99
101
  *
100
- * When called, the spinner will not hide (due to its built-in logic) until {@link SpinnerThreeBounce.hide} is called
102
+ * The method call prevents spinner's built-in logic from automatically hiding it until {@link SpinnerThreeBounce.hide} is called
103
+ *
104
+ * @param delay - The delay in milliseconds before the spinner is shown.
101
105
  */
102
106
  show(delay = 300) {
103
107
  trace(`${T} show`);
@@ -1,21 +1,21 @@
1
1
  import { UICorePlugin } from '@clappr/core';
2
2
  import '../../../assets/subtitles/style.scss';
3
+ /**
4
+ * Configuration options for the {@link ClosedCaptions} plugin.
5
+ * @beta
6
+ */
3
7
  export type ClosedCaptionsPluginSettings = {
4
8
  /**
5
- * Initially selected subtitles language
9
+ * Initially selected subtitles language.
6
10
  */
7
11
  language?: string;
8
12
  };
9
- /**
10
- * @deprecated Use {@link ClosedCaptionsPluginSettings} instead.
11
- */
12
- export type SubtitlesPluginSettings = ClosedCaptionsPluginSettings;
13
13
  /**
14
14
  * `PLUGIN` that provides a UI to select the subtitles when available.
15
15
  * @beta
16
16
  *
17
17
  * @remarks
18
- * The plugin is activated when closed captions tracks are provided with the media source.
18
+ * The plugin is activated when closed captions tracks are detected in the media source.
19
19
  * It shows a familiar "CC" button with a dropdown menu to select the subtitles language.
20
20
  *
21
21
  * Depends on:
@@ -32,7 +32,7 @@ export type SubtitlesPluginSettings = ClosedCaptionsPluginSettings;
32
32
  * new Player({
33
33
  * ...
34
34
  * cc: {
35
- * language: 'en',
35
+ * language: 'pt-BR',
36
36
  * },
37
37
  * })
38
38
  * ```