Compare commits
5 Commits
release-10
...
feature/cr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dd1de3d9c | ||
|
|
d14f15a2f8 | ||
|
|
de2a29621d | ||
|
|
f6fce9eae8 | ||
|
|
0b4b125519 |
@@ -1422,6 +1422,28 @@ export class PlaybackManager {
|
||||
});
|
||||
};
|
||||
|
||||
self.isCrtShaderEnabled = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
return !!(getPlayerData(player).enableCrtShader);
|
||||
};
|
||||
|
||||
self.setCrtShader = function (enabled, shadowMask, player) {
|
||||
player = player || self._currentPlayer;
|
||||
const pd = getPlayerData(player);
|
||||
pd.enableCrtShader = !!enabled;
|
||||
if (shadowMask !== undefined && shadowMask !== null) {
|
||||
pd.crtShadowMask = shadowMask;
|
||||
}
|
||||
// When enabling CRT we must force full re-encode — the filter only runs
|
||||
// server-side via program_opencl and requires actual video decoding/encoding.
|
||||
// AllowVideoStreamCopy:false prevents the server from choosing codec:copy
|
||||
// (container remux), which would bypass the filter chain entirely.
|
||||
const streamParams = enabled
|
||||
? { EnableDirectPlay: false, EnableDirectStream: false, AllowVideoStreamCopy: false }
|
||||
: {};
|
||||
changeStream(player, getCurrentTicks(player), streamParams);
|
||||
};
|
||||
|
||||
self.isFullscreen = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (!player.isLocalPlayer || player.isFullscreen) {
|
||||
@@ -2856,7 +2878,19 @@ export class PlaybackManager {
|
||||
|
||||
playMethod = mediaSource.SupportsDirectPlay ? 'DirectPlay' : 'DirectStream';
|
||||
} else if (mediaSource.SupportsTranscoding) {
|
||||
mediaUrl = apiClient.getUrl(mediaSource.TranscodingUrl);
|
||||
let transcodingUrl = mediaSource.TranscodingUrl;
|
||||
|
||||
// Append CRT shader options as plain query params so ParseStreamOptions
|
||||
// on the server picks them up (key must start lowercase, no streamOptions[] wrapper).
|
||||
if (getPlayerData(player).enableCrtShader) {
|
||||
transcodingUrl += '&crtShader=true';
|
||||
const maskVal = getPlayerData(player).crtShadowMask;
|
||||
if (maskVal !== undefined && maskVal !== null) {
|
||||
transcodingUrl += '&crtShadowMask=' + maskVal;
|
||||
}
|
||||
}
|
||||
|
||||
mediaUrl = apiClient.getUrl(transcodingUrl);
|
||||
|
||||
if (mediaSource.TranscodingSubProtocol === 'hls') {
|
||||
contentType = 'application/x-mpegURL';
|
||||
|
||||
@@ -4,6 +4,34 @@ import globalize from 'lib/globalize';
|
||||
import { ServerConnections } from 'lib/jellyfin-apiclient';
|
||||
import qualityoptions from '../qualityOptions';
|
||||
|
||||
function showCrtMenu(player, btn) {
|
||||
const isEnabled = playbackManager.isCrtShaderEnabled(player);
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
name: globalize.translate('On'),
|
||||
id: 'crt_on',
|
||||
selected: isEnabled
|
||||
},
|
||||
{
|
||||
name: globalize.translate('Off'),
|
||||
id: 'crt_off',
|
||||
selected: !isEnabled
|
||||
}
|
||||
];
|
||||
|
||||
return actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
}).then(function (id) {
|
||||
if (id === 'crt_on' && !isEnabled) {
|
||||
playbackManager.setCrtShader(true, null, player);
|
||||
} else if (id === 'crt_off' && isEnabled) {
|
||||
playbackManager.setCrtShader(false, null, player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showQualityMenu(player, btn) {
|
||||
const videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
|
||||
return stream.Type === 'Video';
|
||||
@@ -214,6 +242,16 @@ function showWithUser(options, player, user) {
|
||||
});
|
||||
}
|
||||
|
||||
if (options.quality && user?.Policy?.EnableVideoPlaybackTranscoding) {
|
||||
menuItems.push({
|
||||
name: 'CRT Shader',
|
||||
id: 'crtshader',
|
||||
asideText: playbackManager.isCrtShaderEnabled(player)
|
||||
? globalize.translate('On')
|
||||
: globalize.translate('Off')
|
||||
});
|
||||
}
|
||||
|
||||
const repeatMode = playbackManager.getRepeatMode(player);
|
||||
|
||||
if (supportedCommands.indexOf('SetRepeatMode') !== -1 && playbackManager.currentMediaSource(player).RunTimeTicks) {
|
||||
@@ -272,6 +310,8 @@ function handleSelectedOption(id, options, player) {
|
||||
return showPlaybackRateMenu(player, options.positionTo);
|
||||
case 'repeatmode':
|
||||
return showRepeatModeMenu(player, options.positionTo);
|
||||
case 'crtshader':
|
||||
return showCrtMenu(player, options.positionTo);
|
||||
case 'stats':
|
||||
if (options.onOption) {
|
||||
options.onOption('stats');
|
||||
|
||||
Reference in New Issue
Block a user