Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions lib/screens/settings/playback_settings_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ class PlaybackSettingsScreen extends StatelessWidget {
builder: (context) {
final svc = SettingsService.instance;
final exoActive = Platform.isAndroid && svc.read(SettingsService.useExoPlayer);
final downmixOn = svc.read(SettingsService.audioDownmix);
// Tizen drives the native Capi backend, so every mpv-only tuning tile
// below points at a property that platform cannot accept.
final mpvTuning = PlatformDetector.supportsMpvTuning();
final downmixOn = mpvTuning && svc.read(SettingsService.audioDownmix);
final showDisplaySwitchDelay =
PlatformDetector.isAppleTV() ||
(Platform.isWindows &&
Expand All @@ -57,8 +60,8 @@ class PlaybackSettingsScreen extends StatelessWidget {
children: [
if (Platform.isAndroid) _playerBackendSelector(),
if (PlatformDetector.supportsExternalPlayers()) _externalPlayerTile(),
if (!exoActive) _mpvConfigTile(),
_hardwareDecodingTile(),
if (!exoActive && mpvTuning) _mpvConfigTile(),
if (mpvTuning) _hardwareDecodingTile(),
if (exoActive) _playbackBufferTile(),
if (exoActive) _tunneledPlaybackTile(),
if (PlatformDetector.supportsPictureInPicture()) _autoPipTile(),
Expand All @@ -76,7 +79,7 @@ class PlaybackSettingsScreen extends StatelessWidget {
if (Platform.isAndroid) _dvConversionModeTile(),
// mpv-only (#2149): ExoPlayer has no filter chain, so the
// tile disappears while the ExoPlayer backend is active.
if (!exoActive) _deinterlaceTile(),
if (!exoActive && mpvTuning) _deinterlaceTile(),
// TODO: "Extend video into display cutout" toggle (#1769)
// goes here, Android-only.
],
Expand All @@ -86,10 +89,10 @@ class PlaybackSettingsScreen extends StatelessWidget {
title: t.settings.audio,
children: [
if (PlatformDetector.supportsAudioPassthrough()) _audioPassthroughTile(),
_audioDownmixTile(),
if (mpvTuning) _audioDownmixTile(),
if (downmixOn) _downmixCenterBoostTile(),
if (downmixOn) _downmixNormalizeTile(),
_maxVolumeTile(),
if (mpvTuning) _maxVolumeTile(),
],
),

Expand Down
11 changes: 11 additions & 0 deletions lib/utils/platform_detector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,17 @@ class PlatformDetector {
static bool supportsGamepads() => !_tizen;
static bool supportsSystemMediaControls() => !_tizen;

/// Whether the mpv-backed playback tuning settings mean anything here.
///
/// Tizen plays through the native Capi backend, and `PlayerTizen.setProperty`
/// rejects every mpv option but `pause` and `sub-visibility`. The settings
/// that exist only to reach mpv — the `mpv.conf` editor, `hwdec`, the
/// deinterlace and downmix filters and `volume-max` — have nothing to act on:
/// `VideoPlayerScreen` already skips the whole property-writing block there,
/// so the screen settings are inert, and the in-player toggles fail their
/// write and snap back.
static bool supportsMpvTuning() => !_tizen;

static bool isAppleTV() {
return TvDetectionService.isAppleTVSync();
}
Expand Down
53 changes: 29 additions & 24 deletions lib/widgets/video_controls/sheets/video_settings_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -839,32 +839,37 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
// "not Dolby" when the system reports notApplicable.
if (PlatformDetector.isAppleTV()) _AudioRenderingModeItem(player: widget.player),

_SettingsToggleItem(
pref: SettingsService.audioNormalization,
icon: Symbols.graphic_eq_rounded,
title: t.videoSettings.audioNormalization,
// Normalization wins over passthrough; say so where passthrough
// exists. Android also folds the track to stereo ahead of loudnorm
// (PlayerBase._loudnormFilter), which a surround owner must hear
// about before flipping it.
subtitle: PlatformDetector.supportsAudioPassthrough()
? Platform.isAndroid
? t.videoSettings.audioNormalizationStereoMix
: t.videoSettings.audioNormalizationDisablesPassthrough
: null,
onAfterWrite: widget.player.setAudioNormalization,
),
// Both audio filters go through mpv's `af`/swresample options, which
// PlayerTizen rejects: the write throws, is logged, and the switch
// snaps back. Do not offer a control that cannot hold its value.
if (PlatformDetector.supportsMpvTuning()) ...[
_SettingsToggleItem(
pref: SettingsService.audioNormalization,
icon: Symbols.graphic_eq_rounded,
title: t.videoSettings.audioNormalization,
// Normalization wins over passthrough; say so where passthrough
// exists. Android also folds the track to stereo ahead of loudnorm
// (PlayerBase._loudnormFilter), which a surround owner must hear
// about before flipping it.
subtitle: PlatformDetector.supportsAudioPassthrough()
? Platform.isAndroid
? t.videoSettings.audioNormalizationStereoMix
: t.videoSettings.audioNormalizationDisablesPassthrough
: null,
onAfterWrite: widget.player.setAudioNormalization,
),

_SettingsToggleItem(
pref: SettingsService.audioDownmix,
icon: Symbols.headphones_rounded,
title: t.videoSettings.audioDownmix,
onAfterWrite: (enabled) => widget.player.setAudioDownmix(
enabled: enabled,
centerBoostDb: SettingsService.instance.read(SettingsService.downmixCenterBoost),
normalize: SettingsService.instance.read(SettingsService.audioDownmixNormalize),
_SettingsToggleItem(
pref: SettingsService.audioDownmix,
icon: Symbols.headphones_rounded,
title: t.videoSettings.audioDownmix,
onAfterWrite: (enabled) => widget.player.setAudioDownmix(
enabled: enabled,
centerBoostDb: SettingsService.instance.read(SettingsService.downmixCenterBoost),
normalize: SettingsService.instance.read(SettingsService.audioDownmixNormalize),
),
),
),
],

// Shader Preset (MPV only)
if (_state.shaderService != null && _state.shaderService!.isSupported)
Expand Down
13 changes: 13 additions & 0 deletions test/tizen/platform_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,17 @@ void main() {
expect(PlatformDetector.supportsExternalPlayers(), isFalse);
expect(PlatformDetector.supportsAudioPassthrough(), isFalse);
});

test('Tizen offers no mpv tuning settings', () {
// PlayerTizen.setProperty rejects every mpv option, so the mpv.conf
// editor, hwdec, deinterlace, the downmix filters and volume-max all
// point at something that cannot accept them.
if (!const bool.fromEnvironment('TIZEN_BUILD')) return;
expect(PlatformDetector.supportsMpvTuning(), isFalse);
});

test('a non-Tizen build keeps its mpv tuning settings', () {
if (const bool.fromEnvironment('TIZEN_BUILD')) return;
expect(PlatformDetector.supportsMpvTuning(), isTrue);
});
}