UNPKG

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