1 | import { isBlacklisted, isEnabled } from './playlist.js';
|
2 | /**
|
3 | * Enable/disable playlist function. It is intended to have the first two
|
4 | * arguments partially-applied in order to create the final per-playlist
|
5 | * function.
|
6 | *
|
7 | * @param {PlaylistLoader} playlist - The rendition or media-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 {Boolean} The current enabled-state of the playlist
|
14 | */
|
15 | const enableFunction = (loader, playlistUri, changePlaylistFn, enable) => {
|
16 | const playlist = loader.master.playlists[playlistUri];
|
17 | const blacklisted = isBlacklisted(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 && !blacklisted) {
|
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 | // Carefully descend into the playlist's attributes since most
|
58 | // properties are optional
|
59 | if (playlist.attributes) {
|
60 | let attributes = playlist.attributes;
|
61 |
|
62 | if (attributes.RESOLUTION) {
|
63 | let resolution = attributes.RESOLUTION;
|
64 |
|
65 | this.width = resolution.width;
|
66 | this.height = resolution.height;
|
67 | }
|
68 |
|
69 | this.bandwidth = attributes.BANDWIDTH;
|
70 | }
|
71 |
|
72 | // The id is simply the ordinality of the media playlist
|
73 | // within the master playlist
|
74 | this.id = id;
|
75 |
|
76 | // Partially-apply the enableFunction to create a playlist-
|
77 | // specific variant
|
78 | this.enabled = enableFunction.bind(this,
|
79 | hlsHandler.playlists,
|
80 | playlist.uri,
|
81 | fastChangeFunction);
|
82 | }
|
83 | }
|
84 |
|
85 | /**
|
86 | * A mixin function that adds the `representations` api to an instance
|
87 | * of the HlsHandler class
|
88 | * @param {HlsHandler} hlsHandler - An instance of HlsHandler to add the
|
89 | * representation API into
|
90 | */
|
91 | let renditionSelectionMixin = function(hlsHandler) {
|
92 | let playlists = hlsHandler.playlists;
|
93 |
|
94 | // Add a single API-specific function to the HlsHandler instance
|
95 | hlsHandler.representations = () => {
|
96 | return playlists
|
97 | .master
|
98 | .playlists
|
99 | .filter((media) => !isBlacklisted(media))
|
100 | .map((e, i) => new Representation(hlsHandler, e, e.uri));
|
101 | };
|
102 | };
|
103 |
|
104 | export default renditionSelectionMixin;
|