Fix CRT shader: pass streamOptions via PlaybackInfo body, not URL
Some checks failed
Push & Release 🌍 / Automation 🎛️ (push) Has been cancelled
Push & Release 🌍 / Unstable release 🚀⚠️ (push) Has been cancelled
Push & Release 🌍 / Quality checks 👌🧪 (push) Has been cancelled
Push & Release 🌍 / GitHub CodeQL 🔬 (push) Has been cancelled
Push & Release 🌍 / Deploy 🚀 (push) Has been cancelled

The previous approach of appending streamOptions[crtShader]=true to
the transcoding URL didn't work — the server only reads StreamOptions
from the PlaybackInfo request body (PlaybackInfoDto), not from the
streaming endpoint URL query string.

Pass streamOptions as part of the getPlaybackInfo query so the server
embeds them in the TranscodingUrl. Also propagate crtShadowMask the
same way. Remove the broken URL-appending code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mani
2026-02-25 21:36:59 +01:00
parent de2a29621d
commit d14f15a2f8

View File

@@ -470,6 +470,9 @@ async function getPlaybackInfo(player, apiClient, item, deviceProfile, mediaSour
if (options.allowAudioStreamCopy != null) {
query.AllowAudioStreamCopy = options.allowAudioStreamCopy;
}
if (options.streamOptions) {
query.StreamOptions = options.streamOptions;
}
if (mediaSourceId) {
query.MediaSourceId = mediaSourceId;
}
@@ -1747,6 +1750,14 @@ export class PlaybackManager {
const currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions();
const crtStreamOptions = (function () {
const pd = getPlayerData(player);
if (!pd.enableCrtShader) return undefined;
const opts = { crtShader: 'true' };
if (pd.crtShadowMask != null) opts.crtShadowMask = String(pd.crtShadowMask);
return opts;
})();
const options = {
maxBitrate,
startPosition: ticks,
@@ -1756,7 +1767,8 @@ export class PlaybackManager {
enableDirectPlay: params.EnableDirectPlay,
enableDirectStream: params.EnableDirectStream,
allowVideoStreamCopy: params.AllowVideoStreamCopy,
allowAudioStreamCopy: params.AllowAudioStreamCopy
allowAudioStreamCopy: params.AllowAudioStreamCopy,
streamOptions: crtStreamOptions
};
getPlaybackInfo(player, apiClient, currentItem, deviceProfile, currentMediaSource.Id, liveStreamId, options).then(function (result) {
@@ -2878,17 +2890,7 @@ export class PlaybackManager {
playMethod = mediaSource.SupportsDirectPlay ? 'DirectPlay' : 'DirectStream';
} else if (mediaSource.SupportsTranscoding) {
let transcodingUrl = mediaSource.TranscodingUrl;
// Append CRT-Lottes shader option when enabled for this session.
if (getPlayerData(player).enableCrtShader) {
const sep = transcodingUrl.includes('?') ? '&' : '?';
transcodingUrl += sep + 'streamOptions%5BcrtShader%5D=true';
const maskVal = getPlayerData(player).crtShadowMask;
if (maskVal !== undefined && maskVal !== null) {
transcodingUrl += '&streamOptions%5BcrtShadowMask%5D=' + maskVal;
}
}
const transcodingUrl = mediaSource.TranscodingUrl;
mediaUrl = apiClient.getUrl(transcodingUrl);