Messages are much less verbose now.
This commit is contained in:
+18
-87
@@ -204,9 +204,7 @@ class BookReader:
|
||||
"""Load and parse the book"""
|
||||
# Check if bookPath is a directory (folder audiobook)
|
||||
if self.bookPath.is_dir():
|
||||
message = f"Loading audiobook folder {self.bookPath.name}"
|
||||
print(message)
|
||||
self.speechEngine.speak(message)
|
||||
self.speechEngine.speak(f"Loading audiobook folder {self.bookPath.name}")
|
||||
|
||||
# Use folder audiobook parser
|
||||
self.parser = FolderAudiobookParser()
|
||||
@@ -238,9 +236,6 @@ class BookReader:
|
||||
else:
|
||||
raise ValueError(f"Unsupported book format: {self.bookPath.suffix}")
|
||||
|
||||
print(f"Loaded: {self.book.title}")
|
||||
print(f"Chapters: {self.book.get_total_chapters()}")
|
||||
|
||||
# If it's an audio book, load it into the player
|
||||
if hasattr(self.book, 'isAudioBook') and self.book.isAudioBook:
|
||||
# Get saved playback speed from config
|
||||
@@ -262,11 +257,8 @@ class BookReader:
|
||||
|
||||
# Inform user about navigation capabilities
|
||||
if self.book.get_total_chapters() == 1:
|
||||
print("\nNote: This audio file has no chapter markers.")
|
||||
print("Navigation: Only play/pause/stop supported (no chapter jumping)")
|
||||
self.speechEngine.speak("Audio book loaded. No chapter markers found. Only basic playback controls available.")
|
||||
else:
|
||||
print(f"\nChapter navigation: Enabled ({self.book.get_total_chapters()} chapters)")
|
||||
self.speechEngine.speak(f"Audio book loaded with {self.book.get_total_chapters()} chapters. Chapter navigation enabled.")
|
||||
|
||||
# Check if this book is linked to Audiobookshelf server
|
||||
@@ -282,10 +274,6 @@ class BookReader:
|
||||
if serverProgress:
|
||||
progressTime = serverProgress.get('currentTime', 0.0)
|
||||
if progressTime > 0:
|
||||
minutes = int(progressTime // 60)
|
||||
seconds = int(progressTime % 60)
|
||||
print(f"Resuming from server progress: {minutes}m {seconds}s")
|
||||
|
||||
# For audio books, save exact position
|
||||
if hasattr(self.book, 'isAudioBook') and self.book.isAudioBook:
|
||||
self.savedAudioPosition = progressTime
|
||||
@@ -303,8 +291,8 @@ class BookReader:
|
||||
pass
|
||||
|
||||
serverProgressLoaded = True
|
||||
except Exception as e:
|
||||
print(f"Could not load server progress: {e}")
|
||||
except:
|
||||
pass
|
||||
|
||||
# Fall back to local bookmark if no server progress
|
||||
if not serverProgressLoaded:
|
||||
@@ -313,16 +301,7 @@ class BookReader:
|
||||
self.currentChapter = bookmark['chapterIndex']
|
||||
self.currentParagraph = bookmark['paragraphIndex']
|
||||
self.savedAudioPosition = bookmark.get('audioPosition', 0.0)
|
||||
|
||||
# For audio books, show resume position
|
||||
if hasattr(self.book, 'isAudioBook') and self.book.isAudioBook and self.savedAudioPosition > 0:
|
||||
minutes = int(self.savedAudioPosition // 60)
|
||||
seconds = int(self.savedAudioPosition % 60)
|
||||
print(f"Resuming from local bookmark: chapter {self.currentChapter + 1} at {minutes}m {seconds}s")
|
||||
else:
|
||||
print(f"Resuming from chapter {self.currentChapter + 1}, paragraph {self.currentParagraph + 1}")
|
||||
else:
|
||||
print("Starting from beginning")
|
||||
self.currentChapter = 0
|
||||
self.currentParagraph = 0
|
||||
self.savedAudioPosition = 0.0
|
||||
@@ -349,10 +328,8 @@ class BookReader:
|
||||
# Generate and play audio (unless muted for Braille-only mode)
|
||||
if not self.brailleOutput.muteVoice:
|
||||
try:
|
||||
print("Generating speech...")
|
||||
wavData = self.ttsEngine.text_to_wav_data(paragraph)
|
||||
if wavData:
|
||||
print("Playing...")
|
||||
completed = self.audioPlayer.play_wav_data(wavData, blocking=True)
|
||||
return completed
|
||||
except Exception as e:
|
||||
@@ -601,14 +578,14 @@ class BookReader:
|
||||
if self.book:
|
||||
self.displayText = "Press SPACE to start reading"
|
||||
self.statusText = f"Book: {self.book.title}"
|
||||
print(f"\n{self.book.title} - {self.book.get_total_chapters()} chapters")
|
||||
print("Press SPACE to start reading")
|
||||
self.speechEngine.speak("BookStorm ready. Press SPACE to start reading. Press i for info. Press h for help.")
|
||||
|
||||
# Determine book type for message
|
||||
isAudioBook = hasattr(self.book, 'isAudioBook') and self.book.isAudioBook
|
||||
bookType = "Audio book" if isAudioBook else "Book"
|
||||
self.speechEngine.speak(f"{bookType} loaded, press h for help.")
|
||||
else:
|
||||
self.displayText = "No book loaded"
|
||||
self.statusText = "Press A for Audiobookshelf, B for local books, R for recent books"
|
||||
print("\nNo book loaded")
|
||||
print("Press A for Audiobookshelf, B for local books, R for recent books")
|
||||
# Speech message already given earlier
|
||||
|
||||
# Cached rendered surfaces to prevent memory leak from re-rendering 30 FPS
|
||||
@@ -835,18 +812,14 @@ class BookReader:
|
||||
gc.collect() # Full collection every 20 seconds
|
||||
else:
|
||||
gc.collect(generation=0) # Fast collection every 10 seconds
|
||||
# Debug: Print memory usage every 10 seconds
|
||||
# Memory watchdog: warn if exceeding 2GB (50% on Pi 4GB)
|
||||
try:
|
||||
import resource
|
||||
# pylint: disable=no-member
|
||||
memUsage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 # MB
|
||||
print(f"DEBUG: Memory usage: {memUsage:.1f} MB")
|
||||
|
||||
# Memory watchdog: warn if exceeding 2GB (50% on Pi 4GB)
|
||||
if memUsage > 2048 and not memoryWarningShown:
|
||||
memoryWarningShown = True
|
||||
self.speechEngine.speak("Warning: High memory usage detected. Consider restarting BookStorm soon.")
|
||||
print("WARNING: Memory usage exceeds 2GB - consider restarting")
|
||||
except:
|
||||
pass
|
||||
gcCounter = 0
|
||||
@@ -912,9 +885,6 @@ class BookReader:
|
||||
# Common commands (from brltty documentation):
|
||||
# FWINRT (forward) and FWINLT (backward) for panning
|
||||
|
||||
# For debugging, print the key code
|
||||
print(f"DEBUG: Braille key pressed: {keyCode}")
|
||||
|
||||
# Check if it's a panning command
|
||||
# The key format varies by device, but we can check ranges
|
||||
# Typically: 0x04000000 range for panning commands
|
||||
@@ -928,18 +898,13 @@ class BookReader:
|
||||
|
||||
if command == CMD_FWINRT or (keyCode & 0xFF) == 0x01:
|
||||
# Forward panning
|
||||
print("DEBUG: Braille pan forward")
|
||||
self.brailleOutput.pan_forward()
|
||||
elif command == CMD_FWINLT or (keyCode & 0xFF) == 0x02:
|
||||
# Backward panning
|
||||
print("DEBUG: Braille pan backward")
|
||||
self.brailleOutput.pan_backward()
|
||||
else:
|
||||
# Unknown key - just log it for now
|
||||
print(f"DEBUG: Unknown Braille key: 0x{keyCode:08x}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"DEBUG: Error handling Braille key: {e}")
|
||||
except:
|
||||
pass
|
||||
|
||||
def _handle_pygame_key(self, event):
|
||||
"""Handle pygame key event"""
|
||||
@@ -993,8 +958,6 @@ class BookReader:
|
||||
readerEngine = self.config.get_reader_engine()
|
||||
|
||||
if not self.isPlaying:
|
||||
# Speak UI feedback (always safe with separate sessions)
|
||||
self.speechEngine.speak("Starting playback")
|
||||
self.isPlaying = True
|
||||
self._start_paragraph_playback()
|
||||
else:
|
||||
@@ -1002,26 +965,20 @@ class BookReader:
|
||||
if isAudioBook:
|
||||
# Handle audio book pause/resume
|
||||
if self.audioPlayer.is_paused():
|
||||
self.speechEngine.speak("Resuming")
|
||||
self.audioPlayer.resume_audio_file()
|
||||
else:
|
||||
self.speechEngine.speak("Paused")
|
||||
self.audioPlayer.pause_audio_file()
|
||||
elif readerEngine == 'speechd':
|
||||
# Handle speech-dispatcher pause/resume
|
||||
if self.readingEngine.is_reading_paused():
|
||||
self.speechEngine.speak("Resuming")
|
||||
self.readingEngine.resume_reading()
|
||||
else:
|
||||
self.speechEngine.speak("Paused")
|
||||
self.readingEngine.pause_reading()
|
||||
else:
|
||||
# Handle piper-tts pause/resume (now uses audio file methods)
|
||||
if self.audioPlayer.is_paused():
|
||||
self.speechEngine.speak("Resuming")
|
||||
self.audioPlayer.resume_audio_file()
|
||||
else:
|
||||
self.speechEngine.speak("Paused")
|
||||
self.audioPlayer.pause_audio_file()
|
||||
|
||||
elif event.key == pygame.K_n:
|
||||
@@ -1043,8 +1000,6 @@ class BookReader:
|
||||
self._stop_playback()
|
||||
|
||||
if self.next_chapter():
|
||||
# Just say "Next chapter" without title to avoid confusion
|
||||
self.speechEngine.speak("Next chapter")
|
||||
if wasPlaying:
|
||||
self.isPlaying = True
|
||||
self._start_paragraph_playback()
|
||||
@@ -1081,8 +1036,6 @@ class BookReader:
|
||||
self._stop_playback()
|
||||
|
||||
if self.previous_chapter():
|
||||
# Just say "Previous chapter" without title to avoid confusion
|
||||
self.speechEngine.speak("Previous chapter")
|
||||
if wasPlaying:
|
||||
self.isPlaying = True
|
||||
self._start_paragraph_playback()
|
||||
@@ -1339,7 +1292,6 @@ class BookReader:
|
||||
# Shift+Left: Previous chapter
|
||||
self._stop_playback()
|
||||
if self.previous_chapter():
|
||||
self.speechEngine.speak("Previous chapter")
|
||||
if self.isPlaying:
|
||||
self._start_paragraph_playback()
|
||||
else:
|
||||
@@ -1372,7 +1324,6 @@ class BookReader:
|
||||
# Shift+Right: Next chapter
|
||||
self._stop_playback()
|
||||
if self.next_chapter():
|
||||
self.speechEngine.speak("Next chapter")
|
||||
if self.isPlaying:
|
||||
self._start_paragraph_playback()
|
||||
else:
|
||||
@@ -1837,8 +1788,6 @@ class BookReader:
|
||||
author = metadata.get('authorName', '')
|
||||
duration = media.get('duration', 0.0)
|
||||
|
||||
print(f"\nDEBUG: Streaming book ID: {serverId}")
|
||||
print(f"DEBUG: Title from metadata: {title}")
|
||||
|
||||
# Get streaming URL (pass full book details to avoid re-fetching)
|
||||
self.speechEngine.speak(f"Loading stream for {title}. Please wait.")
|
||||
@@ -1894,7 +1843,6 @@ class BookReader:
|
||||
# Save server book reference for resume on restart
|
||||
# Use special format: abs://{server_id} so we can detect and resume
|
||||
self.config.set_last_book(f"abs://{serverId}")
|
||||
print(f"DEBUG: Saved last_book as: abs://{serverId}")
|
||||
|
||||
# Create listening session (only if we don't already have one from resume)
|
||||
if not self.sessionId:
|
||||
@@ -1925,7 +1873,6 @@ class BookReader:
|
||||
progressTime = serverProgress.get('currentTime', 0.0)
|
||||
minutes = int(progressTime // 60)
|
||||
seconds = int(progressTime % 60)
|
||||
print(f"Resuming from server progress: {minutes}m {seconds}s ({progressTime:.1f}s)")
|
||||
|
||||
# Save the exact position for playback resume
|
||||
self.savedAudioPosition = progressTime
|
||||
@@ -2027,8 +1974,6 @@ class BookReader:
|
||||
duration = media.get('duration', 0.0)
|
||||
numChapters = media.get('numChapters', 0)
|
||||
|
||||
print(f"\nDEBUG: Downloading book ID: {serverId}")
|
||||
print(f"DEBUG: Title from metadata: {title}")
|
||||
|
||||
# Create sanitized filename
|
||||
safeTitle = "".join(c for c in title if c.isalnum() or c in (' ', '-', '_')).strip()
|
||||
@@ -2150,31 +2095,19 @@ class BookReader:
|
||||
if not isAudioBook:
|
||||
return False
|
||||
|
||||
# Check if audio is actually loaded/playing
|
||||
if not self.audioPlayer.is_audio_file_loaded():
|
||||
self.speechEngine.speak("Nothing playing")
|
||||
return False
|
||||
|
||||
# Get current position
|
||||
currentPos = self.audioPlayer.get_audio_position()
|
||||
|
||||
# Calculate new position
|
||||
newPos = max(0.0, currentPos + seconds)
|
||||
|
||||
# Seek to new position
|
||||
if self.audioPlayer.seek_audio(newPos):
|
||||
# Format time for speech feedback
|
||||
absSeconds = abs(seconds)
|
||||
if absSeconds >= 60:
|
||||
minutes = int(absSeconds // 60)
|
||||
secs = int(absSeconds % 60)
|
||||
if secs > 0:
|
||||
timeStr = f"{minutes} minutes {secs} seconds"
|
||||
else:
|
||||
timeStr = f"{minutes} minutes"
|
||||
else:
|
||||
timeStr = f"{int(absSeconds)} seconds"
|
||||
|
||||
direction = "forward" if seconds > 0 else "backward"
|
||||
self.speechEngine.speak(f"Seek {timeStr} {direction}")
|
||||
return True
|
||||
|
||||
return False
|
||||
# Seek to new position silently (audio feedback is enough)
|
||||
return self.audioPlayer.seek_audio(newPos)
|
||||
|
||||
def _load_new_book(self, bookPath):
|
||||
"""
|
||||
@@ -2359,7 +2292,6 @@ class BookReader:
|
||||
self.savedAudioPosition = 0.0
|
||||
minutes = int(startTime // 60)
|
||||
seconds = int(startTime % 60)
|
||||
print(f"Resuming playback at {minutes}m {seconds}s")
|
||||
else:
|
||||
# Get start time from audio chapter
|
||||
if hasattr(chapter, 'startTime'):
|
||||
@@ -2591,7 +2523,6 @@ def main():
|
||||
if lastBook and lastBook.startswith('abs://'):
|
||||
# Extract server book ID
|
||||
serverId = lastBook[6:] # Remove 'abs://' prefix
|
||||
print(f"Resuming Audiobookshelf book: {serverId}")
|
||||
|
||||
# Try to restore from cached server link
|
||||
from src.server_link_manager import ServerLinkManager
|
||||
|
||||
Reference in New Issue
Block a user