preferred quality setting

This commit is contained in:
Simon
2026-06-17 15:44:20 +00:00
parent d73e413352
commit f8072884b2
7 changed files with 73 additions and 9 deletions

View File

@@ -428,7 +428,7 @@ App.videos = App.videos || {};
return 0;
};
App.videos.pickBestFormat = function(formats) {
App.videos.pickBestFormat = function(formats, preferredHeight) {
if (!Array.isArray(formats) || formats.length === 0) return null;
const candidates = formats.filter((fmt) => fmt && fmt.url);
if (!candidates.length) return null;
@@ -439,7 +439,7 @@ App.videos = App.videos || {};
if (vcodec && vcodec !== 'none') return true;
return false;
});
const pool = videoCandidates.length ? videoCandidates : candidates;
let pool = videoCandidates.length ? videoCandidates : candidates;
const score = (fmt) => {
const height = App.videos.coerceNumber(fmt.height || fmt.quality);
const width = App.videos.coerceNumber(fmt.width);
@@ -448,6 +448,22 @@ App.videos = App.videos || {};
const fps = App.videos.coerceNumber(fmt.fps);
return [size, bitrate, fps];
};
if (preferredHeight) {
const atOrBelow = pool.filter((fmt) => {
const size = score(fmt)[0];
return size > 0 && size <= preferredHeight;
});
if (atOrBelow.length) {
pool = atOrBelow;
} else {
// Nothing at or below the preferred quality, fall back to the lowest available.
const lowest = pool.reduce((min, fmt) => {
if (!min) return fmt;
return score(fmt)[0] < score(min)[0] ? fmt : min;
}, null);
return lowest;
}
}
return pool.reduce((best, fmt) => {
if (!best) return fmt;
const bestScore = score(best);
@@ -460,7 +476,8 @@ App.videos = App.videos || {};
}, null);
};
App.videos.resolveStreamSource = function(videoOrUrl) {
App.videos.resolveStreamSource = function(videoOrUrl, options) {
const applyPreferredQuality = !options || options.applyPreferredQuality !== false;
let sourceUrl = '';
let referer = '';
if (typeof videoOrUrl === 'string') {
@@ -468,7 +485,12 @@ App.videos = App.videos || {};
} else if (videoOrUrl && typeof videoOrUrl === 'object') {
const meta = videoOrUrl.meta || videoOrUrl;
sourceUrl = meta.url || videoOrUrl.url || '';
const best = App.videos.pickBestFormat(meta.formats);
let preferredHeight = null;
if (applyPreferredQuality) {
const preferredQuality = App.storage.getPreferredQuality();
preferredHeight = preferredQuality === 'auto' ? null : App.videos.coerceNumber(preferredQuality);
}
const best = App.videos.pickBestFormat(meta.formats, preferredHeight);
if (best && best.url) {
sourceUrl = best.url;
if (best.http_headers && (best.http_headers.Referer || best.http_headers.referer)) {
@@ -490,8 +512,8 @@ App.videos = App.videos || {};
};
// Builds a proxied stream URL with an optional referer parameter.
App.videos.buildStreamUrl = function(videoOrUrl) {
const resolved = App.videos.resolveStreamSource(videoOrUrl);
App.videos.buildStreamUrl = function(videoOrUrl, options) {
const resolved = App.videos.resolveStreamSource(videoOrUrl, options);
if (!resolved.url) return '';
const refererParam = resolved.referer ? `&referer=${encodeURIComponent(resolved.referer)}` : '';
return `/api/stream?url=${encodeURIComponent(resolved.url)}${refererParam}`;
@@ -499,7 +521,7 @@ App.videos = App.videos || {};
App.videos.downloadVideo = function(video) {
if (!video) return;
const streamUrl = App.videos.buildStreamUrl(video);
const streamUrl = App.videos.buildStreamUrl(video, { applyPreferredQuality: false });
if (!streamUrl) return;
const link = document.createElement('a');
link.href = streamUrl;