1 | import { isIncompatible, isEnabled } from './playlist.js';
|
2 |
|
3 | /**
|
4 | * Returns a function that acts as the Enable/disable playlist function.
|
5 | *
|
6 | * @param {PlaylistLoader} loader - The master playlist loader
|
7 | * @param {String} playlistUri - uri of the playlist
|
8 | * @param {Function} changePlaylistFn - A function to be called after a
|
9 | * playlist's enabled-state has been changed. Will NOT be called if a
|
10 | * playlist's enabled-state is unchanged
|
11 | * @param {Boolean=} enable - Value to set the playlist enabled-state to
|
12 | * or if undefined returns the current enabled-state for the playlist
|
13 | * @return {Function} Function for setting/getting enabled
|
14 | */
|
15 | const enableFunction = (loader, playlistUri, changePlaylistFn) => (enable) => {
|
16 | const playlist = loader.master.playlists[playlistUri];
|
17 | const incompatible = isIncompatible(playlist);
|
18 | const currentlyEnabled = isEnabled(playlist);
|
19 |
|
20 | if (typeof enable === 'undefined') {
|
21 | return currentlyEnabled;
|
22 | }
|
23 |
|
24 | if (enable) {
|
25 | delete playlist.disabled;
|
26 | } else {
|
27 | playlist.disabled = true;
|
28 | }
|
29 |
|
30 | if (enable !== currentlyEnabled && !incompatible) {
|
31 | // Ensure the outside world knows about our changes
|
32 | changePlaylistFn();
|
33 | if (enable) {
|
34 | loader.trigger('renditionenabled');
|
35 | } else {
|
36 | loader.trigger('renditiondisabled');
|
37 | }
|
38 | }
|
39 | return enable;
|
40 | };
|
41 |
|
42 | /**
|
43 | * The representation object encapsulates the publicly visible information
|
44 | * in a media playlist along with a setter/getter-type function (enabled)
|
45 | * for changing the enabled-state of a particular playlist entry
|
46 | *
|
47 | * @class Representation
|
48 | */
|
49 | class Representation {
|
50 | constructor(hlsHandler, playlist, id) {
|
51 | // Get a reference to a bound version of fastQualityChange_
|
52 | let fastChangeFunction = hlsHandler
|
53 | .masterPlaylistController_
|
54 | .fastQualityChange_
|
55 | .bind(hlsHandler.masterPlaylistController_);
|
56 |
|
57 | // some playlist attributes are optional
|
58 | if (playlist.attributes.RESOLUTION) {
|
59 | const resolution = playlist.attributes.RESOLUTION;
|
60 |
|
61 | this.width = resolution.width;
|
62 | this.height = resolution.height;
|
63 | }
|
64 |
|
65 | this.bandwidth = playlist.attributes.BANDWIDTH;
|
66 |
|
67 | // The id is simply the ordinality of the media playlist
|
68 | // within the master playlist
|
69 | this.id = id;
|
70 |
|
71 | // Partially-apply the enableFunction to create a playlist-
|
72 | // specific variant
|
73 | this.enabled = enableFunction(hlsHandler.playlists,
|
74 | playlist.uri,
|
75 | fastChangeFunction);
|
76 | }
|
77 | }
|
78 |
|
79 | /**
|
80 | * A mixin function that adds the `representations` api to an instance
|
81 | * of the HlsHandler class
|
82 | * @param {HlsHandler} hlsHandler - An instance of HlsHandler to add the
|
83 | * representation API into
|
84 | */
|
85 | let renditionSelectionMixin = function(hlsHandler) {
|
86 | let playlists = hlsHandler.playlists;
|
87 |
|
88 | // Add a single API-specific function to the HlsHandler instance
|
89 | hlsHandler.representations = () => {
|
90 | return playlists
|
91 | .master
|
92 | .playlists
|
93 | .filter((media) => !isIncompatible(media))
|
94 | .map((e, i) => new Representation(hlsHandler, e, e.uri));
|
95 | };
|
96 | };
|
97 |
|
98 | export default renditionSelectionMixin;
|