5858from .messages_system import PyRadioMessagesSystem
5959from .server import PyRadioServer, HAS_NETIFACES
6060from .keyboard import kbkey, get_lkbkey, get_unicode_and_cjk_char, dequeue_input, input_queue, set_kb_letter, check_localized, add_l10n_to_functions_dict, set_kb_cjk
61-
61+ from .tts import TTSManager
6262HAVE_CHARSET_NORMALIZER = True
6363try:
6464 from .m3u import parse_m3u
@@ -2129,6 +2129,7 @@ def run(self):
21292129 except KeyboardInterrupt:
21302130 pass
21312131 else:
2132+ self.tts = TTSManager()
21322133 ''' start update detection and notification thread '''
21332134 if CAN_CHECK_FOR_UPDATES:
21342135 if self._cnf.locked:
@@ -2383,6 +2384,10 @@ def ctrl_c_handler(self, signum, frame, save_playlist=True):
23832384 self._remove_icons()
23842385
23852386 def _wait_for_threads(self):
2387+ if hasattr(self, 'tts') and self.tts:
2388+ logger.debug("Stopping TTS threads...")
2389+ # Phase 1: Immediate interruption (non-blocking)
2390+ self.tts.shutdown()
23862391 self.log._stop_desktop_notification_thread = True
23872392 if self._watch_theme_thread:
23882393 self.stop_watch_theme_thread = True
@@ -2409,6 +2414,13 @@ def _wait_for_threads(self):
24092414 if self._simple_schedule:
24102415 self._simple_schedule.exit()
24112416 self._simple_schedule = None
2417+ if hasattr(self, 'tts') and self.tts:
2418+ # Phase 2: Wait for TTS to fully stop (with timeout)
2419+ clean_shutdown = self.tts.wait_for_shutdown(timeout=2.0)
2420+ if clean_shutdown:
2421+ logger.debug("TTS threads stopped cleanly")
2422+ else:
2423+ logger.warning("TTS threads forced to stop")
24122424
24132425 def _goto_playing_station(self, changing_playlist=False):
24142426 ''' make sure playing station is visible '''
@@ -6735,6 +6747,12 @@ def _exit_program_or_playlist_mode(self):
67356747 self._cnf.EXTERNAL_PLAYER_OPTS = None
67366748 return False
67376749
6750+ def _speak_selection(self):
6751+ if self.ws.operation_mode == self.ws.NORMAL_MODE:
6752+ self.tts.speak(f'Selected station: {self.stations[self.selection][0]}')
6753+ elif self.ws.operation_mode == self.ws.PLAYLIST_MODE:
6754+ self.tts.speak(f'Selected playlist: {self.stations[self.selection][0]}')
6755+
67386756 def keypress(self, char):
67396757 ''' PyRadio keypress '''
67406758 # # logger.error('\n\nparams\n{}\n\n'.format(self._cnf.params))
@@ -9789,19 +9807,23 @@ def keypress(self, char):
97899807 if char in (curses.KEY_DOWN, kbkey['j']) or \
97909808 check_localized(char, (kbkey['j'], )):
97919809 self._move_cursor_one_down()
9810+ self._speak_selection()
97929811 return
97939812
97949813 if char in (curses.KEY_UP, kbkey['k']) or \
97959814 check_localized(char, (kbkey['k'], )):
97969815 self._move_cursor_one_up()
9816+ self._speak_selection()
97979817 return
97989818
97999819 if char in (curses.KEY_PPAGE, ):
98009820 self._page_up()
9821+ self._speak_selection()
98019822 return
98029823
98039824 if char in (curses.KEY_NPAGE, ):
98049825 self._page_down()
9826+ self._speak_selection()
98059827 return
98069828
98079829 if self.ws.operation_mode == self.ws.NORMAL_MODE:
0 commit comments