Skip to content

Commit

Permalink
refactor/optional-ocp (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
JarbasAl authored Aug 4, 2023
1 parent 8948d37 commit 2e961ba
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 29 deletions.
76 changes: 51 additions & 25 deletions ovos_audio/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import time
from ovos_bus_client.message import Message
from ovos_config.config import Configuration
from ovos_plugin_manager.audio import load_audio_service_plugins as load_plugins
from ovos_plugin_manager.audio import load_audio_service_plugins as load_plugins, find_audio_service_plugins, setup_audio_service
from ovos_plugin_manager.templates.audio import RemoteAudioBackend
from ovos_utils.log import LOG
from ovos_utils.process_utils import MonotonicEvent
Expand All @@ -34,7 +34,7 @@ class AudioService:
to be played.
"""

def __init__(self, bus, autoload=True):
def __init__(self, bus, autoload=True, disable_ocp=False, validate_source=True):
"""
Args:
bus: Mycroft messagebus
Expand All @@ -48,45 +48,72 @@ def __init__(self, bus, autoload=True):
self.current = None
self.play_start_time = 0
self.volume_is_low = False
self.disable_ocp = disable_ocp
self.validate_source = validate_source

self._loaded = MonotonicEvent()
if autoload:
self.load_services()

def find_ocp(self):
for s in self.service:
if OCPAudioBackend is not None and isinstance(s, OCPAudioBackend):
LOG.info('OCP - OVOS Common Play set as default backend')
self.default = s
return True

def find_default(self):
# Find default backend
default_name = self.config.get('default-backend', '')
if self.disable_ocp and default_name == "OCP":
LOG.warning("default backend set to OCP, but OCP is disabled")
default_name = ""
LOG.info('Finding default audio backend...')
for s in self.service:
if s.name == default_name:
self.default = s
LOG.info('Found ' + self.default.name)
return True
else:
self.default = None
LOG.info('no default found')

def load_services(self):
"""Method for loading services.
Sets up the global service, default and registers the event handlers
for the subsystem.
"""
services = load_plugins(self.config, self.bus)
found_plugins = find_audio_service_plugins()
if 'ovos_common_play' in found_plugins and self.disable_ocp:
found_plugins.pop('ovos_common_play')

local = []
remote = []
for plugin_name, plugin_module in found_plugins.items():
LOG.info(f'Loading audio service plugin: {plugin_name}')
s = setup_audio_service(plugin_module, bus=self.bus)
if not s:
continue
if isinstance(s, RemoteAudioBackend):
remote += s
else:
local += s


# Sort services so local services are checked first
local = [s for s in services if not isinstance(s, RemoteAudioBackend)]
remote = [s for s in services if isinstance(s, RemoteAudioBackend)]
self.service = local + remote

# Register end of track callback
for s in self.service:
s.set_track_start_callback(self.track_start)

# Find OCP
for s in local:
if OCPAudioBackend is not None and isinstance(s, OCPAudioBackend):
LOG.info('OCP - OVOS Common Play set as default backend')
self.default = s
break
if self.disable_ocp:
# default to classic audio only service
self.find_default()
else:
# Find default backend
default_name = self.config.get('default-backend', '')
LOG.info('Finding default backend...')
for s in self.service:
if s.name == default_name:
self.default = s
LOG.info('Found ' + self.default.name)
break
else:
self.default = None
LOG.info('no default found')
# default to OCP, fallback to classic audio only service
self.find_ocp() or self.find_default()

# Setup event handlers
self.bus.on('mycroft.audio.service.play', self._play)
Expand Down Expand Up @@ -323,9 +350,8 @@ def play(self, tracks, prefered_service, repeat=False):
self.current = selected_service
self.play_start_time = time.monotonic()

@staticmethod
def _is_message_for_service(message):
if not message:
def _is_message_for_service(self, message):
if not message or not self.validate_source:
return True
destination = message.context.get("destination")
if destination:
Expand Down
8 changes: 5 additions & 3 deletions ovos_audio/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def on_stopping():
class PlaybackService(Thread):
def __init__(self, ready_hook=on_ready, error_hook=on_error,
stopping_hook=on_stopping, alive_hook=on_alive,
started_hook=on_started, watchdog=lambda: None, bus=None):
started_hook=on_started, watchdog=lambda: None,
bus=None, disable_ocp=False, validate_source=True):
super(PlaybackService, self).__init__()

LOG.info("Starting Audio Service")
Expand All @@ -62,6 +63,7 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error,
self.fallback_tts = None
self._fallback_tts_hash = None
self._last_stop_signal = 0
self.validate_source = validate_source

if not bus:
bus = MessageBusClient()
Expand All @@ -78,7 +80,7 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error,
self.status.set_error(e)

try:
self.audio = AudioService(self.bus)
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)
Expand Down Expand Up @@ -251,7 +253,7 @@ def handle_speak(self, message):
# if the message is targeted and audio is not the target don't
# don't synthesise speech
message.context = message.context or {}
if message.context.get('destination') and not \
if self.validate_source and message.context.get('destination') and not \
any(s in message.context['destination'] for s in self.native_sources):
return

Expand Down
3 changes: 2 additions & 1 deletion test/unittests/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ def setup_mock_backends(mock_load_services, emitter):
return backend, second_backend


@unittest.skip("TODO - the mocks no longer apply, rewrite tests")
class TestService(unittest.TestCase):
emitter = MockEmitter()
service_path = abspath(join(dirname(__file__), 'services'))

@mock.patch('ovos_audio.audio.load_plugins')
@mock.patch('ovos_audio.audio.find_audio_service_plugins')
def test_audio_backend_shutdown(self, mock_load_services):
"""Test shutdown of audio backend."""
backend, second_backend = setup_mock_backends(mock_load_services,
Expand Down

0 comments on commit 2e961ba

Please sign in to comment.