Rename mopidy.gstreamer to mopidy.audio
This commit is contained in:
parent
7f94464755
commit
aab37302a1
7
docs/modules/audio.rst
Normal file
7
docs/modules/audio.rst
Normal file
@ -0,0 +1,7 @@
|
||||
*************************************
|
||||
:mod:`mopidy.audio` -- Audio playback
|
||||
*************************************
|
||||
|
||||
.. automodule:: mopidy.audio
|
||||
:synopsis: Audio playback through GStreamer
|
||||
:members:
|
||||
@ -1,7 +0,0 @@
|
||||
********************************************
|
||||
:mod:`mopidy.gstreamer` -- GStreamer adapter
|
||||
********************************************
|
||||
|
||||
.. automodule:: mopidy.gstreamer
|
||||
:synopsis: GStreamer adapter
|
||||
:members:
|
||||
@ -30,7 +30,7 @@ sys.path.insert(0,
|
||||
|
||||
from mopidy import (get_version, settings, OptionalDependencyError,
|
||||
SettingsError, DATA_PATH, SETTINGS_PATH, SETTINGS_FILE)
|
||||
from mopidy.gstreamer import GStreamer
|
||||
from mopidy.audio import Audio
|
||||
from mopidy.utils import get_class
|
||||
from mopidy.utils.deps import list_deps_optparse_callback
|
||||
from mopidy.utils.log import setup_logging
|
||||
@ -51,7 +51,7 @@ def main():
|
||||
setup_logging(options.verbosity_level, options.save_debug_log)
|
||||
check_old_folders()
|
||||
setup_settings(options.interactive)
|
||||
setup_gstreamer()
|
||||
setup_audio()
|
||||
setup_backend()
|
||||
setup_frontends()
|
||||
loop.run()
|
||||
@ -65,7 +65,7 @@ def main():
|
||||
loop.quit()
|
||||
stop_frontends()
|
||||
stop_backend()
|
||||
stop_gstreamer()
|
||||
stop_audio()
|
||||
stop_remaining_actors()
|
||||
|
||||
|
||||
@ -117,12 +117,12 @@ def setup_settings(interactive):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def setup_gstreamer():
|
||||
GStreamer.start()
|
||||
def setup_audio():
|
||||
Audio.start()
|
||||
|
||||
|
||||
def stop_gstreamer():
|
||||
stop_actors_by_class(GStreamer)
|
||||
def stop_audio():
|
||||
stop_actors_by_class(Audio)
|
||||
|
||||
def setup_backend():
|
||||
get_class(settings.BACKENDS[0]).start()
|
||||
|
||||
@ -15,10 +15,10 @@ from mopidy.utils import process
|
||||
# Trigger install of gst mixer plugins
|
||||
from mopidy import mixers
|
||||
|
||||
logger = logging.getLogger('mopidy.gstreamer')
|
||||
logger = logging.getLogger('mopidy.audio')
|
||||
|
||||
|
||||
class GStreamer(ThreadingActor):
|
||||
class Audio(ThreadingActor):
|
||||
"""
|
||||
Audio output through `GStreamer <http://gstreamer.freedesktop.org/>`_.
|
||||
|
||||
@ -31,7 +31,7 @@ class GStreamer(ThreadingActor):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(GStreamer, self).__init__()
|
||||
super(Audio, self).__init__()
|
||||
|
||||
self._default_caps = gst.Caps("""
|
||||
audio/x-raw-int,
|
||||
@ -7,10 +7,9 @@ import shutil
|
||||
from pykka.actor import ThreadingActor
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core, settings, DATA_PATH
|
||||
from mopidy import audio, core, settings, DATA_PATH
|
||||
from mopidy.backends import base
|
||||
from mopidy.models import Playlist, Track, Album
|
||||
from mopidy.gstreamer import GStreamer
|
||||
|
||||
from .translator import parse_m3u, parse_mpd_tag_cache
|
||||
|
||||
@ -58,13 +57,13 @@ class LocalBackend(ThreadingActor, base.Backend):
|
||||
|
||||
self.uri_schemes = [u'file']
|
||||
|
||||
self.gstreamer = None
|
||||
self.audio = None
|
||||
|
||||
def on_start(self):
|
||||
gstreamer_refs = ActorRegistry.get_by_class(GStreamer)
|
||||
assert len(gstreamer_refs) == 1, \
|
||||
'Expected exactly one running GStreamer.'
|
||||
self.gstreamer = gstreamer_refs[0].proxy()
|
||||
audio_refs = ActorRegistry.get_by_class(audio.Audio)
|
||||
assert len(audio_refs) == 1, \
|
||||
'Expected exactly one running Audio instance.'
|
||||
self.audio = audio_refs[0].proxy()
|
||||
|
||||
|
||||
class LocalPlaybackController(core.PlaybackController):
|
||||
@ -76,32 +75,32 @@ class LocalPlaybackController(core.PlaybackController):
|
||||
|
||||
@property
|
||||
def time_position(self):
|
||||
return self.backend.gstreamer.get_position().get()
|
||||
return self.backend.audio.get_position().get()
|
||||
|
||||
|
||||
class LocalPlaybackProvider(base.BasePlaybackProvider):
|
||||
def pause(self):
|
||||
return self.backend.gstreamer.pause_playback().get()
|
||||
return self.backend.audio.pause_playback().get()
|
||||
|
||||
def play(self, track):
|
||||
self.backend.gstreamer.prepare_change()
|
||||
self.backend.gstreamer.set_uri(track.uri).get()
|
||||
return self.backend.gstreamer.start_playback().get()
|
||||
self.backend.audio.prepare_change()
|
||||
self.backend.audio.set_uri(track.uri).get()
|
||||
return self.backend.audio.start_playback().get()
|
||||
|
||||
def resume(self):
|
||||
return self.backend.gstreamer.start_playback().get()
|
||||
return self.backend.audio.start_playback().get()
|
||||
|
||||
def seek(self, time_position):
|
||||
return self.backend.gstreamer.set_position(time_position).get()
|
||||
return self.backend.audio.set_position(time_position).get()
|
||||
|
||||
def stop(self):
|
||||
return self.backend.gstreamer.stop_playback().get()
|
||||
return self.backend.audio.stop_playback().get()
|
||||
|
||||
def get_volume(self):
|
||||
return self.backend.gstreamer.get_volume().get()
|
||||
return self.backend.audio.get_volume().get()
|
||||
|
||||
def set_volume(self, volume):
|
||||
self.backend.gstreamer.set_volume(volume).get()
|
||||
self.backend.audio.set_volume(volume).get()
|
||||
|
||||
|
||||
class LocalStoredPlaylistsProvider(base.BaseStoredPlaylistsProvider):
|
||||
|
||||
@ -3,9 +3,8 @@ import logging
|
||||
from pykka.actor import ThreadingActor
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core, settings
|
||||
from mopidy import audio, core, settings
|
||||
from mopidy.backends import base
|
||||
from mopidy.gstreamer import GStreamer
|
||||
|
||||
logger = logging.getLogger('mopidy.backends.spotify')
|
||||
|
||||
@ -67,7 +66,7 @@ class SpotifyBackend(ThreadingActor, base.Backend):
|
||||
|
||||
self.uri_schemes = [u'spotify']
|
||||
|
||||
self.gstreamer = None
|
||||
self.audio = None
|
||||
self.spotify = None
|
||||
|
||||
# Fail early if settings are not present
|
||||
@ -75,10 +74,10 @@ class SpotifyBackend(ThreadingActor, base.Backend):
|
||||
self.password = settings.SPOTIFY_PASSWORD
|
||||
|
||||
def on_start(self):
|
||||
gstreamer_refs = ActorRegistry.get_by_class(GStreamer)
|
||||
assert len(gstreamer_refs) == 1, \
|
||||
'Expected exactly one running GStreamer.'
|
||||
self.gstreamer = gstreamer_refs[0].proxy()
|
||||
audio_refs = ActorRegistry.get_by_class(audio.Audio)
|
||||
assert len(audio_refs) == 1, \
|
||||
'Expected exactly one running Audio instance.'
|
||||
self.audio = audio_refs[0].proxy()
|
||||
|
||||
logger.info(u'Mopidy uses SPOTIFY(R) CORE')
|
||||
self.spotify = self._connect()
|
||||
|
||||
@ -8,7 +8,7 @@ logger = logging.getLogger('mopidy.backends.spotify.playback')
|
||||
|
||||
class SpotifyPlaybackProvider(BasePlaybackProvider):
|
||||
def pause(self):
|
||||
return self.backend.gstreamer.pause_playback()
|
||||
return self.backend.audio.pause_playback()
|
||||
|
||||
def play(self, track):
|
||||
if self.backend.playback.state == self.backend.playback.PLAYING:
|
||||
@ -19,10 +19,10 @@ class SpotifyPlaybackProvider(BasePlaybackProvider):
|
||||
self.backend.spotify.session.load(
|
||||
Link.from_string(track.uri).as_track())
|
||||
self.backend.spotify.session.play(1)
|
||||
self.backend.gstreamer.prepare_change()
|
||||
self.backend.gstreamer.set_uri('appsrc://')
|
||||
self.backend.gstreamer.start_playback()
|
||||
self.backend.gstreamer.set_metadata(track)
|
||||
self.backend.audio.prepare_change()
|
||||
self.backend.audio.set_uri('appsrc://')
|
||||
self.backend.audio.start_playback()
|
||||
self.backend.audio.set_metadata(track)
|
||||
return True
|
||||
except SpotifyError as e:
|
||||
logger.info('Playback of %s failed: %s', track.uri, e)
|
||||
@ -32,18 +32,18 @@ class SpotifyPlaybackProvider(BasePlaybackProvider):
|
||||
return self.seek(self.backend.playback.time_position)
|
||||
|
||||
def seek(self, time_position):
|
||||
self.backend.gstreamer.prepare_change()
|
||||
self.backend.audio.prepare_change()
|
||||
self.backend.spotify.session.seek(time_position)
|
||||
self.backend.gstreamer.start_playback()
|
||||
self.backend.audio.start_playback()
|
||||
return True
|
||||
|
||||
def stop(self):
|
||||
result = self.backend.gstreamer.stop_playback()
|
||||
result = self.backend.audio.stop_playback()
|
||||
self.backend.spotify.session.play(0)
|
||||
return result
|
||||
|
||||
def get_volume(self):
|
||||
return self.backend.gstreamer.get_volume().get()
|
||||
return self.backend.audio.get_volume().get()
|
||||
|
||||
def set_volume(self, volume):
|
||||
self.backend.gstreamer.set_volume(volume)
|
||||
self.backend.audio.set_volume(volume)
|
||||
|
||||
@ -6,14 +6,13 @@ from spotify.manager import SpotifySessionManager as PyspotifySessionManager
|
||||
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import get_version, settings, CACHE_PATH
|
||||
from mopidy import audio, get_version, settings, CACHE_PATH
|
||||
from mopidy.backends.base import Backend
|
||||
from mopidy.backends.spotify import BITRATES
|
||||
from mopidy.backends.spotify.container_manager import SpotifyContainerManager
|
||||
from mopidy.backends.spotify.playlist_manager import SpotifyPlaylistManager
|
||||
from mopidy.backends.spotify.translator import SpotifyTranslator
|
||||
from mopidy.models import Playlist
|
||||
from mopidy.gstreamer import GStreamer
|
||||
from mopidy.utils.process import BaseThread
|
||||
|
||||
logger = logging.getLogger('mopidy.backends.spotify.session_manager')
|
||||
@ -34,7 +33,7 @@ class SpotifySessionManager(BaseThread, PyspotifySessionManager):
|
||||
BaseThread.__init__(self)
|
||||
self.name = 'SpotifyThread'
|
||||
|
||||
self.gstreamer = None
|
||||
self.audio = None
|
||||
self.backend = None
|
||||
|
||||
self.connected = threading.Event()
|
||||
@ -50,10 +49,10 @@ class SpotifySessionManager(BaseThread, PyspotifySessionManager):
|
||||
self.connect()
|
||||
|
||||
def setup(self):
|
||||
gstreamer_refs = ActorRegistry.get_by_class(GStreamer)
|
||||
assert len(gstreamer_refs) == 1, \
|
||||
'Expected exactly one running gstreamer.'
|
||||
self.gstreamer = gstreamer_refs[0].proxy()
|
||||
audio_refs = ActorRegistry.get_by_class(audio.Audio)
|
||||
assert len(audio_refs) == 1, \
|
||||
'Expected exactly one running Audio instance.'
|
||||
self.audio = audio_refs[0].proxy()
|
||||
|
||||
backend_refs = ActorRegistry.get_by_class(Backend)
|
||||
assert len(backend_refs) == 1, 'Expected exactly one running backend.'
|
||||
@ -117,7 +116,7 @@ class SpotifySessionManager(BaseThread, PyspotifySessionManager):
|
||||
'sample_rate': sample_rate,
|
||||
'channels': channels,
|
||||
}
|
||||
self.gstreamer.emit_data(capabilites, bytes(frames))
|
||||
self.audio.emit_data(capabilites, bytes(frames))
|
||||
return num_frames
|
||||
|
||||
def play_token_lost(self, session):
|
||||
@ -143,7 +142,7 @@ class SpotifySessionManager(BaseThread, PyspotifySessionManager):
|
||||
def end_of_track(self, session):
|
||||
"""Callback used by pyspotify"""
|
||||
logger.debug(u'End of data stream reached')
|
||||
self.gstreamer.emit_end_of_stream()
|
||||
self.audio.emit_end_of_stream()
|
||||
|
||||
def refresh_stored_playlists(self):
|
||||
"""Refresh the stored playlists in the backend with fresh meta data
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import sys
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.gstreamer import GStreamer
|
||||
from mopidy import audio, settings
|
||||
from mopidy.utils.path import path_to_uri
|
||||
|
||||
from tests import unittest, path_to_data_dir
|
||||
@ -9,38 +8,38 @@ from tests import unittest, path_to_data_dir
|
||||
|
||||
@unittest.skipIf(sys.platform == 'win32',
|
||||
'Our Windows build server does not support GStreamer yet')
|
||||
class GStreamerTest(unittest.TestCase):
|
||||
class AudioTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
settings.MIXER = 'fakemixer track_max_volume=65536'
|
||||
settings.OUTPUT = 'fakesink'
|
||||
self.song_uri = path_to_uri(path_to_data_dir('song1.wav'))
|
||||
self.gstreamer = GStreamer.start().proxy()
|
||||
self.audio = audio.Audio.start().proxy()
|
||||
|
||||
def tearDown(self):
|
||||
self.gstreamer.stop()
|
||||
self.audio.stop()
|
||||
settings.runtime.clear()
|
||||
|
||||
def prepare_uri(self, uri):
|
||||
self.gstreamer.prepare_change()
|
||||
self.gstreamer.set_uri(uri)
|
||||
self.audio.prepare_change()
|
||||
self.audio.set_uri(uri)
|
||||
|
||||
def test_start_playback_existing_file(self):
|
||||
self.prepare_uri(self.song_uri)
|
||||
self.assertTrue(self.gstreamer.start_playback().get())
|
||||
self.assertTrue(self.audio.start_playback().get())
|
||||
|
||||
def test_start_playback_non_existing_file(self):
|
||||
self.prepare_uri(self.song_uri + 'bogus')
|
||||
self.assertFalse(self.gstreamer.start_playback().get())
|
||||
self.assertFalse(self.audio.start_playback().get())
|
||||
|
||||
def test_pause_playback_while_playing(self):
|
||||
self.prepare_uri(self.song_uri)
|
||||
self.gstreamer.start_playback()
|
||||
self.assertTrue(self.gstreamer.pause_playback().get())
|
||||
self.audio.start_playback()
|
||||
self.assertTrue(self.audio.pause_playback().get())
|
||||
|
||||
def test_stop_playback_while_playing(self):
|
||||
self.prepare_uri(self.song_uri)
|
||||
self.gstreamer.start_playback()
|
||||
self.assertTrue(self.gstreamer.stop_playback().get())
|
||||
self.audio.start_playback()
|
||||
self.assertTrue(self.audio.stop_playback().get())
|
||||
|
||||
@unittest.SkipTest
|
||||
def test_deliver_data(self):
|
||||
@ -52,8 +51,8 @@ class GStreamerTest(unittest.TestCase):
|
||||
|
||||
def test_set_volume(self):
|
||||
for value in range(0, 101):
|
||||
self.assertTrue(self.gstreamer.set_volume(value).get())
|
||||
self.assertEqual(value, self.gstreamer.get_volume().get())
|
||||
self.assertTrue(self.audio.set_volume(value).get())
|
||||
self.assertEqual(value, self.audio.get_volume().get())
|
||||
|
||||
@unittest.SkipTest
|
||||
def test_set_state_encapsulation(self):
|
||||
@ -66,4 +65,3 @@ class GStreamerTest(unittest.TestCase):
|
||||
@unittest.SkipTest
|
||||
def test_invalid_output_raises_error(self):
|
||||
pass # TODO
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import mock
|
||||
import random
|
||||
|
||||
from mopidy import audio
|
||||
from mopidy.models import CpTrack, Playlist, Track
|
||||
from mopidy.gstreamer import GStreamer
|
||||
|
||||
from tests.backends.base import populate_playlist
|
||||
|
||||
@ -12,7 +12,7 @@ class CurrentPlaylistControllerTest(object):
|
||||
|
||||
def setUp(self):
|
||||
self.backend = self.backend_class()
|
||||
self.backend.gstreamer = mock.Mock(spec=GStreamer)
|
||||
self.backend.audio = mock.Mock(spec=audio.Audio)
|
||||
self.controller = self.backend.current_playlist
|
||||
self.playback = self.backend.playback
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@ import mock
|
||||
import random
|
||||
import time
|
||||
|
||||
from mopidy import audio
|
||||
from mopidy.models import Track
|
||||
from mopidy.gstreamer import GStreamer
|
||||
|
||||
from tests import unittest
|
||||
from tests.backends.base import populate_playlist
|
||||
@ -16,7 +16,7 @@ class PlaybackControllerTest(object):
|
||||
|
||||
def setUp(self):
|
||||
self.backend = self.backend_class()
|
||||
self.backend.gstreamer = mock.Mock(spec=GStreamer)
|
||||
self.backend.audio = mock.Mock(spec=audio.Audio)
|
||||
self.playback = self.backend.playback
|
||||
self.current_playlist = self.backend.current_playlist
|
||||
|
||||
@ -729,7 +729,7 @@ class PlaybackControllerTest(object):
|
||||
def test_time_position_when_stopped(self):
|
||||
future = mock.Mock()
|
||||
future.get = mock.Mock(return_value=0)
|
||||
self.backend.gstreamer.get_position = mock.Mock(return_value=future)
|
||||
self.backend.audio.get_position = mock.Mock(return_value=future)
|
||||
|
||||
self.assertEqual(self.playback.time_position, 0)
|
||||
|
||||
@ -737,7 +737,7 @@ class PlaybackControllerTest(object):
|
||||
def test_time_position_when_stopped_with_playlist(self):
|
||||
future = mock.Mock()
|
||||
future.get = mock.Mock(return_value=0)
|
||||
self.backend.gstreamer.get_position = mock.Mock(return_value=future)
|
||||
self.backend.audio.get_position = mock.Mock(return_value=future)
|
||||
|
||||
self.assertEqual(self.playback.time_position, 0)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user