fix(player): preserve volume when toggling mute (#1532)
* fix(player): preserve volume when toggling mute Muting now keeps the last volume level memorized. Unmuting restores that level, including amplified values allowed by the configured maximum. * fix(player): preserve volume for companion remote mute Route the companion remote through the shared mute transition so it no longer overwrites the persisted volume or restores to 100%. Also correct the Dartdoc formatting for the transition record fields.
This commit is contained in:
@@ -39,9 +39,9 @@ extension _VideoPlayerCompanionRemoteMethods on VideoPlayerScreenState {
|
||||
receiver.onVolumeMute = () async {
|
||||
if (player == null) return;
|
||||
final settings = await SettingsService.getInstance();
|
||||
final newVolume = player!.state.volume > 0 ? 0.0 : 100.0;
|
||||
unawaited(player!.setVolume(newVolume));
|
||||
unawaited(settings.write(SettingsService.volume, newVolume));
|
||||
final transition = settings.resolveMuteToggle(player!.state.volume);
|
||||
unawaited(player!.setVolume(transition.playerVolume));
|
||||
unawaited(settings.write(SettingsService.volume, transition.persistedVolume));
|
||||
};
|
||||
receiver.onSubtitles = _cycleSubtitleTrack;
|
||||
receiver.onAudioTracks = _cycleAudioTrack;
|
||||
|
||||
@@ -344,9 +344,9 @@ class KeyboardShortcutsService extends ChangeNotifier {
|
||||
onToggleFullscreen?.call();
|
||||
break;
|
||||
case 'mute_toggle':
|
||||
final newVolume = player.state.volume > 0 ? 0.0 : 100.0;
|
||||
player.setVolume(newVolume);
|
||||
_settingsService.write(SettingsService.volume, newVolume);
|
||||
final transition = _settingsService.resolveMuteToggle(player.state.volume);
|
||||
player.setVolume(transition.playerVolume);
|
||||
_settingsService.write(SettingsService.volume, transition.persistedVolume);
|
||||
break;
|
||||
case 'subtitle_toggle':
|
||||
onToggleSubtitles?.call();
|
||||
|
||||
@@ -614,6 +614,21 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
_cachedInstance = null;
|
||||
}
|
||||
|
||||
/// Resolves a video mute toggle without replacing the saved volume with 0.
|
||||
///
|
||||
/// `persistedVolume` is the non-zero value callers should keep in [volume],
|
||||
/// while `playerVolume` is the value to apply to the active player.
|
||||
({double playerVolume, double persistedVolume}) resolveMuteToggle(double currentVolume) {
|
||||
if (currentVolume.isFinite && currentVolume > 0) {
|
||||
return (playerVolume: 0, persistedVolume: currentVolume);
|
||||
}
|
||||
|
||||
final previousVolume = read(volume);
|
||||
final candidate = previousVolume.isFinite && previousVolume > 0 ? previousVolume : volume.defaultValue;
|
||||
final restoredVolume = candidate.clamp(0.0, read(maxVolume).toDouble()).toDouble();
|
||||
return (playerVolume: restoredVolume, persistedVolume: restoredVolume);
|
||||
}
|
||||
|
||||
static Map<String, String> defaultKeyboardShortcuts() => _defaultKeyboardShortcuts();
|
||||
static Map<String, HotKey> defaultKeyboardHotkeys() => _defaultKeyboardHotkeys();
|
||||
|
||||
|
||||
@@ -148,9 +148,9 @@ class _VolumeControlState extends State<VolumeControl> {
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () async {
|
||||
final newVolume = isMuted ? 100.0 : 0.0;
|
||||
await widget.player.setVolume(newVolume);
|
||||
await _settings.write(SettingsService.volume, newVolume);
|
||||
final transition = _settings.resolveMuteToggle(widget.player.state.volume);
|
||||
await widget.player.setVolume(transition.playerVolume);
|
||||
await _settings.write(SettingsService.volume, transition.persistedVolume);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user