PageSourceSearch

https://www.samroxaschua.com/wp-content/plugins/wpstream/public/js…m-quality-selector.js?ver=4.11.2.1777031839

js samroxaschua.com collected 2026-09-26 10:15:20 UTC 5,626 bytes, 209 lines download raw bytes

1/**
2 * WpStream quality selector for Video.js (VHS/HLS).
3 *
4 * Avoids external selector plugins that can break on Video.js 8.
5 * Requires: videojs-contrib-quality-levels
6 */
7(function (window) {
8  'use strict';
9
10  if (!window.videojs) {
11    return;
12  }
13
14  const videojs = window.videojs;
15
16  function isHlsPlayer(player) {
17    try {
18      // VHS exposes qualityLevels() on the player when HLS/MPD tech is used
19      return typeof player.qualityLevels === 'function';
20    } catch (e) {
21      return false;
22    }
23  }
24
25  function getLevels(player) {
26    try {
27      const ql = player.qualityLevels();
28      if (!ql) return [];
29      const arr = [];
30      for (let i = 0; i < ql.length; i++) arr.push(ql[i]);
31      return arr;
32    } catch (e) {
33      return [];
34    }
35  }
36
37  function prettyLabel(level) {
38    if (!level) return '';
39    const h = level.height;
40    const w = level.width;
41    const br = level.bitrate;
42    if (h) return `${h}p`;
43    if (w && level.height) return `${w}x${level.height}`;
44    if (br) return `${Math.round(br / 1000)} kbps`;
45    return 'Quality';
46  }
47
48  function enableAll(levels) {
49    levels.forEach((l) => {
50      try {
51        l.enabled = true;
52      } catch (e) {}
53    });
54  }
55
56  function enableOnly(levels, selected) {
57    levels.forEach((l) => {
58      try {
59        l.enabled = l === selected;
60      } catch (e) {}
61    });
62  }
63
64  const MenuButton = videojs.getComponent('MenuButton');
65  const MenuItem = videojs.getComponent('MenuItem');
66
67  class WpstreamQualityMenuItem extends MenuItem {
68    constructor(player, options) {
69      super(player, options);
70      this.wpstreamLevel = options.wpstreamLevel || null;
71      this.wpstreamIsAuto = !!options.wpstreamIsAuto;
72      this.controlText(options.label || '');
73      this.addClass('vjs-wpstream-quality-item');
74      this.selected(!!options.selected);
75    }
76
77    handleClick() {
78      const player = this.player();
79      const levels = getLevels(player);
80
81      if (this.wpstreamIsAuto) {
82        enableAll(levels);
83        try {
84          player.trigger('wpstreamqualitychange');
85        } catch (e) {}
86        return;
87      }
88
89      if (this.wpstreamLevel) {
90        enableOnly(levels, this.wpstreamLevel);
91        try {
92          player.trigger('wpstreamqualitychange');
93        } catch (e) {}
94      }
95    }
96  }
97
98  class WpstreamQualityMenuButton extends MenuButton {
99    constructor(player, options) {
100      super(player, options);
101      this.addClass('vjs-wpstream-quality');
102      this.controlText('Quality');
103
104      // Rebuild menu when quality levels change.
105      player.on('loadedmetadata', () => this.update());
106      player.on('loadeddata', () => this.update());
107      player.on('wpstreamqualitychange', () => this.update());
108
109      try {
110        const ql = player.qualityLevels && player.qualityLevels();
111        if (ql && typeof ql.on === 'function') {
112          ql.on('addqualitylevel', () => this.update());
113          ql.on('removequalitylevel', () => this.update());
114          ql.on('change', () => this.update());
115        }
116      } catch (e) {}
117    }
118
119    createItems() {
120      const player = this.player();
121      const levels = getLevels(player);
122
123      // Always show the menu button, even if there's only one level.
124      // This is useful for debugging / confirming the stream is being interpreted as HLS.
125      try {
126        this.show();
127      } catch (e) {}
128
129      const sorted = levels
130        .slice()
131        .sort((a, b) => (b.height || 0) - (a.height || 0) || (b.bitrate || 0) - (a.bitrate || 0));
132
133      const items = [];
134
135      // Auto
136      items.push(
137        new WpstreamQualityMenuItem(player, {
138          label: 'Auto',
139          wpstreamIsAuto: true,
140          selectable: true,
141          selected: sorted.length > 0 ? sorted.every((l) => l.enabled === true) : true,
142        })
143      );
144
145      // If VHS hasn't populated levels yet, keep Auto only (menu still visible).
146      if (sorted.length === 0) {
147        return items;
148      }
149
150      // Dedupe by label (common case: duplicate heights)
151      const seen = new Set();
152      sorted.forEach((level) => {
153        const label = prettyLabel(level);
154        if (!label) return;
155        if (seen.has(label)) return;
156        seen.add(label);
157
158        items.push(
159          new WpstreamQualityMenuItem(player, {
160            label,
161            wpstreamLevel: level,
162            selectable: true,
163            selected: level.enabled === true && sorted.filter((l) => l.enabled === true).length === 1,
164          })
165        );
166      });
167
168      return items;
169    }
170  }
171
172  videojs.registerComponent('WpstreamQualityMenuButton', WpstreamQualityMenuButton);
173
174  /**
175   * Install the quality menu on a player.
176   */
177  function install(player) {
178    if (!player || player.isDisposed && player.isDisposed()) return;
179
180    // Ensure we only install once.
181    if (player.wpstreamQualitySelectorInitialized) return;
182    player.wpstreamQualitySelectorInitialized = true;
183
184    // Only for VHS/HLS players.
185    if (!isHlsPlayer(player)) return;
186
187    player.ready(function () {
188      try {
189        const cb = player.getChild('controlBar');
190        if (!cb) return;
191
192        // Avoid duplicates.
193        if (cb.getChild('WpstreamQualityMenuButton')) return;
194
195        // Place near the right side (before fullscreen if available)
196        const children = cb.children();
197        let insertIndex = children ? children.length - 2 : undefined;
198        if (insertIndex < 0) insertIndex = undefined;
199
200        cb.addChild('WpstreamQualityMenuButton', {}, insertIndex);
201      } catch (e) {
202        // ignore
203      }
204    });
205  }
206
207  window.wpstreamInstallQualitySelector = install;
208})(window);
209

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.