From 23844a6013ac6acb385f50d1d49027390ded7a91 Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Thu, 11 Jan 2024 18:39:24 +0000 Subject: [PATCH 1/2] feat/disable_audio_service puts it behind a config option, replaces --- README.md | 25 ++------------ ovos_audio/service.py | 72 ++++++++++++++++++++--------------------- ovos_audio/utils.py | 5 +-- requirements/extras.txt | 10 +----- 4 files changed, 42 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 09e2120..9e5dfc5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The "mouth" of the OVOS assistant! -Handles TTS generation and audio playback +Handles TTS generation and sounds playback ## Install @@ -51,27 +51,6 @@ under mycroft.conf // Mechanism used to play OGG audio files // Override: SYSTEM - "play_ogg_cmdline": "ogg123 -q %1", - - "Audio": { - // message.context may contains a source and destination - // native audio (playback / TTS) will only be played if a - // message destination is a native_source or if missing (considered a broadcast) - "native_sources": ["debug_cli", "audio"], - - "backends": { - "OCP": { - "type": "ovos_common_play", - "active": true - }, - "simple": { - "type": "ovos_audio_simple", - "active": true - }, - "vlc": { - "type": "ovos_vlc", - "active": true - } - } + "play_ogg_cmdline": "ogg123 -q %1" } ``` \ No newline at end of file diff --git a/ovos_audio/service.py b/ovos_audio/service.py index f1f92fd..a538b48 100644 --- a/ovos_audio/service.py +++ b/ovos_audio/service.py @@ -11,12 +11,11 @@ from ovos_bus_client import Message, MessageBusClient from ovos_bus_client.session import SessionManager from ovos_config.config import Configuration -from ovos_plugin_manager.audio import get_audio_service_configs from ovos_plugin_manager.g2p import get_g2p_lang_configs, get_g2p_supported_langs, get_g2p_module_configs from ovos_plugin_manager.tts import TTS from ovos_plugin_manager.tts import get_tts_supported_langs, get_tts_lang_configs, get_tts_module_configs from ovos_utils.file_utils import resolve_resource_file -from ovos_utils.log import LOG +from ovos_utils.log import LOG, deprecated from ovos_utils.metrics import Stopwatch from ovos_utils.process_utils import ProcessStatus, StatusCallbackMap from ovos_utils.sound import play_audio @@ -29,23 +28,23 @@ def on_ready(): - LOG.info('Audio service is ready.') + LOG.info('TTS service is ready.') def on_alive(): - LOG.info('Audio service is alive.') + LOG.info('TTS service is alive.') def on_started(): - LOG.info('Audio service started.') + LOG.info('TTS service started.') def on_error(e='Unknown'): - LOG.error(f'Audio service failed to launch ({e}).') + LOG.error(f'TTS service failed to launch ({e}).') def on_stopping(): - LOG.info('Audio service is shutting down...') + LOG.info('TTS service is shutting down...') class PlaybackService(Thread): @@ -93,11 +92,13 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, LOG.exception(e) self.status.set_error(e) - try: - self.audio = AudioService(self.bus, disable_ocp=disable_ocp, validate_source=validate_source) - except Exception as e: - LOG.exception(e) - self.status.set_error(e) + self.audio = None + self.audio_enabled = self.config.get("enable_old_audioservice", True) # TODO default to False soon + if self.audio_enabled: + try: + self.audio = AudioService(self.bus, disable_ocp=disable_ocp, validate_source=validate_source) + except Exception as e: + LOG.exception(e) @staticmethod def get_tts_lang_options(lang, blacklist=None): @@ -157,6 +158,7 @@ def get_g2p_lang_options(lang, blacklist=None): return opts @staticmethod + @deprecated("audio service moved to ovos-media", "0.1.0") def get_audio_options(blacklist=None): """ returns a list of options to be consumed by an external UI each dict contains metadata about the plugins @@ -166,17 +168,7 @@ def get_audio_options(blacklist=None): "active": True, "plugin_name": 'Ovos Common Play'}] """ - blacklist = blacklist or [] opts = [] - cfgs = get_audio_service_configs() - for name, config in cfgs.items(): - engine = config["type"] - if engine in blacklist: - continue - # For Display purposes, we want to show the engine name without the underscore or dash and capitalized all - plugin_display_name = engine.replace("_", " ").replace("-", " ").title() - config["plugin_name"] = plugin_display_name - opts.append(config) return opts def handle_opm_tts_query(self, message): @@ -229,6 +221,7 @@ def handle_opm_g2p_query(self, message): } self.bus.emit(message.response(data)) + @deprecated("audio service moved to ovos-media", "0.1.0") def handle_opm_audio_query(self, message): """ Responds to opm.audio.query with data about installed plugins @@ -237,21 +230,23 @@ def handle_opm_audio_query(self, message): "configs" - {backend_name: backend_cfg}} "options" - {lang: [list_of_valid_ui_metadata]} """ - cfgs = get_audio_service_configs() data = { - "plugins": list(cfgs.keys()), - "configs": cfgs, - "options": self.get_audio_options() + "plugins": [], + "configs": {}, + "options": {} } self.bus.emit(message.response(data)) def run(self): self.status.set_alive() - if self.audio.wait_for_load(): - if len(self.audio.service) == 0: - LOG.warning('No audio backends loaded! ' - 'Audio playback is not available') - LOG.info("Running audio service in TTS only mode") + if self.audio_enabled: + LOG.warning("audio service has moved to ovos-media, if you already migrated to ovos-media " + 'set "enable_old_audioservice": false in mycroft.conf') + if self.audio.wait_for_load(): + if len(self.audio.service) == 0: + LOG.warning('No audio backends loaded! ' + 'Audio playback is not available') + LOG.info("Running audio service in TTS only mode") # If at least TTS exists, report ready if self.tts: self.status.set_ready() @@ -492,14 +487,18 @@ def handle_instant_play(self, message): volume_changed = True elif muted: self.bus.emit(Message("mycroft.volume.unmute")) - if self.audio.current and not duck_pulse_handled: - self.audio.current.lower_volume() + + if self.audio: + if self.audio.current and not duck_pulse_handled: + self.audio.current.lower_volume() play_audio(audio_file).wait() # return to previous state - if self.audio.current and not duck_pulse_handled: - self.audio.current.restore_volume() + if self.audio: + if self.audio.current and not duck_pulse_handled: + self.audio.current.restore_volume() + if ensure_volume: if volume_changed: self.bus.emit(Message("mycroft.volume.set", {"percent": volume, @@ -528,7 +527,8 @@ def shutdown(self): if self.tts.playback: self.tts.playback.shutdown() self.tts.playback.join() - self.audio.shutdown() + if self.audio: + self.audio.shutdown() def init_messagebus(self): """ diff --git a/ovos_audio/utils.py b/ovos_audio/utils.py index 9d48d33..4eaad21 100644 --- a/ovos_audio/utils.py +++ b/ovos_audio/utils.py @@ -14,10 +14,11 @@ # import time +from ovos_utils.log import deprecated +from ovos_utils.signal import check_for_signal + from ovos_bus_client.send_func import send from ovos_config import Configuration -from ovos_utils.log import LOG, deprecated -from ovos_utils.signal import check_for_signal def validate_message_context(message, native_sources=None): diff --git a/requirements/extras.txt b/requirements/extras.txt index 110e6f2..a822e9c 100644 --- a/requirements/extras.txt +++ b/requirements/extras.txt @@ -1,9 +1 @@ -ovos_plugin_common_play~=0.0, >=0.0.6a11 - -ovos-tts-plugin-server - -# ovos-ocp-youtube-plugin -ovos-ocp-m3u-plugin -ovos-ocp-rss-plugin -ovos-ocp-files-plugin -ovos-ocp-news-plugin \ No newline at end of file +ovos-tts-plugin-server \ No newline at end of file From cc960e7f2ea35a6f6de0f5127edab57d8dcaebe3 Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Thu, 11 Jan 2024 19:23:52 +0000 Subject: [PATCH 2/2] feat/disable_audio_service puts it behind a config option, replaces --- test/unittests/test_speech.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/test/unittests/test_speech.py b/test/unittests/test_speech.py index 6c91279..1451bc1 100644 --- a/test/unittests/test_speech.py +++ b/test/unittests/test_speech.py @@ -286,27 +286,17 @@ def rcvm(msg): speech.handle_opm_g2p_query(Message("opm.g2p.query")) - @mock.patch('ovos_audio.service.get_audio_service_configs') - def test_opm_audio(self, mock_get_configs, tts_factory_mock, config_mock): + def test_opm_audio(self, tts_factory_mock, config_mock): setup_mocks(config_mock, tts_factory_mock) - ocp = {"type": "ovos_common_play", "active": True} - p = {"type": "ovos_badass_player", "active": True} - - # per module configs, mocking same return val for all plugin inputs (!) - mock_get_configs.return_value = {"ocp": ocp, "badass": p} - bus = FakeBus() speech = PlaybackService(bus=bus) def rcvm(msg): msg = json.loads(msg) self.assertEqual(msg["type"], "opm.audio.query.response") - self.assertEqual(msg["data"]["plugins"], ["ocp", "badass"]) - self.assertEqual(msg["data"]["configs"], {"ocp": ocp, "badass": p}) - ocp["plugin_name"] = 'Ovos Common Play' - p["plugin_name"] = 'Ovos Badass Player' - self.assertEqual(msg["data"]["options"], [ocp, p]) + self.assertEqual(msg["data"]["plugins"], []) + self.assertEqual(msg["data"]["configs"], {}) bus.on("message", rcvm)