Volume adjustments should now save on exit.
This commit is contained in:
+42
-10
@@ -78,6 +78,10 @@ class BookReader:
|
|||||||
self.speechEngine = SpeechEngine() # UI feedback
|
self.speechEngine = SpeechEngine() # UI feedback
|
||||||
self.audioPlayer = MpvPlayer() # Used for both audio books and TTS playback
|
self.audioPlayer = MpvPlayer() # Used for both audio books and TTS playback
|
||||||
|
|
||||||
|
# Configure audio player from saved settings
|
||||||
|
savedVolume = self.config.get_volume()
|
||||||
|
self.audioPlayer.set_volume(savedVolume)
|
||||||
|
|
||||||
# Configure speech engine from saved settings
|
# Configure speech engine from saved settings
|
||||||
speechRate = self.config.get_speech_rate()
|
speechRate = self.config.get_speech_rate()
|
||||||
self.speechEngine.set_rate(speechRate)
|
self.speechEngine.set_rate(speechRate)
|
||||||
@@ -246,6 +250,10 @@ class BookReader:
|
|||||||
if not self.audioPlayer.load_audio_file(self.book.audioPath, playbackSpeed=playbackSpeed):
|
if not self.audioPlayer.load_audio_file(self.book.audioPath, playbackSpeed=playbackSpeed):
|
||||||
raise Exception("Failed to load audio file")
|
raise Exception("Failed to load audio file")
|
||||||
|
|
||||||
|
# Restore saved volume setting
|
||||||
|
savedVolume = self.config.get_volume()
|
||||||
|
self.audioPlayer.set_volume(savedVolume)
|
||||||
|
|
||||||
# Inform user about navigation capabilities
|
# Inform user about navigation capabilities
|
||||||
if self.book.get_total_chapters() == 1:
|
if self.book.get_total_chapters() == 1:
|
||||||
print("\nNote: This audio file has no chapter markers.")
|
print("\nNote: This audio file has no chapter markers.")
|
||||||
@@ -1220,20 +1228,32 @@ class BookReader:
|
|||||||
self.speechEngine.speak("No book loaded")
|
self.speechEngine.speak("No book loaded")
|
||||||
|
|
||||||
elif event.key == pygame.K_0:
|
elif event.key == pygame.K_0:
|
||||||
# Increase volume (audio books only - mpv handles volume control)
|
# Increase volume (audio books and Piper-TTS - mpv handles volume control)
|
||||||
if self.book and hasattr(self.book, 'isAudioBook') and self.book.isAudioBook:
|
if self.book:
|
||||||
newVolume = self.audioPlayer.increase_volume(5)
|
isAudioBook = hasattr(self.book, 'isAudioBook') and self.book.isAudioBook
|
||||||
self.speechEngine.speak(f"Volume {newVolume}")
|
isPiperMode = self.config.get_reader_engine() == 'piper'
|
||||||
|
if isAudioBook or isPiperMode:
|
||||||
|
newVolume = self.audioPlayer.increase_volume(5)
|
||||||
|
self.config.set_volume(newVolume)
|
||||||
|
self.speechEngine.speak(f"Volume {newVolume}")
|
||||||
|
else:
|
||||||
|
self.speechEngine.speak("Volume control only works for audio books and Piper TTS mode")
|
||||||
else:
|
else:
|
||||||
self.speechEngine.speak("Volume control only works for audio books")
|
self.speechEngine.speak("No book loaded")
|
||||||
|
|
||||||
elif event.key == pygame.K_9:
|
elif event.key == pygame.K_9:
|
||||||
# Decrease volume (audio books only - mpv handles volume control)
|
# Decrease volume (audio books and Piper-TTS - mpv handles volume control)
|
||||||
if self.book and hasattr(self.book, 'isAudioBook') and self.book.isAudioBook:
|
if self.book:
|
||||||
newVolume = self.audioPlayer.decrease_volume(5)
|
isAudioBook = hasattr(self.book, 'isAudioBook') and self.book.isAudioBook
|
||||||
self.speechEngine.speak(f"Volume {newVolume}")
|
isPiperMode = self.config.get_reader_engine() == 'piper'
|
||||||
|
if isAudioBook or isPiperMode:
|
||||||
|
newVolume = self.audioPlayer.decrease_volume(5)
|
||||||
|
self.config.set_volume(newVolume)
|
||||||
|
self.speechEngine.speak(f"Volume {newVolume}")
|
||||||
|
else:
|
||||||
|
self.speechEngine.speak("Volume control only works for audio books and Piper TTS mode")
|
||||||
else:
|
else:
|
||||||
self.speechEngine.speak("Volume control only works for audio books")
|
self.speechEngine.speak("No book loaded")
|
||||||
|
|
||||||
elif event.key == pygame.K_HOME and shiftPressed:
|
elif event.key == pygame.K_HOME and shiftPressed:
|
||||||
# Shift+Home: Clear bookmark and jump to beginning of book
|
# Shift+Home: Clear bookmark and jump to beginning of book
|
||||||
@@ -1905,6 +1925,10 @@ class BookReader:
|
|||||||
print("Make sure mpv is installed: sudo pacman -S mpv")
|
print("Make sure mpv is installed: sudo pacman -S mpv")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Restore saved volume setting
|
||||||
|
savedVolume = self.config.get_volume()
|
||||||
|
self.audioPlayer.set_volume(savedVolume)
|
||||||
|
|
||||||
# Success! Start playing
|
# Success! Start playing
|
||||||
self.speechEngine.speak(f"Now streaming {title}. Press space to pause.")
|
self.speechEngine.speak(f"Now streaming {title}. Press space to pause.")
|
||||||
print(f"\nNow streaming: {title} by {author}")
|
print(f"\nNow streaming: {title} by {author}")
|
||||||
@@ -2462,6 +2486,14 @@ class BookReader:
|
|||||||
self.serverLinkManager.clear_session(str(self.bookPath))
|
self.serverLinkManager.clear_session(str(self.bookPath))
|
||||||
self.sessionId = None
|
self.sessionId = None
|
||||||
|
|
||||||
|
# Save current volume setting if audio book or Piper-TTS was used
|
||||||
|
if self.book:
|
||||||
|
isAudioBook = hasattr(self.book, 'isAudioBook') and self.book.isAudioBook
|
||||||
|
isPiperMode = self.config.get_reader_engine() == 'piper'
|
||||||
|
if isAudioBook or isPiperMode:
|
||||||
|
currentVolume = self.audioPlayer.get_volume()
|
||||||
|
self.config.set_volume(currentVolume)
|
||||||
|
|
||||||
self._cancel_buffer()
|
self._cancel_buffer()
|
||||||
# Cleanup audio player (handles both TTS and audio books)
|
# Cleanup audio player (handles both TTS and audio books)
|
||||||
self.audioPlayer.cleanup()
|
self.audioPlayer.cleanup()
|
||||||
|
|||||||
+18
-1
@@ -57,7 +57,8 @@ class ConfigManager:
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.config['Audio'] = {
|
self.config['Audio'] = {
|
||||||
'playback_speed': '1.0'
|
'playback_speed': '1.0',
|
||||||
|
'volume': '100'
|
||||||
}
|
}
|
||||||
|
|
||||||
self.config['Paths'] = {
|
self.config['Paths'] = {
|
||||||
@@ -335,6 +336,22 @@ class ConfigManager:
|
|||||||
self.set('Audio', 'playback_speed', str(speed))
|
self.set('Audio', 'playback_speed', str(speed))
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
def get_volume(self):
|
||||||
|
"""Get audio volume (0-200, 100 is normal)"""
|
||||||
|
try:
|
||||||
|
volume = int(self.get('Audio', 'volume', '100'))
|
||||||
|
# Clamp to valid range
|
||||||
|
return max(0, min(200, volume))
|
||||||
|
except ValueError:
|
||||||
|
return 100
|
||||||
|
|
||||||
|
def set_volume(self, volume):
|
||||||
|
"""Set audio volume (0-200, 100 is normal)"""
|
||||||
|
# Clamp to valid range
|
||||||
|
volume = max(0, min(200, int(volume)))
|
||||||
|
self.set('Audio', 'volume', str(volume))
|
||||||
|
self.save()
|
||||||
|
|
||||||
# Braille settings
|
# Braille settings
|
||||||
|
|
||||||
def get_braille_enabled(self):
|
def get_braille_enabled(self):
|
||||||
|
|||||||
+27
-5
@@ -28,6 +28,7 @@ class MpvPlayer:
|
|||||||
self.isPaused = False
|
self.isPaused = False
|
||||||
self.audioFileLoaded = False # Track if audio file is loaded
|
self.audioFileLoaded = False # Track if audio file is loaded
|
||||||
self.playbackSpeed = 1.0 # Current playback speed
|
self.playbackSpeed = 1.0 # Current playback speed
|
||||||
|
self.volume = 100 # Current volume level (0-200)
|
||||||
self.endFileCallback = None # Callback for when file finishes
|
self.endFileCallback = None # Callback for when file finishes
|
||||||
self.playlist = [] # Current playlist (for multi-file audiobooks)
|
self.playlist = [] # Current playlist (for multi-file audiobooks)
|
||||||
self.currentPlaylistIndex = 0 # Current file index in playlist
|
self.currentPlaylistIndex = 0 # Current file index in playlist
|
||||||
@@ -183,6 +184,7 @@ class MpvPlayer:
|
|||||||
currentVolume = self.player.volume if self.player.volume is not None else 100
|
currentVolume = self.player.volume if self.player.volume is not None else 100
|
||||||
# Allow up to 200% for software amplification (useful for quiet audio)
|
# Allow up to 200% for software amplification (useful for quiet audio)
|
||||||
newVolume = min(200, currentVolume + step)
|
newVolume = min(200, currentVolume + step)
|
||||||
|
self.volume = newVolume
|
||||||
self.player.volume = newVolume
|
self.player.volume = newVolume
|
||||||
return int(newVolume)
|
return int(newVolume)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -206,6 +208,7 @@ class MpvPlayer:
|
|||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
currentVolume = self.player.volume if self.player.volume is not None else 100
|
currentVolume = self.player.volume if self.player.volume is not None else 100
|
||||||
newVolume = max(0, currentVolume - step)
|
newVolume = max(0, currentVolume - step)
|
||||||
|
self.volume = newVolume
|
||||||
self.player.volume = newVolume
|
self.player.volume = newVolume
|
||||||
return int(newVolume)
|
return int(newVolume)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -219,15 +222,30 @@ class MpvPlayer:
|
|||||||
Returns:
|
Returns:
|
||||||
Current volume (0-200, 100 is normal, >100 is software amplification)
|
Current volume (0-200, 100 is normal, >100 is software amplification)
|
||||||
"""
|
"""
|
||||||
|
# Return our tracked volume instead of querying mpv
|
||||||
|
# This is more reliable, especially during cleanup
|
||||||
|
return self.volume
|
||||||
|
|
||||||
|
def set_volume(self, volume):
|
||||||
|
"""
|
||||||
|
Set volume level
|
||||||
|
|
||||||
|
Args:
|
||||||
|
volume: Volume level (0-200, 100 is normal, >100 is software amplification)
|
||||||
|
"""
|
||||||
if not self.isInitialized or not self.player:
|
if not self.isInitialized or not self.player:
|
||||||
return 100
|
# Store it anyway for when player is ready
|
||||||
|
self.volume = max(0, min(200, int(volume)))
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Clamp to valid range
|
||||||
|
volume = max(0, min(200, int(volume)))
|
||||||
|
self.volume = volume
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
volume = self.player.volume
|
self.player.volume = volume
|
||||||
return int(volume) if volume is not None else 100
|
except Exception as e:
|
||||||
except:
|
print(f"Error setting volume: {e}")
|
||||||
return 100
|
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
"""Cleanup resources"""
|
"""Cleanup resources"""
|
||||||
@@ -283,6 +301,8 @@ class MpvPlayer:
|
|||||||
self.player.loadfile(audioPath, 'replace')
|
self.player.loadfile(audioPath, 'replace')
|
||||||
self.player.pause = True # Keep paused until play_audio_file() is called
|
self.player.pause = True # Keep paused until play_audio_file() is called
|
||||||
self.player.speed = self.playbackSpeed
|
self.player.speed = self.playbackSpeed
|
||||||
|
# Restore volume setting (important for TTS paragraphs)
|
||||||
|
self.player.volume = self.volume
|
||||||
self.audioFileLoaded = True
|
self.audioFileLoaded = True
|
||||||
self.playlist = [] # Clear playlist (single file mode)
|
self.playlist = [] # Clear playlist (single file mode)
|
||||||
self.currentPlaylistIndex = 0
|
self.currentPlaylistIndex = 0
|
||||||
@@ -338,6 +358,8 @@ class MpvPlayer:
|
|||||||
|
|
||||||
self.player.pause = True
|
self.player.pause = True
|
||||||
self.player.speed = self.playbackSpeed
|
self.player.speed = self.playbackSpeed
|
||||||
|
# Restore volume setting (important for playlist/folder audiobooks)
|
||||||
|
self.player.volume = self.volume
|
||||||
self.audioFileLoaded = True
|
self.audioFileLoaded = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user