diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 55746fd4..6698b3a0 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -150,6 +150,10 @@ class _VideoPlayerScreenState extends State { ); } + // Apply saved volume + final savedVolume = settingsService.getVolume(); + player!.setVolume(savedVolume); + // Notify that player is ready if (mounted) { setState(() { diff --git a/lib/services/keyboard_shortcuts_service.dart b/lib/services/keyboard_shortcuts_service.dart index 30bd9a56..abfd4a6c 100644 --- a/lib/services/keyboard_shortcuts_service.dart +++ b/lib/services/keyboard_shortcuts_service.dart @@ -262,10 +262,12 @@ class KeyboardShortcutsService { case 'volume_up': final newVolume = (player.state.volume + 10).clamp(0.0, 100.0); player.setVolume(newVolume); + _settingsService.setVolume(newVolume); break; case 'volume_down': final newVolume = (player.state.volume - 10).clamp(0.0, 100.0); player.setVolume(newVolume); + _settingsService.setVolume(newVolume); break; case 'seek_forward': _seekWithClamping(player, Duration(seconds: _seekTimeSmall)); @@ -283,7 +285,9 @@ class KeyboardShortcutsService { onToggleFullscreen?.call(); break; case 'mute_toggle': - player.setVolume(player.state.volume > 0 ? 0.0 : 100.0); + final newVolume = player.state.volume > 0 ? 0.0 : 100.0; + player.setVolume(newVolume); + _settingsService.setVolume(newVolume); break; case 'subtitle_toggle': onToggleSubtitles?.call(); diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 34d97bd9..5e06f5dd 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -29,6 +29,7 @@ class SettingsService { static const String _keySleepTimerDuration = 'sleep_timer_duration'; static const String _keyAudioSyncOffset = 'audio_sync_offset'; static const String _keySubtitleSyncOffset = 'subtitle_sync_offset'; + static const String _keyVolume = 'volume'; static SettingsService? _instance; late SharedPreferences _prefs; @@ -200,6 +201,15 @@ class SettingsService { 0; // Default: 0ms (no offset) } + // Volume (0.0 to 100.0) + Future setVolume(double volume) async { + await _prefs.setDouble(_keyVolume, volume); + } + + double getVolume() { + return _prefs.getDouble(_keyVolume) ?? 100.0; // Default: full volume + } + // Keyboard Shortcuts (Legacy String-based) Map getDefaultKeyboardShortcuts() { return { @@ -716,6 +726,7 @@ class SettingsService { _prefs.remove(_keySleepTimerDuration), _prefs.remove(_keyAudioSyncOffset), _prefs.remove(_keySubtitleSyncOffset), + _prefs.remove(_keyVolume), ]); } diff --git a/lib/widgets/video_controls/video_controls.dart b/lib/widgets/video_controls/video_controls.dart index b73318ac..e8928512 100644 --- a/lib/widgets/video_controls/video_controls.dart +++ b/lib/widgets/video_controls/video_controls.dart @@ -1282,12 +1282,11 @@ class _PlexVideoControlsState extends State isMuted ? Icons.volume_off : Icons.volume_up, color: Colors.white, ), - onPressed: () { - if (isMuted) { - widget.player.setVolume(100.0); - } else { - widget.player.setVolume(0.0); - } + onPressed: () async { + final newVolume = isMuted ? 100.0 : 0.0; + widget.player.setVolume(newVolume); + final settings = await SettingsService.getInstance(); + await settings.setVolume(newVolume); }, padding: EdgeInsets.zero, constraints: const BoxConstraints(), @@ -1312,6 +1311,10 @@ class _PlexVideoControlsState extends State onChanged: (value) { widget.player.setVolume(value); }, + onChangeEnd: (value) async { + final settings = await SettingsService.getInstance(); + await settings.setVolume(value); + }, activeColor: Colors.white, inactiveColor: Colors.white.withValues(alpha: 0.3), ),