bigscreen-player 5.0.0 → 5.1.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 +18 -221
- package/dist/esm/{imscsubtitles-0db3d543.js → imscsubtitles-202e609e.js} +1 -1
- package/dist/esm/{legacysubtitles-1216da7e.js → legacysubtitles-c022e4cc.js} +1 -1
- package/dist/esm/{main-d7e70a16.js → main-9380338b.js} +235 -29
- package/dist/esm/main.js +1 -1
- package/dist/esm/{msestrategy-0fa7b78e.js → msestrategy-e09206c4.js} +1 -1
- package/package.json +4 -1
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
|
-
|
|
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
|
-
|
|
13
|
+
## Running Locally
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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-
|
|
2
|
+
import { b as TimeUtils, L as LoadUrl, a as DebugTool, P as Plugins, U as Utils, D as DOMHelpers } from './main-9380338b.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-
|
|
1
|
+
import { D as DOMHelpers, a as DebugTool, P as Plugins, L as LoadUrl, T as TransportControlPosition } from './main-9380338b.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
|
|
|
@@ -240,7 +248,8 @@ var Plugins = {
|
|
|
240
248
|
onSubtitlesTimeout: (evt) => callOnAllPlugins('onSubtitlesTimeout', evt),
|
|
241
249
|
onSubtitlesXMLError: (evt) => callOnAllPlugins('onSubtitlesXMLError', evt),
|
|
242
250
|
onSubtitlesTransformError: (evt) => callOnAllPlugins('onSubtitlesTransformError', evt),
|
|
243
|
-
onSubtitlesRenderError: (evt) => callOnAllPlugins('onSubtitlesRenderError', evt)
|
|
251
|
+
onSubtitlesRenderError: (evt) => callOnAllPlugins('onSubtitlesRenderError', evt),
|
|
252
|
+
onSubtitlesDynamicLoadError: (evt) => callOnAllPlugins('onSubtitlesDynamicLoadError', evt)
|
|
244
253
|
}
|
|
245
254
|
};
|
|
246
255
|
|
|
@@ -835,21 +844,7 @@ if (instance === undefined) {
|
|
|
835
844
|
|
|
836
845
|
var DebugTool$1 = instance;
|
|
837
846
|
|
|
838
|
-
function PlaybackSpinner () {
|
|
839
|
-
const spinnerContainer = document.createElement('div');
|
|
840
|
-
spinnerContainer.id = 'loadingSpinner';
|
|
841
|
-
spinnerContainer.className = 'loadingSpinner loadingSpinner--large ';
|
|
842
|
-
|
|
843
|
-
const spinner = document.createElement('div');
|
|
844
|
-
spinner.className = 'loadingSpinner__spinner';
|
|
845
|
-
|
|
846
|
-
spinnerContainer.appendChild(spinner);
|
|
847
|
-
|
|
848
|
-
return spinnerContainer
|
|
849
|
-
}
|
|
850
|
-
|
|
851
847
|
function LiveGlitchCurtain (parentElement) {
|
|
852
|
-
let spinner = new PlaybackSpinner();
|
|
853
848
|
let curtain = document.createElement('div');
|
|
854
849
|
|
|
855
850
|
curtain.id = 'liveGlitchCurtain';
|
|
@@ -861,8 +856,6 @@ function LiveGlitchCurtain (parentElement) {
|
|
|
861
856
|
curtain.style.bottom = 0;
|
|
862
857
|
curtain.style.backgroundColor = '#3c3c3c';
|
|
863
858
|
|
|
864
|
-
curtain.appendChild(spinner);
|
|
865
|
-
|
|
866
859
|
return {
|
|
867
860
|
showCurtain: () => {
|
|
868
861
|
curtain.style.display = 'block';
|
|
@@ -871,15 +864,10 @@ function LiveGlitchCurtain (parentElement) {
|
|
|
871
864
|
|
|
872
865
|
hideCurtain: () => {
|
|
873
866
|
curtain.style.display = 'none';
|
|
874
|
-
DOMHelpers.safeRemoveElement(spinner);
|
|
875
867
|
},
|
|
876
868
|
|
|
877
869
|
tearDown: () => {
|
|
878
870
|
DOMHelpers.safeRemoveElement(curtain);
|
|
879
|
-
|
|
880
|
-
if (spinner) {
|
|
881
|
-
spinner = undefined;
|
|
882
|
-
}
|
|
883
871
|
}
|
|
884
872
|
}
|
|
885
873
|
}
|
|
@@ -5683,12 +5671,12 @@ function StrategyPicker (windowType, isUHD) {
|
|
|
5683
5671
|
return resolve(NativeStrategy)
|
|
5684
5672
|
}
|
|
5685
5673
|
|
|
5686
|
-
return import('./msestrategy-
|
|
5674
|
+
return import('./msestrategy-e09206c4.js').then(({default: MSEStrategy}) => resolve(MSEStrategy))
|
|
5687
5675
|
.catch(() => {
|
|
5688
5676
|
reject({error: 'strategyDynamicLoadError'});
|
|
5689
5677
|
})
|
|
5690
5678
|
} else if (window.bigscreenPlayer.playbackStrategy === PlaybackStrategy.MSE) {
|
|
5691
|
-
return import('./msestrategy-
|
|
5679
|
+
return import('./msestrategy-e09206c4.js').then(({default: MSEStrategy}) => resolve(MSEStrategy))
|
|
5692
5680
|
.catch(() => {
|
|
5693
5681
|
reject({error: 'strategyDynamicLoadError'});
|
|
5694
5682
|
})
|
|
@@ -6068,7 +6056,7 @@ function CallCallbacks (callbacks, data) {
|
|
|
6068
6056
|
callbacks.forEach((callback) => DeferExceptions(() => callback(data)));
|
|
6069
6057
|
}
|
|
6070
6058
|
|
|
6071
|
-
var version = "5.
|
|
6059
|
+
var version = "5.1.1";
|
|
6072
6060
|
|
|
6073
6061
|
var sourceList;
|
|
6074
6062
|
var source;
|
|
@@ -7254,14 +7242,18 @@ function Subtitles (mediaPlayer, autoStart, playbackElement, defaultStyleOpts, m
|
|
|
7254
7242
|
let subtitlesContainer;
|
|
7255
7243
|
|
|
7256
7244
|
if (useLegacySubs) {
|
|
7257
|
-
import('./legacysubtitles-
|
|
7245
|
+
import('./legacysubtitles-c022e4cc.js').then(({default: LegacySubtitles}) => {
|
|
7258
7246
|
subtitlesContainer = LegacySubtitles(mediaPlayer, autoStart, playbackElement, mediaSources, defaultStyleOpts);
|
|
7259
7247
|
callback(subtitlesEnabled);
|
|
7248
|
+
}).catch(() => {
|
|
7249
|
+
Plugins.interface.onSubtitlesDynamicLoadError();
|
|
7260
7250
|
});
|
|
7261
7251
|
} else {
|
|
7262
|
-
import('./imscsubtitles-
|
|
7252
|
+
import('./imscsubtitles-202e609e.js').then(({default: IMSCSubtitles}) => {
|
|
7263
7253
|
subtitlesContainer = IMSCSubtitles(mediaPlayer, autoStart, playbackElement, mediaSources, defaultStyleOpts);
|
|
7264
7254
|
callback(subtitlesEnabled);
|
|
7255
|
+
}).catch(() => {
|
|
7256
|
+
Plugins.interface.onSubtitlesDynamicLoadError();
|
|
7265
7257
|
});
|
|
7266
7258
|
}
|
|
7267
7259
|
|
|
@@ -7332,6 +7324,10 @@ function Subtitles (mediaPlayer, autoStart, playbackElement, defaultStyleOpts, m
|
|
|
7332
7324
|
}
|
|
7333
7325
|
}
|
|
7334
7326
|
|
|
7327
|
+
/**
|
|
7328
|
+
* @module bigscreenplayer/bigscreenplayer
|
|
7329
|
+
*/
|
|
7330
|
+
|
|
7335
7331
|
function BigscreenPlayer () {
|
|
7336
7332
|
let stateChangeCallbacks = [];
|
|
7337
7333
|
let timeUpdateCallbacks = [];
|
|
@@ -7489,7 +7485,19 @@ function BigscreenPlayer () {
|
|
|
7489
7485
|
return subtitles ? subtitles.available() : false
|
|
7490
7486
|
}
|
|
7491
7487
|
|
|
7492
|
-
return {
|
|
7488
|
+
return /** @alias module:bigscreenplayer/bigscreenplayer */{
|
|
7489
|
+
|
|
7490
|
+
/**
|
|
7491
|
+
* Call first to initialise bigscreen player for playback.
|
|
7492
|
+
* @function
|
|
7493
|
+
* @name init
|
|
7494
|
+
* @param {HTMLDivElement} playbackElement - The Div element where content elements should be rendered
|
|
7495
|
+
* @param {BigscreenPlayerData} bigscreenPlayerData
|
|
7496
|
+
* @param {WindowTypes} newWindowType
|
|
7497
|
+
* @param {boolean} enableSubtitles - Enable subtitles on initialisation
|
|
7498
|
+
* @param {TALDevice} newDevice - An optional TAL device object
|
|
7499
|
+
* @param {InitCallbacks} callbacks
|
|
7500
|
+
*/
|
|
7493
7501
|
init: (newPlaybackElement, bigscreenPlayerData, newWindowType, enableSubtitles, callbacks) => {
|
|
7494
7502
|
playbackElement = newPlaybackElement;
|
|
7495
7503
|
Chronicle.init();
|
|
@@ -7526,6 +7534,11 @@ function BigscreenPlayer () {
|
|
|
7526
7534
|
mediaSources.init(bigscreenPlayerData.media, serverDate, windowType, getLiveSupport(), mediaSourceCallbacks);
|
|
7527
7535
|
},
|
|
7528
7536
|
|
|
7537
|
+
/**
|
|
7538
|
+
* Should be called at the end of all playback sessions. Resets state and clears any UI.
|
|
7539
|
+
* @function
|
|
7540
|
+
* @name tearDown
|
|
7541
|
+
*/
|
|
7529
7542
|
tearDown: function () {
|
|
7530
7543
|
if (subtitles) {
|
|
7531
7544
|
subtitles.tearDown();
|
|
@@ -7555,11 +7568,22 @@ function BigscreenPlayer () {
|
|
|
7555
7568
|
Chronicle.tearDown();
|
|
7556
7569
|
},
|
|
7557
7570
|
|
|
7571
|
+
/**
|
|
7572
|
+
* Pass a function to call whenever the player transitions state.
|
|
7573
|
+
* @see {@link module:models/mediastate}
|
|
7574
|
+
* @function
|
|
7575
|
+
* @param {Function} callback
|
|
7576
|
+
*/
|
|
7558
7577
|
registerForStateChanges: (callback) => {
|
|
7559
7578
|
stateChangeCallbacks.push(callback);
|
|
7560
7579
|
return callback
|
|
7561
7580
|
},
|
|
7562
7581
|
|
|
7582
|
+
/**
|
|
7583
|
+
* Unregisters a previously registered callback.
|
|
7584
|
+
* @function
|
|
7585
|
+
* @param {Function} callback
|
|
7586
|
+
*/
|
|
7563
7587
|
unregisterForStateChanges: (callback) => {
|
|
7564
7588
|
const indexOf = stateChangeCallbacks.indexOf(callback);
|
|
7565
7589
|
if (indexOf !== -1) {
|
|
@@ -7567,11 +7591,21 @@ function BigscreenPlayer () {
|
|
|
7567
7591
|
}
|
|
7568
7592
|
},
|
|
7569
7593
|
|
|
7594
|
+
/**
|
|
7595
|
+
* Pass a function to call whenever the player issues a time update.
|
|
7596
|
+
* @function
|
|
7597
|
+
* @param {Function} callback
|
|
7598
|
+
*/
|
|
7570
7599
|
registerForTimeUpdates: (callback) => {
|
|
7571
7600
|
timeUpdateCallbacks.push(callback);
|
|
7572
7601
|
return callback
|
|
7573
7602
|
},
|
|
7574
7603
|
|
|
7604
|
+
/**
|
|
7605
|
+
* Unregisters a previously registered callback.
|
|
7606
|
+
* @function
|
|
7607
|
+
* @param {Function} callback
|
|
7608
|
+
*/
|
|
7575
7609
|
unregisterForTimeUpdates: (callback) => {
|
|
7576
7610
|
const indexOf = timeUpdateCallbacks.indexOf(callback);
|
|
7577
7611
|
|
|
@@ -7580,11 +7614,21 @@ function BigscreenPlayer () {
|
|
|
7580
7614
|
}
|
|
7581
7615
|
},
|
|
7582
7616
|
|
|
7617
|
+
/**
|
|
7618
|
+
* Pass a function to be called whenever subtitles are enabled or disabled.
|
|
7619
|
+
* @function
|
|
7620
|
+
* @param {Function} callback
|
|
7621
|
+
*/
|
|
7583
7622
|
registerForSubtitleChanges: (callback) => {
|
|
7584
7623
|
subtitleCallbacks.push(callback);
|
|
7585
7624
|
return callback
|
|
7586
7625
|
},
|
|
7587
7626
|
|
|
7627
|
+
/**
|
|
7628
|
+
* Unregisters a previously registered callback for changes to subtitles.
|
|
7629
|
+
* @function
|
|
7630
|
+
* @param {Function} callback
|
|
7631
|
+
*/
|
|
7588
7632
|
unregisterForSubtitleChanges: (callback) => {
|
|
7589
7633
|
const indexOf = subtitleCallbacks.indexOf(callback);
|
|
7590
7634
|
if (indexOf !== -1) {
|
|
@@ -7592,6 +7636,11 @@ function BigscreenPlayer () {
|
|
|
7592
7636
|
}
|
|
7593
7637
|
},
|
|
7594
7638
|
|
|
7639
|
+
/**
|
|
7640
|
+
* Sets the current time of the media asset.
|
|
7641
|
+
* @function
|
|
7642
|
+
* @param {Number} time - In seconds
|
|
7643
|
+
*/
|
|
7595
7644
|
setCurrentTime: function (time) {
|
|
7596
7645
|
DebugTool$1.apicall('setCurrentTime');
|
|
7597
7646
|
if (playerComponent) {
|
|
@@ -7609,15 +7658,46 @@ function BigscreenPlayer () {
|
|
|
7609
7658
|
},
|
|
7610
7659
|
|
|
7611
7660
|
getPlaybackRate: () => playerComponent && playerComponent.getPlaybackRate(),
|
|
7661
|
+
|
|
7662
|
+
/**
|
|
7663
|
+
* Returns the media asset's current time in seconds.
|
|
7664
|
+
* @function
|
|
7665
|
+
*/
|
|
7612
7666
|
getCurrentTime: () => playerComponent && playerComponent.getCurrentTime() || 0,
|
|
7667
|
+
|
|
7668
|
+
/**
|
|
7669
|
+
* Returns the current media kind.
|
|
7670
|
+
* 'audio' or 'video'
|
|
7671
|
+
* @function
|
|
7672
|
+
*/
|
|
7613
7673
|
getMediaKind: () => mediaKind,
|
|
7674
|
+
|
|
7675
|
+
/**
|
|
7676
|
+
* Returns the current window type.
|
|
7677
|
+
* @see {@link module:bigscreenplayer/models/windowtypes}
|
|
7678
|
+
* @function
|
|
7679
|
+
*/
|
|
7614
7680
|
getWindowType: () => windowType,
|
|
7681
|
+
|
|
7682
|
+
/**
|
|
7683
|
+
* Returns an object including the current start and end times.
|
|
7684
|
+
* @function
|
|
7685
|
+
* @returns {Object} {start: Number, end: Number}
|
|
7686
|
+
*/
|
|
7615
7687
|
getSeekableRange: () => playerComponent ? playerComponent.getSeekableRange() : {},
|
|
7616
7688
|
|
|
7689
|
+
/**
|
|
7690
|
+
* @function
|
|
7691
|
+
* @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).
|
|
7692
|
+
*/
|
|
7617
7693
|
isPlayingAtLiveEdge: function () {
|
|
7618
7694
|
return !!playerComponent && windowType !== WindowTypes.STATIC && Math.abs(this.getSeekableRange().end - this.getCurrentTime()) < END_OF_STREAM_TOLERANCE
|
|
7619
7695
|
},
|
|
7620
7696
|
|
|
7697
|
+
/**
|
|
7698
|
+
* @function
|
|
7699
|
+
* @return {Object} An object of the shape {windowStartTime: Number, windowEndTime: Number, initialPlaybackTime: Number, serverDate: Date}
|
|
7700
|
+
*/
|
|
7621
7701
|
getLiveWindowData: () => {
|
|
7622
7702
|
if (windowType === WindowTypes.STATIC) {
|
|
7623
7703
|
return {}
|
|
@@ -7631,15 +7711,39 @@ function BigscreenPlayer () {
|
|
|
7631
7711
|
}
|
|
7632
7712
|
},
|
|
7633
7713
|
|
|
7714
|
+
/**
|
|
7715
|
+
* @function
|
|
7716
|
+
* @returns the duration of the media asset.
|
|
7717
|
+
*/
|
|
7634
7718
|
getDuration: () => playerComponent && playerComponent.getDuration(),
|
|
7719
|
+
|
|
7720
|
+
/**
|
|
7721
|
+
* @function
|
|
7722
|
+
* @returns if the player is paused.
|
|
7723
|
+
*/
|
|
7635
7724
|
isPaused: () => playerComponent ? playerComponent.isPaused() : true,
|
|
7725
|
+
|
|
7726
|
+
/**
|
|
7727
|
+
* @function
|
|
7728
|
+
* @returns if the media asset has ended.
|
|
7729
|
+
*/
|
|
7636
7730
|
isEnded: () => playerComponent ? playerComponent.isEnded() : false,
|
|
7637
7731
|
|
|
7732
|
+
/**
|
|
7733
|
+
* Play the media assest from the current point in time.
|
|
7734
|
+
* @function
|
|
7735
|
+
*/
|
|
7638
7736
|
play: () => {
|
|
7639
7737
|
DebugTool$1.apicall('play');
|
|
7640
7738
|
playerComponent.play();
|
|
7641
7739
|
},
|
|
7642
|
-
|
|
7740
|
+
/**
|
|
7741
|
+
* Pause the media asset.
|
|
7742
|
+
* @function
|
|
7743
|
+
* @param {*} opts
|
|
7744
|
+
* @param {boolean} opts.userPause
|
|
7745
|
+
* @param {boolean} opts.disableAutoResume
|
|
7746
|
+
*/
|
|
7643
7747
|
pause: (opts) => {
|
|
7644
7748
|
DebugTool$1.apicall('pause');
|
|
7645
7749
|
pauseTrigger = opts && opts.userPause === false ? PauseTriggers.APP : PauseTriggers.USER;
|
|
@@ -7660,8 +7764,23 @@ function BigscreenPlayer () {
|
|
|
7660
7764
|
resizer.clear(playbackElement);
|
|
7661
7765
|
},
|
|
7662
7766
|
|
|
7767
|
+
/**
|
|
7768
|
+
* Set whether or not subtitles should be enabled.
|
|
7769
|
+
* @function
|
|
7770
|
+
* @param {boolean} value
|
|
7771
|
+
*/
|
|
7663
7772
|
setSubtitlesEnabled: setSubtitlesEnabled,
|
|
7773
|
+
|
|
7774
|
+
/**
|
|
7775
|
+
* @function
|
|
7776
|
+
* @return if subtitles are currently enabled.
|
|
7777
|
+
*/
|
|
7664
7778
|
isSubtitlesEnabled: isSubtitlesEnabled,
|
|
7779
|
+
|
|
7780
|
+
/**
|
|
7781
|
+
* @function
|
|
7782
|
+
* @return Returns whether or not subtitles are currently enabled.
|
|
7783
|
+
*/
|
|
7665
7784
|
isSubtitlesAvailable: isSubtitlesAvailable,
|
|
7666
7785
|
|
|
7667
7786
|
areSubtitlesCustomisable: () => {
|
|
@@ -7686,45 +7805,132 @@ function BigscreenPlayer () {
|
|
|
7686
7805
|
}
|
|
7687
7806
|
},
|
|
7688
7807
|
|
|
7808
|
+
/**
|
|
7809
|
+
*
|
|
7810
|
+
* An enum may be used to set the on-screen position of any transport controls
|
|
7811
|
+
* (work in progress to remove this - UI concern).
|
|
7812
|
+
* @function
|
|
7813
|
+
* @param {*} position
|
|
7814
|
+
*/
|
|
7689
7815
|
setTransportControlsPosition: (position) => {
|
|
7690
7816
|
if (subtitles) {
|
|
7691
7817
|
subtitles.setPosition(position);
|
|
7692
7818
|
}
|
|
7693
7819
|
},
|
|
7694
7820
|
|
|
7821
|
+
/**
|
|
7822
|
+
* @function
|
|
7823
|
+
* @return Returns whether the current media asset is seekable.
|
|
7824
|
+
*/
|
|
7695
7825
|
canSeek: function () {
|
|
7696
7826
|
return windowType === WindowTypes.STATIC || DynamicWindowUtils.canSeek(getWindowStartTime(), getWindowEndTime(), getLiveSupport(), this.getSeekableRange())
|
|
7697
7827
|
},
|
|
7698
7828
|
|
|
7829
|
+
/**
|
|
7830
|
+
* @function
|
|
7831
|
+
* @return Returns whether the current media asset is pausable.
|
|
7832
|
+
*/
|
|
7699
7833
|
canPause: () => {
|
|
7700
7834
|
return windowType === WindowTypes.STATIC || DynamicWindowUtils.canPause(getWindowStartTime(), getWindowEndTime(), getLiveSupport())
|
|
7701
7835
|
},
|
|
7702
7836
|
|
|
7837
|
+
/**
|
|
7838
|
+
* Return a mock for in place testing.
|
|
7839
|
+
* @function
|
|
7840
|
+
* @param {*} opts
|
|
7841
|
+
*/
|
|
7703
7842
|
mock: function (opts) { MockBigscreenPlayer.mock(this, opts); },
|
|
7843
|
+
|
|
7844
|
+
/**
|
|
7845
|
+
* Unmock the player.
|
|
7846
|
+
* @function
|
|
7847
|
+
*/
|
|
7704
7848
|
unmock: function () { MockBigscreenPlayer.unmock(this); },
|
|
7849
|
+
|
|
7850
|
+
/**
|
|
7851
|
+
* Return a mock for unit tests.
|
|
7852
|
+
* @function
|
|
7853
|
+
* @param {*} opts
|
|
7854
|
+
*/
|
|
7705
7855
|
mockJasmine: function (opts) { MockBigscreenPlayer.mockJasmine(this, opts); },
|
|
7706
7856
|
|
|
7857
|
+
/**
|
|
7858
|
+
* Register a plugin for extended events.
|
|
7859
|
+
* @function
|
|
7860
|
+
* @param {*} plugin
|
|
7861
|
+
*/
|
|
7707
7862
|
registerPlugin: (plugin) => Plugins.registerPlugin(plugin),
|
|
7863
|
+
|
|
7864
|
+
/**
|
|
7865
|
+
* Unregister a previously registered plugin.
|
|
7866
|
+
* @function
|
|
7867
|
+
* @param {*} plugin
|
|
7868
|
+
*/
|
|
7708
7869
|
unregisterPlugin: (plugin) => Plugins.unregisterPlugin(plugin),
|
|
7870
|
+
|
|
7871
|
+
/**
|
|
7872
|
+
* Returns an object with a number of functions related to the ability to transition state
|
|
7873
|
+
* given the current state and the playback strategy in use.
|
|
7874
|
+
* @function
|
|
7875
|
+
*/
|
|
7709
7876
|
transitions: () => playerComponent ? playerComponent.transitions() : {},
|
|
7877
|
+
|
|
7878
|
+
/**
|
|
7879
|
+
* @function
|
|
7880
|
+
* @return The media element currently being used.
|
|
7881
|
+
*/
|
|
7710
7882
|
getPlayerElement: () => playerComponent && playerComponent.getPlayerElement(),
|
|
7711
7883
|
|
|
7884
|
+
/**
|
|
7885
|
+
* @function
|
|
7886
|
+
* @param {Number} epochTime - Unix Epoch based time in milliseconds.
|
|
7887
|
+
* @return the time in seconds within the current sliding window.
|
|
7888
|
+
*/
|
|
7712
7889
|
convertEpochMsToVideoTimeSeconds: (epochTime) => {
|
|
7713
7890
|
return getWindowStartTime() ? Math.floor((epochTime - getWindowStartTime()) / 1000) : undefined
|
|
7714
7891
|
},
|
|
7715
7892
|
|
|
7893
|
+
/**
|
|
7894
|
+
* @function
|
|
7895
|
+
* @return The runtime version of the library.
|
|
7896
|
+
*/
|
|
7716
7897
|
getFrameworkVersion: () => {
|
|
7717
7898
|
return version
|
|
7718
7899
|
},
|
|
7719
7900
|
|
|
7901
|
+
/**
|
|
7902
|
+
* @function
|
|
7903
|
+
* @param {Number} time - Seconds
|
|
7904
|
+
* @return the time in milliseconds within the current sliding window.
|
|
7905
|
+
*/
|
|
7720
7906
|
convertVideoTimeSecondsToEpochMs: convertVideoTimeSecondsToEpochMs,
|
|
7907
|
+
|
|
7908
|
+
/**
|
|
7909
|
+
* Toggle the visibility of the debug tool overlay.
|
|
7910
|
+
* @function
|
|
7911
|
+
*/
|
|
7721
7912
|
toggleDebug: toggleDebug,
|
|
7913
|
+
|
|
7914
|
+
/**
|
|
7915
|
+
* @function
|
|
7916
|
+
* @return {Object} - Key value pairs of available log levels
|
|
7917
|
+
*/
|
|
7722
7918
|
getLogLevels: () => DebugTool$1.logLevels,
|
|
7919
|
+
|
|
7920
|
+
/**
|
|
7921
|
+
* @function
|
|
7922
|
+
* @param logLevel - log level to display @see getLogLevels
|
|
7923
|
+
*/
|
|
7723
7924
|
setLogLevel: DebugTool$1.setLogLevel,
|
|
7724
7925
|
getDebugLogs: () => Chronicle.retrieve()
|
|
7725
7926
|
}
|
|
7726
7927
|
}
|
|
7727
7928
|
|
|
7929
|
+
/**
|
|
7930
|
+
* @function
|
|
7931
|
+
* @param {TALDevice} device
|
|
7932
|
+
* @return the live support of the device.
|
|
7933
|
+
*/
|
|
7728
7934
|
function getLiveSupport () {
|
|
7729
7935
|
return PlayerComponent.getLiveSupport()
|
|
7730
7936
|
}
|
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-
|
|
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-9380338b.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-
|
|
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-9380338b.js';
|
|
2
2
|
import { MediaPlayer } from 'dashjs/index_mediaplayerOnly';
|
|
3
3
|
|
|
4
4
|
function filter (manifest, representationOptions) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bigscreen-player",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.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",
|