feat: add "Prevent resolution drops" setting (#791)

This commit is contained in:
redphx
2025-09-22 20:14:35 +07:00
parent 2260304313
commit a1a8a3a80e
7 changed files with 45 additions and 23 deletions

View File

@@ -68,6 +68,7 @@ var ALL_PREFS = {
"stream.video.maxBitrate", "stream.video.maxBitrate",
"stream.locale", "stream.locale",
"stream.video.resolution", "stream.video.resolution",
"stream.video.preventResolutionDrops",
"touchController.autoOff", "touchController.autoOff",
"touchController.opacity.default", "touchController.opacity.default",
"touchController.mode", "touchController.mode",
@@ -640,6 +641,7 @@ var SUPPORTED_LANGUAGES = {
e => `按下 ${e.key} 來啟用此功能` e => `按下 ${e.key} 來啟用此功能`
], ],
"press-to-bind": "Press a key or do a mouse click to bind...", "press-to-bind": "Press a key or do a mouse click to bind...",
"prevent-resolution-drops": "Prevent resolution drops",
"prompt-preset-name": "Preset's name:", "prompt-preset-name": "Preset's name:",
quality: "Quality", quality: "Quality",
recommended: "Recommended", recommended: "Recommended",
@@ -1375,6 +1377,11 @@ class GlobalSettingsStorage extends BaseSettingsStorage {
highest: "1080p-hq" highest: "1080p-hq"
} }
}, },
"stream.video.preventResolutionDrops": {
label: t("prevent-resolution-drops"),
default: !1,
note: CE("a", { href: "https://github.com/redphx/better-xcloud/issues/791", target: "_blank" }, "⚠️ " + t("unexpected-behavior"))
},
"stream.video.codecProfile": { "stream.video.codecProfile": {
label: t("visual-quality"), label: t("visual-quality"),
default: "default", default: "default",
@@ -5739,15 +5746,17 @@ ${subsVar} = subs;
patchStreamMetadata(str) { patchStreamMetadata(str) {
let index = str.indexOf("}onVideoFrame("); let index = str.indexOf("}onVideoFrame(");
if (index >= 0 && (index = PatcherUtils.indexOf(str, "){", index, 30, !0)), index < 0) return !1; if (index >= 0 && (index = PatcherUtils.indexOf(str, "){", index, 30, !0)), index < 0) return !1;
let code = ` let maxDt = 10, code = `
try { try {
const obj = arguments[0]; const obj = arguments[0];
const baseMs = obj.frameSubmittedTimeMs; if (true || obj.frameDecodedTimeMs - obj.frameSubmittedTimeMs > ${maxDt}) {
const renderMs = obj.frameRenderedTimeMs - obj.frameDecodedTimeMs; const baseMs = obj.frameSubmittedTimeMs;
obj.frameDecodedTimeMs = baseMs + ${1}; const renderMs = obj.frameRenderedTimeMs - obj.frameDecodedTimeMs;
obj.frameRenderedTimeMs = obj.frameDecodedTimeMs + renderMs; obj.frameDecodedTimeMs = baseMs + ${maxDt};
obj.expectedDisplayTime = obj.frameRenderedTimeMs; obj.frameRenderedTimeMs = obj.frameDecodedTimeMs + renderMs;
arguments[0] = obj; obj.expectedDisplayTime = obj.frameRenderedTimeMs;
arguments[0] = obj;
}
} catch (e) { alert(e) } } catch (e) { alert(e) }
`; `;
return str = PatcherUtils.insertAt(str, index, code), str; return str = PatcherUtils.insertAt(str, index, code), str;
@@ -5826,7 +5835,7 @@ try {
"playVibration", "playVibration",
"alwaysShowStreamHud", "alwaysShowStreamHud",
"injectStreamMenuUseEffect", "injectStreamMenuUseEffect",
"patchStreamMetadata", getGlobalPref("stream.video.preventResolutionDrops") && "patchStreamMetadata",
getGlobalPref("audio.volume.booster.enabled") && !getGlobalPref("stream.video.combineAudio") && "patchAudioMediaStream", getGlobalPref("audio.volume.booster.enabled") && !getGlobalPref("stream.video.combineAudio") && "patchAudioMediaStream",
getGlobalPref("audio.volume.booster.enabled") && getGlobalPref("stream.video.combineAudio") && "patchCombinedAudioVideoMediaStream", getGlobalPref("audio.volume.booster.enabled") && getGlobalPref("stream.video.combineAudio") && "patchCombinedAudioVideoMediaStream",
getGlobalPref("ui.feedbackDialog.disabled") && "skipFeedbackDialog", getGlobalPref("ui.feedbackDialog.disabled") && "skipFeedbackDialog",
@@ -7280,6 +7289,7 @@ class SettingsDialog extends NavigationDialog {
"stream.video.resolution", "stream.video.resolution",
"stream.video.codecProfile", "stream.video.codecProfile",
"stream.video.maxBitrate", "stream.video.maxBitrate",
"stream.video.preventResolutionDrops",
"audio.volume.booster.enabled", "audio.volume.booster.enabled",
"screenshot.applyFilters", "screenshot.applyFilters",
"audio.mic.onPlaying", "audio.mic.onPlaying",

File diff suppressed because one or more lines are too long

View File

@@ -34,6 +34,7 @@ export const enum GlobalPref {
STREAM_CODEC_PROFILE = 'stream.video.codecProfile', STREAM_CODEC_PROFILE = 'stream.video.codecProfile',
STREAM_MAX_VIDEO_BITRATE = 'stream.video.maxBitrate', STREAM_MAX_VIDEO_BITRATE = 'stream.video.maxBitrate',
STREAM_COMBINE_SOURCES = 'stream.video.combineAudio', STREAM_COMBINE_SOURCES = 'stream.video.combineAudio',
STREAM_PREVENT_RESOLUTION_DROPS = 'stream.video.preventResolutionDrops',
USER_AGENT_PROFILE = 'userAgent.profile', USER_AGENT_PROFILE = 'userAgent.profile',
@@ -110,6 +111,7 @@ export type GlobalPrefTypeMap = {
[GlobalPref.STREAM_MAX_VIDEO_BITRATE]: number; [GlobalPref.STREAM_MAX_VIDEO_BITRATE]: number;
[GlobalPref.STREAM_PREFERRED_LOCALE]: StreamPreferredLocale; [GlobalPref.STREAM_PREFERRED_LOCALE]: StreamPreferredLocale;
[GlobalPref.STREAM_RESOLUTION]: StreamResolution; [GlobalPref.STREAM_RESOLUTION]: StreamResolution;
[GlobalPref.STREAM_PREVENT_RESOLUTION_DROPS]: boolean;
[GlobalPref.TOUCH_CONTROLLER_AUTO_OFF]: boolean; [GlobalPref.TOUCH_CONTROLLER_AUTO_OFF]: boolean;
[GlobalPref.TOUCH_CONTROLLER_DEFAULT_OPACITY]: number; [GlobalPref.TOUCH_CONTROLLER_DEFAULT_OPACITY]: number;
[GlobalPref.TOUCH_CONTROLLER_MODE]: TouchControllerMode; [GlobalPref.TOUCH_CONTROLLER_MODE]: TouchControllerMode;
@@ -245,6 +247,7 @@ export const ALL_PREFS: {
GlobalPref.STREAM_MAX_VIDEO_BITRATE, GlobalPref.STREAM_MAX_VIDEO_BITRATE,
GlobalPref.STREAM_PREFERRED_LOCALE, GlobalPref.STREAM_PREFERRED_LOCALE,
GlobalPref.STREAM_RESOLUTION, GlobalPref.STREAM_RESOLUTION,
GlobalPref.STREAM_PREVENT_RESOLUTION_DROPS,
GlobalPref.TOUCH_CONTROLLER_AUTO_OFF, GlobalPref.TOUCH_CONTROLLER_AUTO_OFF,
GlobalPref.TOUCH_CONTROLLER_DEFAULT_OPACITY, GlobalPref.TOUCH_CONTROLLER_DEFAULT_OPACITY,
GlobalPref.TOUCH_CONTROLLER_MODE, GlobalPref.TOUCH_CONTROLLER_MODE,

View File

@@ -1248,16 +1248,18 @@ ${subsVar} = subs;
return false; return false;
} }
const fakeDtMs = 1; const maxDt = 10;
const code = ` const code = `
try { try {
const obj = arguments[0]; const obj = arguments[0];
const baseMs = obj.frameSubmittedTimeMs; if (true || obj.frameDecodedTimeMs - obj.frameSubmittedTimeMs > ${maxDt}) {
const renderMs = obj.frameRenderedTimeMs - obj.frameDecodedTimeMs; const baseMs = obj.frameSubmittedTimeMs;
obj.frameDecodedTimeMs = baseMs + ${fakeDtMs}; const renderMs = obj.frameRenderedTimeMs - obj.frameDecodedTimeMs;
obj.frameRenderedTimeMs = obj.frameDecodedTimeMs + renderMs; obj.frameDecodedTimeMs = baseMs + ${maxDt};
obj.expectedDisplayTime = obj.frameRenderedTimeMs; obj.frameRenderedTimeMs = obj.frameDecodedTimeMs + renderMs;
arguments[0] = obj; obj.expectedDisplayTime = obj.frameRenderedTimeMs;
arguments[0] = obj;
}
} catch (e) { alert(e) } } catch (e) { alert(e) }
`; `;
str = PatcherUtils.insertAt(str, index, code); str = PatcherUtils.insertAt(str, index, code);
@@ -1409,7 +1411,7 @@ let STREAM_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches([
'injectStreamMenuUseEffect', 'injectStreamMenuUseEffect',
'patchStreamMetadata', getGlobalPref(GlobalPref.STREAM_PREVENT_RESOLUTION_DROPS) && 'patchStreamMetadata',
// 'exposeEventTarget', // 'exposeEventTarget',

View File

@@ -213,6 +213,7 @@ export class SettingsDialog extends NavigationDialog {
GlobalPref.STREAM_RESOLUTION, GlobalPref.STREAM_RESOLUTION,
GlobalPref.STREAM_CODEC_PROFILE, GlobalPref.STREAM_CODEC_PROFILE,
GlobalPref.STREAM_MAX_VIDEO_BITRATE, GlobalPref.STREAM_MAX_VIDEO_BITRATE,
GlobalPref.STREAM_PREVENT_RESOLUTION_DROPS,
GlobalPref.AUDIO_VOLUME_CONTROL_ENABLED, GlobalPref.AUDIO_VOLUME_CONTROL_ENABLED,

View File

@@ -151,6 +151,11 @@ export class GlobalSettingsStorage extends BaseSettingsStorage<GlobalPref> {
highest: StreamResolution.DIM_1080P_HQ, highest: StreamResolution.DIM_1080P_HQ,
}, },
}, },
[GlobalPref.STREAM_PREVENT_RESOLUTION_DROPS]: {
label: t('prevent-resolution-drops'),
default: false,
note: CE('a', { href: 'https://github.com/redphx/better-xcloud/issues/791', target: '_blank' }, '⚠️ ' + t('unexpected-behavior')),
},
[GlobalPref.STREAM_CODEC_PROFILE]: { [GlobalPref.STREAM_CODEC_PROFILE]: {
label: t('visual-quality'), label: t('visual-quality'),

View File

@@ -265,6 +265,7 @@ const Texts = {
(e: any) => `按下 ${e.key} 來啟用此功能`, (e: any) => `按下 ${e.key} 來啟用此功能`,
], ],
"press-to-bind": "Press a key or do a mouse click to bind...", "press-to-bind": "Press a key or do a mouse click to bind...",
"prevent-resolution-drops": "Prevent resolution drops",
"prompt-preset-name": "Preset's name:", "prompt-preset-name": "Preset's name:",
"quality": "Quality", "quality": "Quality",
"recommended": "Recommended", "recommended": "Recommended",