diff --git a/docs/api/backends.rst b/docs/api/backends.rst index 6760fc54..adb87e56 100644 --- a/docs/api/backends.rst +++ b/docs/api/backends.rst @@ -98,18 +98,17 @@ Manages the music library, e.g. searching for tracks to be added to a playlist. :members: -:mod:`mopidy.backends.gstreamer` -- GStreamer backend -===================================================== - -.. automodule:: mopidy.backends.gstreamer - :synopsis: Backend for playing music from a local music archive using the - GStreamer library - :members: - - :mod:`mopidy.backends.libspotify` -- Libspotify backend ======================================================= .. automodule:: mopidy.backends.libspotify :synopsis: Spotify backend using the libspotify library :members: + + +:mod:`mopidy.backends.local` -- Local backend +===================================================== + +.. automodule:: mopidy.backends.local + :synopsis: Backend for playing music files on local storage + :members: diff --git a/docs/changes.rst b/docs/changes.rst index 2e765176..c8e4c912 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -12,9 +12,11 @@ Another great release. **Changes** +- GStreamer is now a required dependency. - Exit early if not Python >= 2.6, < 3. - Include Sphinx scripts for building docs, pylintrc, tests and test data in the packages created by ``setup.py`` for i.e. PyPI. +- Rename :mod:`mopidy.backends.gstreamer` to :mod:`mopidy.backends.local`. - MPD frontend: - Relocate from :mod:`mopidy.mpd` to :mod:`mopidy.frontends.mpd`. diff --git a/docs/development/roadmap.rst b/docs/development/roadmap.rst index 32d52ec5..7dc284df 100644 --- a/docs/development/roadmap.rst +++ b/docs/development/roadmap.rst @@ -14,7 +14,7 @@ Version 0.1 - Read-only support for Spotify through :mod:`mopidy.backends.despotify` and/or :mod:`mopidy.backends.libspotify`. - Initial support for local file playback through - :mod:`mopidy.backends.gstreamer`. The state of local file playback will not + :mod:`mopidy.backends.local`. The state of local file playback will not block the release of 0.1. diff --git a/docs/installation/despotify.rst b/docs/installation/despotify.rst index 335efa14..6787070d 100644 --- a/docs/installation/despotify.rst +++ b/docs/installation/despotify.rst @@ -27,16 +27,22 @@ Build and install Despotify:: cd despotify/src/ sudo make install +When Despotify has been installed, continue with :ref:`spytify_installation`. + Installing Despotify on OS X ============================ -In OS X you need to have `XCode `_ -installed, and `Homebrew `_. Then, install +In OS X you need to have `XCode `_ and +`Homebrew `_ installed. Then, to install Despotify:: brew install despotify +When Despotify has been installed, continue with :ref:`spytify_installation`. + + +.. _spytify_installation: Installing spytify ================== diff --git a/docs/installation/gstreamer.rst b/docs/installation/gstreamer.rst index a5b30d0e..ef66c673 100644 --- a/docs/installation/gstreamer.rst +++ b/docs/installation/gstreamer.rst @@ -1,39 +1,48 @@ ********************** -Gstreamer installation +GStreamer installation ********************** -To use the `Gstreamer `_ backend, you first -need to install Gstreamer and its Python bindings. +To use the Mopidy, you first need to install GStreamer and its Python bindings. -Installing Gstreamer on Linux +Installing GStreamer on Linux ============================= -Gstreamer is packaged for most popular Linux distributions. If you use -Debian/Ubuntu you can install Gstreamer with Aptitude:: +GStreamer is packaged for most popular Linux distributions. If you use +Debian/Ubuntu you can install GStreamer with Aptitude:: sudo aptitude install python-gst0.10 gstreamer0.10-plugins-good \ gstreamer0.10-plugins-ugly -Installing Gstreamer on OS X +Installing GStreamer on OS X ============================ -To install Gstreamer on OS X using Homebrew:: +.. note:: + + We have created GStreamer formulas for Homebrew to make the GStreamer + installation easy for you, but our formulas has not been merged into + Homebrew's master branch yet. You should either fetch the formula files + from `Homebrew's issue #1612 + `_ yourself, or fall + back to using MacPorts. + +To install GStreamer on OS X using Homebrew:: brew install gst-python gst-plugins-good gst-plugins-ugly -To install Gstreamer on OS X using MacPorts:: +To install GStreamer on OS X using MacPorts:: sudo port install py26-gst-python gstreamer-plugins-good \ gstreamer-plugins-ugly -Setting up Mopidy to use the Gstreamer backend -============================================== +Testing the installation +======================== -Currently :mod:`mopidy.backends.despotify` is the default -backend. If you want to use :mod:`mopidy.backends.gstreamer` -instead, add the following to ``~/.mopidy/settings.py``:: +If you now run the ``gst-inspect-0.10`` command (the version number may vary), +you should see a long listing of installed plugins, ending in a summary line:: - BACKENDS = (u'mopidy.backends.gstreamer.GstreamerBackend',) + $ gst-inspect-0.10 + ... long list of installed plugins ... + Total count: 218 plugins (1 blacklist entry not shown), 1031 features diff --git a/docs/installation/index.rst b/docs/installation/index.rst index 863e465c..73ae62cb 100644 --- a/docs/installation/index.rst +++ b/docs/installation/index.rst @@ -3,47 +3,58 @@ Installation ************ Mopidy itself is a breeze to install, as it just requires a standard Python -2.6 or newer installation. The libraries we depend on to connect to the Spotify -service is far more tricky to get working for the time being. Until -installation of these libraries are either well documented by their developers, -or the libraries are packaged for various Linux distributions, we will supply -our own installation guides. +installation and the GStreamer library. The libraries we depend on to connect +to the Spotify service is far more tricky to get working for the time being. +Until installation of these libraries are either well documented by their +developers, or the libraries are packaged for various Linux distributions, we +will supply our own installation guides, as linked to below. -Dependencies -============ +Install dependencies +==================== .. toctree:: :hidden: - despotify - libspotify gstreamer + libspotify + despotify + +Make sure you got the required dependencies installed. - Python >= 2.6, < 3 +- :doc:`GStreamer ` (>= 0.10 ?) with Python bindings - Dependencies for at least one Mopidy mixer: - - AlsaMixer (Linux only) + - :mod:`mopidy.mixers.alsa` (Linux only) - pyalsaaudio >= 0.2 (Debian/Ubuntu package: python-alsaaudio) - - OsaMixer (OS X only) + - :mod:`mopidy.mixers.denon` (Linux, OS X, and Windows) - - Nothing needed. + - pyserial (Debian/Ubuntu package: python-serial) + + - :mod:`mopidy.mixers.nad` (Linux, OS X, and Windows) + + - pyserial (Debian/Ubuntu package: python-serial) + + - :mod:`mopidy.mixers.osa` (OS X only) + + - No additional dependencies. - Dependencies for at least one Mopidy backend: - - DespotifyBackend (Linux and OS X) + - :mod:`mopidy.backends.despotify` (Linux and OS X) - - see :doc:`despotify` + - :doc:`Despotify and spytify ` - - LibspotifyBackend (Linux, OS X and Windows) + - :mod:`mopidy.backends.libspotify` (Linux, OS X, and Windows) - - see :doc:`libspotify` + - :doc:`libspotify and pyspotify ` - - GstreamerBackend (Linux, OS X and Windows) + - :mod:`mopidy.backends.local` (Linux, OS X, and Windows) - - see :doc:`gstreamer` + - No additional dependencies. Install latest release @@ -84,15 +95,30 @@ For an introduction to ``git``, please visit `git-scm.com `_. -Spotify settings -================ +Settings +======== -Create a file named ``settings.py`` in the directory ``~/.mopidy/``. Enter -your Spotify Premium account's username and password into the file, like this:: +Create a file named ``settings.py`` in the directory ``~/.mopidy/``. + +If you are using a Spotify backend, enter your Spotify Premium account's +username and password into the file, like this:: SPOTIFY_USERNAME = u'myusername' SPOTIFY_PASSWORD = u'mysecret' +Currently :mod:`mopidy.backends.despotify` is the default +backend. + +If you want to use :mod:`mopidy.backends.libspotify`, copy the Spotify +application key to ``~/.mopidy/spotify_appkey.key``, and add the following +setting:: + + BACKENDS = (u'mopidy.backends.libspotify.LibspotifyBackend',) + +If you want to use :mod:`mopidy.backends.local`, add the following setting:: + + BACKENDS = (u'mopidy.backends.local.LocalBackend',) + For a full list of available settings, see :mod:`mopidy.settings`. @@ -105,8 +131,8 @@ To start Mopidy, simply open a terminal and run:: When Mopidy says ``MPD server running at [localhost]:6600`` it's ready to accept connections by any MPD client. You can find a list of tons of MPD -clients at http://mpd.wikia.com/wiki/Clients. We use Sonata, GMPC, ncmpc, and -ncmpcpp during development. The first two are GUI clients, while the last two -are terminal clients. +clients at http://mpd.wikia.com/wiki/Clients. We use GMPC and +ncmpcpp during development. The first is a GUI client, and the second is a +terminal client. To stop Mopidy, press ``CTRL+C``. diff --git a/docs/installation/libspotify.rst b/docs/installation/libspotify.rst index 8f15e479..9dc9689f 100644 --- a/docs/installation/libspotify.rst +++ b/docs/installation/libspotify.rst @@ -12,11 +12,9 @@ To use the libspotify backend you must install libspotify and This backend requires a Spotify premium account, and it requires you to get an application key from Spotify before use. -**TODO** Test and document installation on OS X. - -Installing libspotify -===================== +Installing libspotify on Linux +============================== Download and install libspotify 0.0.4 for your OS and CPU architecture from https://developer.spotify.com/en/libspotify/. @@ -29,39 +27,52 @@ For 64-bit Linux the process is as follows:: sudo make install prefix=/usr/local sudo ldconfig +When libspotify has been installed, continue with +:ref:`pyspotify_installation`. + + +Installing libspotify on OS X +============================= + +In OS X you need to have `XCode `_ and +`Homebrew `_ installed. Then, to install +libspotify:: + + brew install libspotify + +When libspotify has been installed, continue with +:ref:`pyspotify_installation`. + + +Install libspotify on Windows +============================= + +**TODO** Test and document installation on Windows. + + +.. _pyspotify_installation: Installing pyspotify ==================== Install pyspotify's dependencies. At Debian/Ubuntu systems:: - sudo aptitude install python-alsaaudio + sudo aptitude install python-dev python-alsaaudio Check out the pyspotify code, and install it:: git clone git://github.com/jodal/pyspotify.git cd pyspotify/pyspotify/ - sudo python setup.py develop - -Apply for an application key at -https://developer.spotify.com/en/libspotify/application-key, download the -binary version, and place the file at ``pyspotify/spotify_appkey.key``. + sudo python setup.py install Testing the installation ======================== +Apply for an application key at +https://developer.spotify.com/en/libspotify/application-key, download the +binary version, and place the file at ``pyspotify/spotify_appkey.key``. + Test your libspotify setup:: examples/example1.py -u USERNAME -p PASSWORD - - -Setting up Mopidy to use libspotify -=================================== - -Currently :mod:`mopidy.backends.despotify` is the default -backend. If you want to use :mod:`mopidy.backends.libspotify` -instead, copy the Spotify application key to ``~/.mopidy/spotify_appkey.key``, -and add the following to ``~/.mopidy/settings.py``:: - - BACKENDS = (u'mopidy.backends.libspotify.LibspotifyBackend',) diff --git a/mopidy/backends/libspotify/__init__.py b/mopidy/backends/libspotify/__init__.py index 0b1f2483..017a4155 100644 --- a/mopidy/backends/libspotify/__init__.py +++ b/mopidy/backends/libspotify/__init__.py @@ -148,9 +148,6 @@ class LibspotifyStoredPlaylistsController(BaseStoredPlaylistsController): def save(self, playlist): pass # TODO - def search(self, query): - pass # TODO - class LibspotifyTranslator(object): @classmethod diff --git a/mopidy/backends/gstreamer/__init__.py b/mopidy/backends/local/__init__.py similarity index 88% rename from mopidy/backends/gstreamer/__init__.py rename to mopidy/backends/local/__init__.py index 74dd8332..87d2f7c0 100644 --- a/mopidy/backends/gstreamer/__init__.py +++ b/mopidy/backends/local/__init__.py @@ -19,38 +19,36 @@ from mopidy.models import Playlist, Track, Album from mopidy import settings from mopidy.utils import parse_m3u, parse_mpd_tag_cache -logger = logging.getLogger(u'backends.gstreamer') +logger = logging.getLogger(u'mopidy.backends.local') -class GStreamerMessages(threading.Thread): +class LocalMessages(threading.Thread): def run(self): gobject.MainLoop().run() -message_thread = GStreamerMessages() +message_thread = LocalMessages() message_thread.daemon = True message_thread.start() -class GStreamerBackend(BaseBackend): +class LocalBackend(BaseBackend): """ A backend for playing music from a local music archive. - Uses the `GStreamer `_ library. - - **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-gstreamer + **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-local """ def __init__(self, *args, **kwargs): - super(GStreamerBackend, self).__init__(*args, **kwargs) + super(LocalBackend, self).__init__(*args, **kwargs) - self.library = GStreamerLibraryController(self) - self.stored_playlists = GStreamerStoredPlaylistsController(self) + self.library = LocalLibraryController(self) + self.stored_playlists = LocalStoredPlaylistsController(self) self.current_playlist = BaseCurrentPlaylistController(self) - self.playback = GStreamerPlaybackController(self) + self.playback = LocalPlaybackController(self) self.uri_handlers = [u'file://'] -class GStreamerPlaybackController(BasePlaybackController): +class LocalPlaybackController(BasePlaybackController): def __init__(self, backend): - super(GStreamerPlaybackController, self).__init__(backend) + super(LocalPlaybackController, self).__init__(backend) self._bin = gst.element_factory_make("playbin", "player") self._bus = self._bin.get_bus() @@ -64,12 +62,6 @@ class GStreamerPlaybackController(BasePlaybackController): self.stop() - def use_fake_sink(self): - """For testing. To avoid audio output during testing, and the need for - a sound card and a fully working gstreamer installation.""" - sink = gst.element_factory_make("fakesink", "fakesink") - self._bin.set_property("audio-sink", sink) - def _set_state(self, state): self._bin.set_state(state) (_, new, _) = self._bin.get_state() @@ -124,9 +116,9 @@ class GStreamerPlaybackController(BasePlaybackController): del playbin -class GStreamerStoredPlaylistsController(BaseStoredPlaylistsController): +class LocalStoredPlaylistsController(BaseStoredPlaylistsController): def __init__(self, *args): - super(GStreamerStoredPlaylistsController, self).__init__(*args) + super(LocalStoredPlaylistsController, self).__init__(*args) self._folder = os.path.expanduser(settings.LOCAL_PLAYLIST_FOLDER) self.refresh() @@ -197,9 +189,9 @@ class GStreamerStoredPlaylistsController(BaseStoredPlaylistsController): self._playlists.append(playlist) -class GStreamerLibraryController(BaseLibraryController): +class LocalLibraryController(BaseLibraryController): def __init__(self, backend): - super(GStreamerLibraryController, self).__init__(backend) + super(LocalLibraryController, self).__init__(backend) self._uri_mapping = {} self.refresh() diff --git a/tests/backends/gstreamer_test.py b/tests/backends/local_test.py similarity index 86% rename from tests/backends/gstreamer_test.py rename to tests/backends/local_test.py index 22619c80..63282bde 100644 --- a/tests/backends/gstreamer_test.py +++ b/tests/backends/local_test.py @@ -1,14 +1,14 @@ import unittest import os -# FIXME Our Windows build server does not support Gstreamer yet +# FIXME Our Windows build server does not support GStreamer yet import sys if sys.platform == 'win32': from tests import SkipTest raise SkipTest from mopidy import settings -from mopidy.backends.gstreamer import GStreamerBackend +from mopidy.backends.local import LocalBackend from mopidy.mixers.dummy import DummyMixer from mopidy.models import Playlist, Track from mopidy.utils import path_to_uri @@ -21,22 +21,22 @@ generate_song = lambda i: path_to_uri(song % i) # FIXME can be switched to generic test -class GStreamerCurrentPlaylistControllerTest(BaseCurrentPlaylistControllerTest, +class LocalCurrentPlaylistControllerTest(BaseCurrentPlaylistControllerTest, unittest.TestCase): tracks = [Track(uri=generate_song(i), length=4464) for i in range(1, 4)] - backend_class = GStreamerBackend + backend_class = LocalBackend -class GStreamerPlaybackControllerTest(BasePlaybackControllerTest, +class LocalPlaybackControllerTest(BasePlaybackControllerTest, unittest.TestCase): tracks = [Track(uri=generate_song(i), length=4464) for i in range(1, 4)] - backend_class = GStreamerBackend + backend_class = LocalBackend def setUp(self): - super(GStreamerPlaybackControllerTest, self).setUp() + super(LocalPlaybackControllerTest, self).setUp() # Two tests does not work at all when using the fake sink #self.backend.playback.use_fake_sink() @@ -64,10 +64,10 @@ class GStreamerPlaybackControllerTest(BasePlaybackControllerTest, self.assertEqual(self.playback.state, self.playback.PLAYING) -class GStreamerStoredPlaylistsControllerTest(BaseStoredPlaylistsControllerTest, +class LocalStoredPlaylistsControllerTest(BaseStoredPlaylistsControllerTest, unittest.TestCase): - backend_class = GStreamerBackend + backend_class = LocalBackend def test_created_playlist_is_persisted(self): path = os.path.join(settings.LOCAL_PLAYLIST_FOLDER, 'test.m3u') @@ -136,10 +136,10 @@ class GStreamerStoredPlaylistsControllerTest(BaseStoredPlaylistsControllerTest, raise SkipTest -class GStreamerLibraryControllerTest(BaseLibraryControllerTest, +class LocalLibraryControllerTest(BaseLibraryControllerTest, unittest.TestCase): - backend_class = GStreamerBackend + backend_class = LocalBackend def setUp(self): self.original_tag_cache = settings.LOCAL_TAG_CACHE @@ -148,13 +148,13 @@ class GStreamerLibraryControllerTest(BaseLibraryControllerTest, settings.LOCAL_TAG_CACHE = data_folder('library_tag_cache') settings.LOCAL_MUSIC_FOLDER = data_folder('') - super(GStreamerLibraryControllerTest, self).setUp() + super(LocalLibraryControllerTest, self).setUp() def tearDown(self): settings.LOCAL_TAG_CACHE = self.original_tag_cache settings.LOCAL_MUSIC_FOLDER = self.original_music_folder - super(GStreamerLibraryControllerTest, self).tearDown() + super(LocalLibraryControllerTest, self).tearDown() if __name__ == '__main__': unittest.main()