bigscreen-player 5.0.2 → 5.2.1

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/README.md CHANGED
@@ -8,248 +8,45 @@
8
8
 
9
9
  *Bigscreen Player* is an open source project developed by the BBC to simplify video and audio playback on a wide range of 'bigscreen' devices (TVs, set-top boxes, games consoles, and streaming devices).
10
10
 
11
- ## Getting Started
11
+ For documentation on using this library, please see our [Getting Started guide](https://bbc.github.io/bigscreen-player/api/tutorial-Getting%20Started.html).
12
12
 
13
- `$ npm install`
13
+ ## Running Locally
14
14
 
15
- ### Initialisation
16
-
17
- A playback session can be initialised by simply calling the `init()` function with some initial data.
18
-
19
-
20
- The player will render itself into a supplied parent element, and playback will begin as soon as enough data has buffered.
21
-
22
- ```javascript
23
- import { BigscreenPlayer, MediaKinds, WindowTypes } from 'bigscreen-player'
24
-
25
- // configure the media player that will be used before loading
26
- // see below for further details of ths config
27
-
28
- // options are: msestrategy, nativestrategy, hybridstrategy
29
- window.bigscreenPlayer.playbackStrategy = 'msestrategy'
30
-
31
- const bigscreenPlayer = BigscreenPlayer()
32
- const playbackElement = document.createElement('div')
33
- const body = document.getElementByTagName('body')[0]
34
-
35
- playbackElement.id = 'BigscreenPlayback'
36
- body.appendChild(playbackElement)
37
-
38
- const minimalData = {
39
- media: {
40
- type: 'application/dash+xml',
41
- urls: [
42
- {
43
- url: 'https://example.com/video.mpd'
44
- }
45
- ]
46
- }
47
- }
48
-
49
- const optionalData = {
50
- initialPlaybackTime: 0, // Time (in seconds) to begin playback from
51
- media: {
52
- type: 'application/dash+xml',
53
- kind: MediaKinds.VIDEO, // Can be VIDEO, or AUDIO
54
- urls: [
55
- // Multiple urls offer the ability to fail-over to another CDN if required
56
- {
57
- url: 'https://example.com/video.mpd',
58
- cdn: 'origin' // For Debug Tool reference
59
- }, {
60
- url: 'https://failover.example.com/video.mpd',
61
- cdn: 'failover'
62
- }
63
- ],
64
- captions: [{
65
- url: 'https://example.com/captions/$segment$', // $segment$ required for replacement for live subtitle segments
66
- segmentLength: 3.84, // Required to calculate live subtitle segment to fetch & live subtitle URL.
67
- cdn: 'origin' // Displayed by Debug Tool
68
- }, {
69
- url: 'https://failover.example.com/captions/$segment$',
70
- segmentLength: 3.84,
71
- cdn: 'failover'
72
- }
73
- ],
74
- captionsUrl: 'https://example.com/imsc-doc.xml', // NB This parameter is being deprecated in favour of the captions array shown above.
75
- subtitlesRequestTimeout: 5000, // Optional override for the XHR timeout on sidecar loaded subtitles
76
- subtitleCustomisation: {
77
- size: 0.75,
78
- lineHeight: 1.10,
79
- fontFamily: 'Arial',
80
- backgroundColour: 'black' // (css colour, hex)
81
- },
82
- playerSettings: { // This currently can be used to customise settings for the msestrategy. It is a pass through of all the dash.js player settings.
83
- failoverSort: failoverSort, // Post failover custom sorting algorithm
84
- failoverResetTime: 60000,
85
- streaming: {
86
- bufferToKeep: 8
87
- }
88
- }
89
- }
90
- }
91
-
92
- // STATIC for VOD content, GROWING/SLIDING for LIVE content
93
- const windowType = WindowTypes.STATIC
94
- const enableSubtitles = false
95
-
96
- bigscreenPlayer.init(playbackElement, optionalData, windowType, enableSubtitles)
97
- ```
98
-
99
- ### Configuration
100
-
101
- Bigscreen Player has some global configuration that is needed before initialisation. A *playback strategy* may be configured, or defaulted to the native Html5 strategy:
102
-
103
- ```javascript
104
- window.bigscreenPlayer.playbackStrategy = 'msestrategy' // OR 'nativestrategy' OR 'hybridstrategy'
15
+ Install dependencies:
16
+ ```bash
17
+ $ npm install
105
18
  ```
106
19
 
107
- See the [configuration](https://github.com/bbc/bigscreen-player/wiki/Playback-Strategy) wiki page for further details on these strategies.
108
-
109
- ### Reacting to state changes
110
-
111
- State changes which are emitted from the player can be acted upon to by registering a callback. The callback will receive all of the following state changes as the `state` property of the event:
112
- - `MediaState.STOPPED`
113
- - `MediaState.PAUSED`
114
- - `MediaState.PLAYING`
115
- - `MediaState.WAITING`
116
- - `MediaState.ENDED`
117
- - `MediaState.FATAL_ERROR`
118
-
119
- State changes may be registered for before initialisation and will automatically be cleared upon `tearDown()` of the player.
120
-
121
- ```javascript
122
- const bigscreenPlayer = BigscreenPlayer()
123
-
124
- // The token is only required in the case where the function is anonymous, a reference to the function can be stored and used to unregister otherwise.
125
- var stateChangeToken = bigscreenPlayer.registerForStateChanges(function (event) {
126
- if(event.state == MediaState.PLAYING) {
127
- console.log('Playing')
128
- // handle playing event
129
- }
130
- })
131
-
132
- bigscreenPlayer.unregisterForStateChanges(stateChangeToken)
133
- ```
134
-
135
- ### Reacting to time updates
136
-
137
- Time updates are emitted multiple times a second. Your application can register to receive these updates. The emitted object contains the `currentTime` and `endOfStream` properties.
138
-
139
- Time updates may be registered for before initialisation and will automatically be cleared upon `tearDown()` of the player.
140
-
141
- ```javascript
142
- var bigscreenPlayer = BigscreenPlayer();
143
-
144
- // The token is only required in the case where the function is anonymous, a reference to the function can be stored and used to unregister otherwise.
145
- var timeUpdateToken = bigscreenPlayer.registerForTimeUpdates(function (event) {
146
- console.log('Current Time: ' + event.currentTime);
147
- });
148
-
149
- bigscreenPlayer.unRegisterForTimeUpdates(timeUpdateToken);
20
+ You can run Bigscreen Player locally in a dev environment by running:
21
+ ```bash
22
+ $ npm run start
150
23
  ```
151
24
 
152
- ### Reacting to subtitles being turned on/off
153
-
154
- This is emitted on every `setSubtitlesEnabled` call. The emitted object contains an `enabled` property.
155
-
156
- This may be registered for before initialisation and will automatically be cleared upon `tearDown()` of the player.
157
-
158
- ```javascript
159
- var bigscreenPlayer = BigscreenPlayer();
160
-
161
- // The token is only required in the case where the function is anonymous, a reference to the function can be stored and used to unregister otherwise.
162
- var subtitleChangeToken = bigscreenPlayer.registerForSubtitleChanges(function (event) {
163
- console.log('Subttiles enabled: ' + event.enabled);
164
- });
165
-
166
- bigscreenPlayer.unregisterForSubtitleChanges(subtitleChangeToken);
167
- ```
168
-
169
- ### Creating a plugin
170
-
171
- Plugins can be created to extend the functionality of the Bigscreen Player by adhering to an interface which propagates non state change events from the player. For example, when an error is raised or cleared.
172
-
173
- The full interface is as follows:
174
- - `onError`
175
- - `onFatalError`
176
- - `onErrorCleared`
177
- - `onErrorHandled`
178
- - `onBuffering`
179
- - `onBufferingCleared`
180
- - `onScreenCapabilityDetermined`
181
-
182
- An example plugin may look like:
183
-
184
- ```javascript
185
- function ExamplePlugin (appName) {
186
-
187
- var name = appName;
188
-
189
- function onFatalError (evt) {
190
- console.log('A fatal error has occured in the app: ' + name);
191
- }
192
-
193
- function onErrorHandled (evt) {
194
- console.log('The ' + name + ' app is handling a playback error');
195
- }
196
-
197
- return {
198
- onFatalError: onFatalError,
199
- onErrorHandled: onErrorHandled
200
- };
201
- }
202
- ```
203
-
204
- ```javascript
205
- var bigscreenPlayer = BigscreenPlayer();
206
-
207
- var examplePlugin = ExamplePlugin('myApp');
208
-
209
- bigscreenPlayer.registerPlugin(examplePlugin);
210
-
211
- // initialise bigscreenPlayer - see above
212
-
213
- // you should unregister your plugins as part of your playback cleanup
214
-
215
- // calling with no argument will unregister all plugins
216
- bigscreenPlayer.unregisterPlugin(examplePlugin);
217
-
218
- ```
25
+ This will open a web page at `localhost:8080`.
219
26
 
220
27
  ## Testing
221
28
 
222
29
  The project is unit tested using [Jest](https://jestjs.io/). To run the tests:
223
-
224
- `$ npm test`
225
-
30
+ ```bash
31
+ $ npm test
32
+ ```
226
33
  This project currently has unit test coverage but no integration test suite. This is on our Roadmap to address.
227
34
 
228
- ### Mocking media playback
229
-
230
- When writing tests for your application it may be useful to use the mocking functions provided. This creates a fake player with mocking hook functions to simulate real world scenarios.
231
-
232
- See [here](https://github.com/bbc/bigscreen-player/wiki/Mocking-Bigscreen-Player) for example usage.
233
-
234
35
  ## Releasing
235
36
 
236
37
  1. Create a PR.
237
- 2. Label the PR with one of these labels:
238
- - `semver prerelease`
239
- - `semver patch`
240
- - `semver minor`
241
- - `semver major`
242
-
38
+ 2. Label the PR with one of these labels; `semver prerelease`, `semver patch`, `semver minor` or `semver major`
243
39
  3. Get a review from the core team.
244
40
  4. If the PR checks are green. The core team can merge to master.
245
41
  5. Automation takes care of the package versioning.
246
42
  6. Publishing to NPM is handled with our [GitHub Actions CI integration](https://github.com/bbc/bigscreen-player/blob/master/.github/workflows/npm-publish.yml).
247
43
 
44
+ ## Documentation
248
45
 
249
-
250
- ## API Reference
251
-
252
- The API is documented [here](https://github.com/bbc/bigscreen-player/wiki/API-Reference).
46
+ Bigscreen Player uses JSDocs to autogenerate API documentation. To regenerate the documentation run:
47
+ ```bash
48
+ $ npm run docs
49
+ ```
253
50
 
254
51
  ## Contributing
255
52
 
@@ -1,5 +1,5 @@
1
1
  import { fromXML, generateISD, renderHTML } from 'smp-imsc';
2
- import { b as TimeUtils, L as LoadUrl, a as DebugTool, P as Plugins, U as Utils, D as DOMHelpers } from './main-6ba6ec1b.js';
2
+ import { b as TimeUtils, L as LoadUrl, a as DebugTool, P as Plugins, U as Utils, D as DOMHelpers } from './main-ab590038.js';
3
3
 
4
4
  function IMSCSubtitles (mediaPlayer, autoStart, parentElement, mediaSources, defaultStyleOpts) {
5
5
  const SEGMENTS_TO_KEEP = 3;
@@ -1,4 +1,4 @@
1
- import { D as DOMHelpers, a as DebugTool, P as Plugins, L as LoadUrl, T as TransportControlPosition } from './main-6ba6ec1b.js';
1
+ import { D as DOMHelpers, a as DebugTool, P as Plugins, L as LoadUrl, T as TransportControlPosition } from './main-ab590038.js';
2
2
 
3
3
  /**
4
4
  * Safely checks if an attribute exists on an element.
@@ -13,9 +13,17 @@ const MediaState = {
13
13
  FATAL_ERROR: 6
14
14
  };
15
15
 
16
+ /**
17
+ * Enums for WindowTypes
18
+ * @readonly
19
+ * @enum {string}
20
+ */
16
21
  const WindowTypes = {
22
+ /** Media with a duration */
17
23
  STATIC: 'staticWindow',
24
+ /** Media with a start time but without a duration until an indeterminate time in the future */
18
25
  GROWING: 'growingWindow',
26
+ /** Media with a rewind window that progresses through a media timeline */
19
27
  SLIDING: 'slidingWindow'
20
28
  };
21
29
 
@@ -236,6 +244,8 @@ var Plugins = {
236
244
  onBufferingCleared: (evt) => callOnAllPlugins('onBufferingCleared', evt),
237
245
  onScreenCapabilityDetermined: (tvInfo) => callOnAllPlugins('onScreenCapabilityDetermined', tvInfo),
238
246
  onPlayerInfoUpdated: (evt) => callOnAllPlugins('onPlayerInfoUpdated', evt),
247
+ onManifestLoaded: (manifest) => callOnAllPlugins('onManifestLoaded', manifest),
248
+ onQualityChangedRendered: (evt) => callOnAllPlugins('onQualityChangedRendered', evt),
239
249
  onSubtitlesLoadError: (evt) => callOnAllPlugins('onSubtitlesLoadError', evt),
240
250
  onSubtitlesTimeout: (evt) => callOnAllPlugins('onSubtitlesTimeout', evt),
241
251
  onSubtitlesXMLError: (evt) => callOnAllPlugins('onSubtitlesXMLError', evt),
@@ -836,21 +846,7 @@ if (instance === undefined) {
836
846
 
837
847
  var DebugTool$1 = instance;
838
848
 
839
- function PlaybackSpinner () {
840
- const spinnerContainer = document.createElement('div');
841
- spinnerContainer.id = 'loadingSpinner';
842
- spinnerContainer.className = 'loadingSpinner loadingSpinner--large ';
843
-
844
- const spinner = document.createElement('div');
845
- spinner.className = 'loadingSpinner__spinner';
846
-
847
- spinnerContainer.appendChild(spinner);
848
-
849
- return spinnerContainer
850
- }
851
-
852
849
  function LiveGlitchCurtain (parentElement) {
853
- let spinner = new PlaybackSpinner();
854
850
  let curtain = document.createElement('div');
855
851
 
856
852
  curtain.id = 'liveGlitchCurtain';
@@ -862,8 +858,6 @@ function LiveGlitchCurtain (parentElement) {
862
858
  curtain.style.bottom = 0;
863
859
  curtain.style.backgroundColor = '#3c3c3c';
864
860
 
865
- curtain.appendChild(spinner);
866
-
867
861
  return {
868
862
  showCurtain: () => {
869
863
  curtain.style.display = 'block';
@@ -872,15 +866,10 @@ function LiveGlitchCurtain (parentElement) {
872
866
 
873
867
  hideCurtain: () => {
874
868
  curtain.style.display = 'none';
875
- DOMHelpers.safeRemoveElement(spinner);
876
869
  },
877
870
 
878
871
  tearDown: () => {
879
872
  DOMHelpers.safeRemoveElement(curtain);
880
-
881
- if (spinner) {
882
- spinner = undefined;
883
- }
884
873
  }
885
874
  }
886
875
  }
@@ -5684,12 +5673,12 @@ function StrategyPicker (windowType, isUHD) {
5684
5673
  return resolve(NativeStrategy)
5685
5674
  }
5686
5675
 
5687
- return import('./msestrategy-a4167ac9.js').then(({default: MSEStrategy}) => resolve(MSEStrategy))
5676
+ return import('./msestrategy-223ded9f.js').then(({default: MSEStrategy}) => resolve(MSEStrategy))
5688
5677
  .catch(() => {
5689
5678
  reject({error: 'strategyDynamicLoadError'});
5690
5679
  })
5691
5680
  } else if (window.bigscreenPlayer.playbackStrategy === PlaybackStrategy.MSE) {
5692
- return import('./msestrategy-a4167ac9.js').then(({default: MSEStrategy}) => resolve(MSEStrategy))
5681
+ return import('./msestrategy-223ded9f.js').then(({default: MSEStrategy}) => resolve(MSEStrategy))
5693
5682
  .catch(() => {
5694
5683
  reject({error: 'strategyDynamicLoadError'});
5695
5684
  })
@@ -6069,7 +6058,7 @@ function CallCallbacks (callbacks, data) {
6069
6058
  callbacks.forEach((callback) => DeferExceptions(() => callback(data)));
6070
6059
  }
6071
6060
 
6072
- var version = "5.0.2";
6061
+ var version = "5.2.1";
6073
6062
 
6074
6063
  var sourceList;
6075
6064
  var source;
@@ -7255,14 +7244,14 @@ function Subtitles (mediaPlayer, autoStart, playbackElement, defaultStyleOpts, m
7255
7244
  let subtitlesContainer;
7256
7245
 
7257
7246
  if (useLegacySubs) {
7258
- import('./legacysubtitles-f8a640e9.js').then(({default: LegacySubtitles}) => {
7247
+ import('./legacysubtitles-e0e55e63.js').then(({default: LegacySubtitles}) => {
7259
7248
  subtitlesContainer = LegacySubtitles(mediaPlayer, autoStart, playbackElement, mediaSources, defaultStyleOpts);
7260
7249
  callback(subtitlesEnabled);
7261
7250
  }).catch(() => {
7262
7251
  Plugins.interface.onSubtitlesDynamicLoadError();
7263
7252
  });
7264
7253
  } else {
7265
- import('./imscsubtitles-000a037d.js').then(({default: IMSCSubtitles}) => {
7254
+ import('./imscsubtitles-65c7604e.js').then(({default: IMSCSubtitles}) => {
7266
7255
  subtitlesContainer = IMSCSubtitles(mediaPlayer, autoStart, playbackElement, mediaSources, defaultStyleOpts);
7267
7256
  callback(subtitlesEnabled);
7268
7257
  }).catch(() => {
@@ -7337,6 +7326,10 @@ function Subtitles (mediaPlayer, autoStart, playbackElement, defaultStyleOpts, m
7337
7326
  }
7338
7327
  }
7339
7328
 
7329
+ /**
7330
+ * @module bigscreenplayer/bigscreenplayer
7331
+ */
7332
+
7340
7333
  function BigscreenPlayer () {
7341
7334
  let stateChangeCallbacks = [];
7342
7335
  let timeUpdateCallbacks = [];
@@ -7494,7 +7487,19 @@ function BigscreenPlayer () {
7494
7487
  return subtitles ? subtitles.available() : false
7495
7488
  }
7496
7489
 
7497
- return {
7490
+ return /** @alias module:bigscreenplayer/bigscreenplayer */{
7491
+
7492
+ /**
7493
+ * Call first to initialise bigscreen player for playback.
7494
+ * @function
7495
+ * @name init
7496
+ * @param {HTMLDivElement} playbackElement - The Div element where content elements should be rendered
7497
+ * @param {BigscreenPlayerData} bigscreenPlayerData
7498
+ * @param {WindowTypes} newWindowType
7499
+ * @param {boolean} enableSubtitles - Enable subtitles on initialisation
7500
+ * @param {TALDevice} newDevice - An optional TAL device object
7501
+ * @param {InitCallbacks} callbacks
7502
+ */
7498
7503
  init: (newPlaybackElement, bigscreenPlayerData, newWindowType, enableSubtitles, callbacks) => {
7499
7504
  playbackElement = newPlaybackElement;
7500
7505
  Chronicle.init();
@@ -7531,6 +7536,11 @@ function BigscreenPlayer () {
7531
7536
  mediaSources.init(bigscreenPlayerData.media, serverDate, windowType, getLiveSupport(), mediaSourceCallbacks);
7532
7537
  },
7533
7538
 
7539
+ /**
7540
+ * Should be called at the end of all playback sessions. Resets state and clears any UI.
7541
+ * @function
7542
+ * @name tearDown
7543
+ */
7534
7544
  tearDown: function () {
7535
7545
  if (subtitles) {
7536
7546
  subtitles.tearDown();
@@ -7560,11 +7570,22 @@ function BigscreenPlayer () {
7560
7570
  Chronicle.tearDown();
7561
7571
  },
7562
7572
 
7573
+ /**
7574
+ * Pass a function to call whenever the player transitions state.
7575
+ * @see {@link module:models/mediastate}
7576
+ * @function
7577
+ * @param {Function} callback
7578
+ */
7563
7579
  registerForStateChanges: (callback) => {
7564
7580
  stateChangeCallbacks.push(callback);
7565
7581
  return callback
7566
7582
  },
7567
7583
 
7584
+ /**
7585
+ * Unregisters a previously registered callback.
7586
+ * @function
7587
+ * @param {Function} callback
7588
+ */
7568
7589
  unregisterForStateChanges: (callback) => {
7569
7590
  const indexOf = stateChangeCallbacks.indexOf(callback);
7570
7591
  if (indexOf !== -1) {
@@ -7572,11 +7593,21 @@ function BigscreenPlayer () {
7572
7593
  }
7573
7594
  },
7574
7595
 
7596
+ /**
7597
+ * Pass a function to call whenever the player issues a time update.
7598
+ * @function
7599
+ * @param {Function} callback
7600
+ */
7575
7601
  registerForTimeUpdates: (callback) => {
7576
7602
  timeUpdateCallbacks.push(callback);
7577
7603
  return callback
7578
7604
  },
7579
7605
 
7606
+ /**
7607
+ * Unregisters a previously registered callback.
7608
+ * @function
7609
+ * @param {Function} callback
7610
+ */
7580
7611
  unregisterForTimeUpdates: (callback) => {
7581
7612
  const indexOf = timeUpdateCallbacks.indexOf(callback);
7582
7613
 
@@ -7585,11 +7616,21 @@ function BigscreenPlayer () {
7585
7616
  }
7586
7617
  },
7587
7618
 
7619
+ /**
7620
+ * Pass a function to be called whenever subtitles are enabled or disabled.
7621
+ * @function
7622
+ * @param {Function} callback
7623
+ */
7588
7624
  registerForSubtitleChanges: (callback) => {
7589
7625
  subtitleCallbacks.push(callback);
7590
7626
  return callback
7591
7627
  },
7592
7628
 
7629
+ /**
7630
+ * Unregisters a previously registered callback for changes to subtitles.
7631
+ * @function
7632
+ * @param {Function} callback
7633
+ */
7593
7634
  unregisterForSubtitleChanges: (callback) => {
7594
7635
  const indexOf = subtitleCallbacks.indexOf(callback);
7595
7636
  if (indexOf !== -1) {
@@ -7597,6 +7638,11 @@ function BigscreenPlayer () {
7597
7638
  }
7598
7639
  },
7599
7640
 
7641
+ /**
7642
+ * Sets the current time of the media asset.
7643
+ * @function
7644
+ * @param {Number} time - In seconds
7645
+ */
7600
7646
  setCurrentTime: function (time) {
7601
7647
  DebugTool$1.apicall('setCurrentTime');
7602
7648
  if (playerComponent) {
@@ -7614,15 +7660,46 @@ function BigscreenPlayer () {
7614
7660
  },
7615
7661
 
7616
7662
  getPlaybackRate: () => playerComponent && playerComponent.getPlaybackRate(),
7663
+
7664
+ /**
7665
+ * Returns the media asset's current time in seconds.
7666
+ * @function
7667
+ */
7617
7668
  getCurrentTime: () => playerComponent && playerComponent.getCurrentTime() || 0,
7669
+
7670
+ /**
7671
+ * Returns the current media kind.
7672
+ * 'audio' or 'video'
7673
+ * @function
7674
+ */
7618
7675
  getMediaKind: () => mediaKind,
7676
+
7677
+ /**
7678
+ * Returns the current window type.
7679
+ * @see {@link module:bigscreenplayer/models/windowtypes}
7680
+ * @function
7681
+ */
7619
7682
  getWindowType: () => windowType,
7683
+
7684
+ /**
7685
+ * Returns an object including the current start and end times.
7686
+ * @function
7687
+ * @returns {Object} {start: Number, end: Number}
7688
+ */
7620
7689
  getSeekableRange: () => playerComponent ? playerComponent.getSeekableRange() : {},
7621
7690
 
7691
+ /**
7692
+ * @function
7693
+ * @returns {boolean} Returns true if media is initialised and playing a live stream within a tolerance of the end of the seekable range (10 seconds).
7694
+ */
7622
7695
  isPlayingAtLiveEdge: function () {
7623
7696
  return !!playerComponent && windowType !== WindowTypes.STATIC && Math.abs(this.getSeekableRange().end - this.getCurrentTime()) < END_OF_STREAM_TOLERANCE
7624
7697
  },
7625
7698
 
7699
+ /**
7700
+ * @function
7701
+ * @return {Object} An object of the shape {windowStartTime: Number, windowEndTime: Number, initialPlaybackTime: Number, serverDate: Date}
7702
+ */
7626
7703
  getLiveWindowData: () => {
7627
7704
  if (windowType === WindowTypes.STATIC) {
7628
7705
  return {}
@@ -7636,15 +7713,39 @@ function BigscreenPlayer () {
7636
7713
  }
7637
7714
  },
7638
7715
 
7716
+ /**
7717
+ * @function
7718
+ * @returns the duration of the media asset.
7719
+ */
7639
7720
  getDuration: () => playerComponent && playerComponent.getDuration(),
7721
+
7722
+ /**
7723
+ * @function
7724
+ * @returns if the player is paused.
7725
+ */
7640
7726
  isPaused: () => playerComponent ? playerComponent.isPaused() : true,
7727
+
7728
+ /**
7729
+ * @function
7730
+ * @returns if the media asset has ended.
7731
+ */
7641
7732
  isEnded: () => playerComponent ? playerComponent.isEnded() : false,
7642
7733
 
7734
+ /**
7735
+ * Play the media assest from the current point in time.
7736
+ * @function
7737
+ */
7643
7738
  play: () => {
7644
7739
  DebugTool$1.apicall('play');
7645
7740
  playerComponent.play();
7646
7741
  },
7647
-
7742
+ /**
7743
+ * Pause the media asset.
7744
+ * @function
7745
+ * @param {*} opts
7746
+ * @param {boolean} opts.userPause
7747
+ * @param {boolean} opts.disableAutoResume
7748
+ */
7648
7749
  pause: (opts) => {
7649
7750
  DebugTool$1.apicall('pause');
7650
7751
  pauseTrigger = opts && opts.userPause === false ? PauseTriggers.APP : PauseTriggers.USER;
@@ -7665,8 +7766,23 @@ function BigscreenPlayer () {
7665
7766
  resizer.clear(playbackElement);
7666
7767
  },
7667
7768
 
7769
+ /**
7770
+ * Set whether or not subtitles should be enabled.
7771
+ * @function
7772
+ * @param {boolean} value
7773
+ */
7668
7774
  setSubtitlesEnabled: setSubtitlesEnabled,
7775
+
7776
+ /**
7777
+ * @function
7778
+ * @return if subtitles are currently enabled.
7779
+ */
7669
7780
  isSubtitlesEnabled: isSubtitlesEnabled,
7781
+
7782
+ /**
7783
+ * @function
7784
+ * @return Returns whether or not subtitles are currently enabled.
7785
+ */
7670
7786
  isSubtitlesAvailable: isSubtitlesAvailable,
7671
7787
 
7672
7788
  areSubtitlesCustomisable: () => {
@@ -7691,45 +7807,132 @@ function BigscreenPlayer () {
7691
7807
  }
7692
7808
  },
7693
7809
 
7810
+ /**
7811
+ *
7812
+ * An enum may be used to set the on-screen position of any transport controls
7813
+ * (work in progress to remove this - UI concern).
7814
+ * @function
7815
+ * @param {*} position
7816
+ */
7694
7817
  setTransportControlsPosition: (position) => {
7695
7818
  if (subtitles) {
7696
7819
  subtitles.setPosition(position);
7697
7820
  }
7698
7821
  },
7699
7822
 
7823
+ /**
7824
+ * @function
7825
+ * @return Returns whether the current media asset is seekable.
7826
+ */
7700
7827
  canSeek: function () {
7701
7828
  return windowType === WindowTypes.STATIC || DynamicWindowUtils.canSeek(getWindowStartTime(), getWindowEndTime(), getLiveSupport(), this.getSeekableRange())
7702
7829
  },
7703
7830
 
7831
+ /**
7832
+ * @function
7833
+ * @return Returns whether the current media asset is pausable.
7834
+ */
7704
7835
  canPause: () => {
7705
7836
  return windowType === WindowTypes.STATIC || DynamicWindowUtils.canPause(getWindowStartTime(), getWindowEndTime(), getLiveSupport())
7706
7837
  },
7707
7838
 
7839
+ /**
7840
+ * Return a mock for in place testing.
7841
+ * @function
7842
+ * @param {*} opts
7843
+ */
7708
7844
  mock: function (opts) { MockBigscreenPlayer.mock(this, opts); },
7845
+
7846
+ /**
7847
+ * Unmock the player.
7848
+ * @function
7849
+ */
7709
7850
  unmock: function () { MockBigscreenPlayer.unmock(this); },
7851
+
7852
+ /**
7853
+ * Return a mock for unit tests.
7854
+ * @function
7855
+ * @param {*} opts
7856
+ */
7710
7857
  mockJasmine: function (opts) { MockBigscreenPlayer.mockJasmine(this, opts); },
7711
7858
 
7859
+ /**
7860
+ * Register a plugin for extended events.
7861
+ * @function
7862
+ * @param {*} plugin
7863
+ */
7712
7864
  registerPlugin: (plugin) => Plugins.registerPlugin(plugin),
7865
+
7866
+ /**
7867
+ * Unregister a previously registered plugin.
7868
+ * @function
7869
+ * @param {*} plugin
7870
+ */
7713
7871
  unregisterPlugin: (plugin) => Plugins.unregisterPlugin(plugin),
7872
+
7873
+ /**
7874
+ * Returns an object with a number of functions related to the ability to transition state
7875
+ * given the current state and the playback strategy in use.
7876
+ * @function
7877
+ */
7714
7878
  transitions: () => playerComponent ? playerComponent.transitions() : {},
7879
+
7880
+ /**
7881
+ * @function
7882
+ * @return The media element currently being used.
7883
+ */
7715
7884
  getPlayerElement: () => playerComponent && playerComponent.getPlayerElement(),
7716
7885
 
7886
+ /**
7887
+ * @function
7888
+ * @param {Number} epochTime - Unix Epoch based time in milliseconds.
7889
+ * @return the time in seconds within the current sliding window.
7890
+ */
7717
7891
  convertEpochMsToVideoTimeSeconds: (epochTime) => {
7718
7892
  return getWindowStartTime() ? Math.floor((epochTime - getWindowStartTime()) / 1000) : undefined
7719
7893
  },
7720
7894
 
7895
+ /**
7896
+ * @function
7897
+ * @return The runtime version of the library.
7898
+ */
7721
7899
  getFrameworkVersion: () => {
7722
7900
  return version
7723
7901
  },
7724
7902
 
7903
+ /**
7904
+ * @function
7905
+ * @param {Number} time - Seconds
7906
+ * @return the time in milliseconds within the current sliding window.
7907
+ */
7725
7908
  convertVideoTimeSecondsToEpochMs: convertVideoTimeSecondsToEpochMs,
7909
+
7910
+ /**
7911
+ * Toggle the visibility of the debug tool overlay.
7912
+ * @function
7913
+ */
7726
7914
  toggleDebug: toggleDebug,
7915
+
7916
+ /**
7917
+ * @function
7918
+ * @return {Object} - Key value pairs of available log levels
7919
+ */
7727
7920
  getLogLevels: () => DebugTool$1.logLevels,
7921
+
7922
+ /**
7923
+ * @function
7924
+ * @param logLevel - log level to display @see getLogLevels
7925
+ */
7728
7926
  setLogLevel: DebugTool$1.setLogLevel,
7729
7927
  getDebugLogs: () => Chronicle.retrieve()
7730
7928
  }
7731
7929
  }
7732
7930
 
7931
+ /**
7932
+ * @function
7933
+ * @param {TALDevice} device
7934
+ * @return the live support of the device.
7935
+ */
7733
7936
  function getLiveSupport () {
7734
7937
  return PlayerComponent.getLiveSupport()
7735
7938
  }
package/dist/esm/main.js CHANGED
@@ -1 +1 @@
1
- export { B as BigscreenPlayer, c as LiveSupport, d as MediaKinds, M as MediaState, f as MockBigscreenPlayer, g as PauseTriggers, h as PlaybackStrategy, i as TransferFormat, T as TransportControlPosition, W as WindowTypes } from './main-6ba6ec1b.js';
1
+ export { B as BigscreenPlayer, c as LiveSupport, d as MediaKinds, M as MediaState, f as MockBigscreenPlayer, g as PauseTriggers, h as PlaybackStrategy, i as TransferFormat, T as TransportControlPosition, W as WindowTypes } from './main-ab590038.js';
@@ -1,4 +1,4 @@
1
- import { D as DOMHelpers, W as WindowTypes, c as LiveSupport, M as MediaState, a as DebugTool, d as MediaKinds, P as Plugins, U as Utils, b as TimeUtils, e as DynamicWindowUtils } from './main-6ba6ec1b.js';
1
+ import { D as DOMHelpers, W as WindowTypes, c as LiveSupport, M as MediaState, a as DebugTool, P as Plugins, d as MediaKinds, U as Utils, b as TimeUtils, e as DynamicWindowUtils } from './main-ab590038.js';
2
2
  import { MediaPlayer } from 'dashjs/index_mediaplayerOnly';
3
3
 
4
4
  function filter (manifest, representationOptions) {
@@ -259,9 +259,15 @@ function MSEStrategy (mediaSources, windowType, mediaKind, playbackElement, isUH
259
259
 
260
260
  ManifestModifier.filter(manifest, representationOptions);
261
261
  ManifestModifier.generateBaseUrls(manifest, mediaSources.availableSources());
262
+
263
+ emitManifestInfo(manifest);
262
264
  }
263
265
  }
264
266
 
267
+ function emitManifestInfo (manifest) {
268
+ Plugins.interface.onManifestLoaded(manifest);
269
+ }
270
+
265
271
  function onManifestValidityChange (event) {
266
272
  DebugTool.info('Manifest validity changed. Duration is: ' + event.newDuration);
267
273
  }
@@ -325,6 +331,7 @@ function MSEStrategy (mediaSources, windowType, mediaKind, playbackElement, isUH
325
331
  }
326
332
 
327
333
  emitPlayerInfo();
334
+ Plugins.interface.onQualityChangedRendered(event);
328
335
  }
329
336
 
330
337
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigscreen-player",
3
- "version": "5.0.2",
3
+ "version": "5.2.1",
4
4
  "description": "Simplified media playback for bigscreen devices.",
5
5
  "main": "dist/esm/main.js",
6
6
  "browser": "dist/esm/main.js",
@@ -15,6 +15,7 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "prepare": "[ ! -d dist/ ] && npm run build || exit 0",
18
+ "docs": "npx jsdoc -c jsdoc.conf.json",
18
19
  "build": "rollup -c rollup.config.js",
19
20
  "start": "rollup -c rollup.dev.config.js -w",
20
21
  "test": "jest",
@@ -37,6 +38,7 @@
37
38
  "@rollup/plugin-json": "^4.1.0",
38
39
  "@rollup/plugin-node-resolve": "^13.0.4",
39
40
  "babel-jest": "^27.0.6",
41
+ "clean-jsdoc-theme": "^3.2.7",
40
42
  "eslint": "^7.2.0",
41
43
  "eslint-plugin-es5": "1.3.1",
42
44
  "eslint-plugin-jest": "^24.4.0",
@@ -45,6 +47,7 @@
45
47
  "eslint-plugin-standard": "4.0.0",
46
48
  "husky": "^4.2.5",
47
49
  "jest": "^27.0.6",
50
+ "jsdoc": "^3.6.4",
48
51
  "rollup": "^2.54.0",
49
52
  "rollup-plugin-livereload": "^2.0.5",
50
53
  "rollup-plugin-polyfill-node": "^0.7.0",