Merge pull request #1027 from friday/quality
Minor code improvements for quality switching
This commit is contained in:
commit
0b09b8ee6f
6
src/js/controls.js
vendored
6
src/js/controls.js
vendored
@ -632,7 +632,6 @@ const controls = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Set the quality menu
|
// Set the quality menu
|
||||||
// TODO: Vimeo support
|
|
||||||
setQualityMenu(options) {
|
setQualityMenu(options) {
|
||||||
// Menu required
|
// Menu required
|
||||||
if (!utils.is.element(this.elements.settings.panes.quality)) {
|
if (!utils.is.element(this.elements.settings.panes.quality)) {
|
||||||
@ -642,9 +641,10 @@ const controls = {
|
|||||||
const type = 'quality';
|
const type = 'quality';
|
||||||
const list = this.elements.settings.panes.quality.querySelector('ul');
|
const list = this.elements.settings.panes.quality.querySelector('ul');
|
||||||
|
|
||||||
// Set options if passed and filter based on config
|
// Set options if passed and filter based on uniqueness and config
|
||||||
if (utils.is.array(options)) {
|
if (utils.is.array(options)) {
|
||||||
this.options.quality = options.filter(quality => this.config.quality.options.includes(quality));
|
this.options.quality = utils.dedupe(options)
|
||||||
|
.filter(quality => this.config.quality.options.includes(quality));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
|
@ -8,35 +8,21 @@ import utils from './utils';
|
|||||||
const html5 = {
|
const html5 = {
|
||||||
getSources() {
|
getSources() {
|
||||||
if (!this.isHTML5) {
|
if (!this.isHTML5) {
|
||||||
return null;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.media.querySelectorAll('source');
|
const sources = Array.from(this.media.querySelectorAll('source'));
|
||||||
|
|
||||||
|
// Filter out unsupported sources
|
||||||
|
return sources.filter(source => support.mime.call(this, source.getAttribute('type')));
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get quality levels
|
// Get quality levels
|
||||||
getQualityOptions() {
|
getQualityOptions() {
|
||||||
if (!this.isHTML5) {
|
// Get sizes from <source> elements
|
||||||
return null;
|
return html5.getSources.call(this)
|
||||||
}
|
.map(source => Number(source.getAttribute('size')))
|
||||||
|
.filter(Boolean);
|
||||||
// Get sources
|
|
||||||
const sources = html5.getSources.call(this);
|
|
||||||
|
|
||||||
if (utils.is.empty(sources)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get <source> with size attribute
|
|
||||||
const sizes = Array.from(sources).filter(source => !utils.is.empty(source.getAttribute('size')));
|
|
||||||
|
|
||||||
// If none, bail
|
|
||||||
if (utils.is.empty(sizes)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reduce to unique list
|
|
||||||
return utils.dedupe(sizes.map(source => Number(source.getAttribute('size'))));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
extend() {
|
extend() {
|
||||||
@ -51,53 +37,28 @@ const html5 = {
|
|||||||
get() {
|
get() {
|
||||||
// Get sources
|
// Get sources
|
||||||
const sources = html5.getSources.call(player);
|
const sources = html5.getSources.call(player);
|
||||||
|
const [source] = sources.filter(source => source.getAttribute('src') === player.source);
|
||||||
|
|
||||||
if (utils.is.empty(sources)) {
|
// Return size, if match is found
|
||||||
return null;
|
return source && Number(source.getAttribute('size'));
|
||||||
}
|
|
||||||
|
|
||||||
const matches = Array.from(sources).filter(source => source.getAttribute('src') === player.source);
|
|
||||||
|
|
||||||
if (utils.is.empty(matches)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Number(matches[0].getAttribute('size'));
|
|
||||||
},
|
},
|
||||||
set(input) {
|
set(input) {
|
||||||
// Get sources
|
// Get sources
|
||||||
const sources = html5.getSources.call(player);
|
const sources = html5.getSources.call(player);
|
||||||
|
|
||||||
if (utils.is.empty(sources)) {
|
// Get first match for requested size
|
||||||
|
const source = sources.find(source => Number(source.getAttribute('size')) === input);
|
||||||
|
|
||||||
|
// No matching source found
|
||||||
|
if (!source) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get matches for requested size
|
|
||||||
const matches = Array.from(sources).filter(source => Number(source.getAttribute('size')) === input);
|
|
||||||
|
|
||||||
// No matches for requested size
|
|
||||||
if (utils.is.empty(matches)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get supported sources
|
|
||||||
const supported = matches.filter(source => support.mime.call(player, source.getAttribute('type')));
|
|
||||||
|
|
||||||
// No supported sources
|
|
||||||
if (utils.is.empty(supported)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger change event
|
|
||||||
utils.dispatchEvent.call(player, player.media, 'qualityrequested', false, {
|
|
||||||
quality: input,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get current state
|
// Get current state
|
||||||
const { currentTime, playing } = player;
|
const { currentTime, playing } = player;
|
||||||
|
|
||||||
// Set new source
|
// Set new source
|
||||||
player.media.src = supported[0].getAttribute('src');
|
player.media.src = source.getAttribute('src');
|
||||||
|
|
||||||
// Restore time
|
// Restore time
|
||||||
const onLoadedMetaData = () => {
|
const onLoadedMetaData = () => {
|
||||||
|
@ -8,52 +8,26 @@ import utils from './../utils';
|
|||||||
|
|
||||||
// Standardise YouTube quality unit
|
// Standardise YouTube quality unit
|
||||||
function mapQualityUnit(input) {
|
function mapQualityUnit(input) {
|
||||||
switch (input) {
|
const qualities = {
|
||||||
case 'hd2160':
|
hd2160: 2160,
|
||||||
return 2160;
|
hd1440: 1440,
|
||||||
|
hd1080: 1080,
|
||||||
|
hd720: 720,
|
||||||
|
large: 480,
|
||||||
|
medium: 360,
|
||||||
|
small: 240,
|
||||||
|
tiny: 144,
|
||||||
|
};
|
||||||
|
|
||||||
case 2160:
|
const entry = Object.entries(qualities)
|
||||||
return 'hd2160';
|
.find(entry => entry.includes(input));
|
||||||
|
|
||||||
case 'hd1440':
|
if (entry) {
|
||||||
return 1440;
|
// Get the match corresponding to the input
|
||||||
|
return entry.find(value => value !== input);
|
||||||
case 1440:
|
|
||||||
return 'hd1440';
|
|
||||||
|
|
||||||
case 'hd1080':
|
|
||||||
return 1080;
|
|
||||||
|
|
||||||
case 1080:
|
|
||||||
return 'hd1080';
|
|
||||||
|
|
||||||
case 'hd720':
|
|
||||||
return 720;
|
|
||||||
|
|
||||||
case 720:
|
|
||||||
return 'hd720';
|
|
||||||
|
|
||||||
case 'large':
|
|
||||||
return 480;
|
|
||||||
|
|
||||||
case 480:
|
|
||||||
return 'large';
|
|
||||||
|
|
||||||
case 'medium':
|
|
||||||
return 360;
|
|
||||||
|
|
||||||
case 360:
|
|
||||||
return 'medium';
|
|
||||||
|
|
||||||
case 'small':
|
|
||||||
return 240;
|
|
||||||
|
|
||||||
case 240:
|
|
||||||
return 'small';
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 'default';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapQualityUnits(levels) {
|
function mapQualityUnits(levels) {
|
||||||
@ -328,15 +302,7 @@ const youtube = {
|
|||||||
return mapQualityUnit(instance.getPlaybackQuality());
|
return mapQualityUnit(instance.getPlaybackQuality());
|
||||||
},
|
},
|
||||||
set(input) {
|
set(input) {
|
||||||
const quality = input;
|
instance.setPlaybackQuality(mapQualityUnit(input));
|
||||||
|
|
||||||
// Set via API
|
|
||||||
instance.setPlaybackQuality(mapQualityUnit(quality));
|
|
||||||
|
|
||||||
// Trigger request event
|
|
||||||
utils.dispatchEvent.call(player, player.media, 'qualityrequested', false, {
|
|
||||||
quality,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -669,36 +669,31 @@ class Plyr {
|
|||||||
* @param {number} input - Quality level
|
* @param {number} input - Quality level
|
||||||
*/
|
*/
|
||||||
set quality(input) {
|
set quality(input) {
|
||||||
let quality = null;
|
const config = this.config.quality;
|
||||||
|
const options = this.options.quality;
|
||||||
|
|
||||||
if (!utils.is.empty(input)) {
|
if (!options.length) {
|
||||||
quality = Number(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!utils.is.number(quality)) {
|
|
||||||
quality = this.storage.get('quality');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!utils.is.number(quality)) {
|
|
||||||
quality = this.config.quality.selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!utils.is.number(quality)) {
|
|
||||||
quality = this.config.quality.default;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.options.quality.length) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.options.quality.includes(quality)) {
|
let quality = ([
|
||||||
const closest = utils.closest(this.options.quality, quality);
|
!utils.is.empty(input) && Number(input),
|
||||||
|
this.storage.get('quality'),
|
||||||
|
config.selected,
|
||||||
|
config.default,
|
||||||
|
]).find(utils.is.number);
|
||||||
|
|
||||||
|
if (!options.includes(quality)) {
|
||||||
|
const closest = utils.closest(options, quality);
|
||||||
this.debug.warn(`Unsupported quality option: ${quality}, using ${closest} instead`);
|
this.debug.warn(`Unsupported quality option: ${quality}, using ${closest} instead`);
|
||||||
quality = closest;
|
quality = closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trigger request event
|
||||||
|
utils.dispatchEvent.call(this, this.media, 'qualityrequested', false, { quality });
|
||||||
|
|
||||||
// Update config
|
// Update config
|
||||||
this.config.quality.selected = quality;
|
config.selected = quality;
|
||||||
|
|
||||||
// Set quality
|
// Set quality
|
||||||
this.media.quality = quality;
|
this.media.quality = quality;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user