Merge branch 'master' of github.com:knutz3n/mopidy into gstreamer

This commit is contained in:
Johannes Knutsen 2010-08-12 01:48:00 +02:00
commit 940d3db490
10 changed files with 154 additions and 112 deletions

View File

@ -98,18 +98,17 @@ Manages the music library, e.g. searching for tracks to be added to a playlist.
:members: :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 :mod:`mopidy.backends.libspotify` -- Libspotify backend
======================================================= =======================================================
.. automodule:: mopidy.backends.libspotify .. automodule:: mopidy.backends.libspotify
:synopsis: Spotify backend using the libspotify library :synopsis: Spotify backend using the libspotify library
:members: :members:
:mod:`mopidy.backends.local` -- Local backend
=====================================================
.. automodule:: mopidy.backends.local
:synopsis: Backend for playing music files on local storage
:members:

View File

@ -12,9 +12,11 @@ Another great release.
**Changes** **Changes**
- GStreamer is now a required dependency.
- Exit early if not Python >= 2.6, < 3. - Exit early if not Python >= 2.6, < 3.
- Include Sphinx scripts for building docs, pylintrc, tests and test data in - Include Sphinx scripts for building docs, pylintrc, tests and test data in
the packages created by ``setup.py`` for i.e. PyPI. the packages created by ``setup.py`` for i.e. PyPI.
- Rename :mod:`mopidy.backends.gstreamer` to :mod:`mopidy.backends.local`.
- MPD frontend: - MPD frontend:
- Relocate from :mod:`mopidy.mpd` to :mod:`mopidy.frontends.mpd`. - Relocate from :mod:`mopidy.mpd` to :mod:`mopidy.frontends.mpd`.

View File

@ -14,7 +14,7 @@ Version 0.1
- Read-only support for Spotify through :mod:`mopidy.backends.despotify` and/or - Read-only support for Spotify through :mod:`mopidy.backends.despotify` and/or
:mod:`mopidy.backends.libspotify`. :mod:`mopidy.backends.libspotify`.
- Initial support for local file playback through - 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. block the release of 0.1.

View File

@ -27,16 +27,22 @@ Build and install Despotify::
cd despotify/src/ cd despotify/src/
sudo make install sudo make install
When Despotify has been installed, continue with :ref:`spytify_installation`.
Installing Despotify on OS X Installing Despotify on OS X
============================ ============================
In OS X you need to have `XCode <http://developer.apple.com/tools/xcode/>`_ In OS X you need to have `XCode <http://developer.apple.com/tools/xcode/>`_ and
installed, and `Homebrew <http://mxcl.github.com/homebrew/>`_. Then, install `Homebrew <http://mxcl.github.com/homebrew/>`_ installed. Then, to install
Despotify:: Despotify::
brew install despotify brew install despotify
When Despotify has been installed, continue with :ref:`spytify_installation`.
.. _spytify_installation:
Installing spytify Installing spytify
================== ==================

View File

@ -1,39 +1,48 @@
********************** **********************
Gstreamer installation GStreamer installation
********************** **********************
To use the `Gstreamer <http://gstreamer.freedesktop.org/>`_ backend, you first To use the Mopidy, you first need to install GStreamer and its Python bindings.
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 GStreamer is packaged for most popular Linux distributions. If you use
Debian/Ubuntu you can install Gstreamer with Aptitude:: Debian/Ubuntu you can install GStreamer with Aptitude::
sudo aptitude install python-gst0.10 gstreamer0.10-plugins-good \ sudo aptitude install python-gst0.10 gstreamer0.10-plugins-good \
gstreamer0.10-plugins-ugly 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
<http://github.com/mxcl/homebrew/issues/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 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 \ sudo port install py26-gst-python gstreamer-plugins-good \
gstreamer-plugins-ugly gstreamer-plugins-ugly
Setting up Mopidy to use the Gstreamer backend Testing the installation
============================================== ========================
Currently :mod:`mopidy.backends.despotify` is the default If you now run the ``gst-inspect-0.10`` command (the version number may vary),
backend. If you want to use :mod:`mopidy.backends.gstreamer` you should see a long listing of installed plugins, ending in a summary line::
instead, add the following to ``~/.mopidy/settings.py``::
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

View File

@ -3,47 +3,58 @@ Installation
************ ************
Mopidy itself is a breeze to install, as it just requires a standard Python 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 installation and the GStreamer library. The libraries we depend on to connect
service is far more tricky to get working for the time being. Until to the Spotify service is far more tricky to get working for the time being.
installation of these libraries are either well documented by their developers, Until installation of these libraries are either well documented by their
or the libraries are packaged for various Linux distributions, we will supply developers, or the libraries are packaged for various Linux distributions, we
our own installation guides. will supply our own installation guides, as linked to below.
Dependencies Install dependencies
============ ====================
.. toctree:: .. toctree::
:hidden: :hidden:
despotify
libspotify
gstreamer gstreamer
libspotify
despotify
Make sure you got the required dependencies installed.
- Python >= 2.6, < 3 - Python >= 2.6, < 3
- :doc:`GStreamer <gstreamer>` (>= 0.10 ?) with Python bindings
- Dependencies for at least one Mopidy mixer: - Dependencies for at least one Mopidy mixer:
- AlsaMixer (Linux only) - :mod:`mopidy.mixers.alsa` (Linux only)
- pyalsaaudio >= 0.2 (Debian/Ubuntu package: python-alsaaudio) - 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: - 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 <despotify>`
- LibspotifyBackend (Linux, OS X and Windows) - :mod:`mopidy.backends.libspotify` (Linux, OS X, and Windows)
- see :doc:`libspotify` - :doc:`libspotify and pyspotify <libspotify>`
- GstreamerBackend (Linux, OS X and Windows) - :mod:`mopidy.backends.local` (Linux, OS X, and Windows)
- see :doc:`gstreamer` - No additional dependencies.
Install latest release Install latest release
@ -84,15 +95,30 @@ For an introduction to ``git``, please visit `git-scm.com
<http://git-scm.com/>`_. <http://git-scm.com/>`_.
Spotify settings Settings
================ ========
Create a file named ``settings.py`` in the directory ``~/.mopidy/``. Enter Create a file named ``settings.py`` in the directory ``~/.mopidy/``.
your Spotify Premium account's username and password into the file, like this::
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_USERNAME = u'myusername'
SPOTIFY_PASSWORD = u'mysecret' 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`. 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 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 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 clients at http://mpd.wikia.com/wiki/Clients. We use GMPC and
ncmpcpp during development. The first two are GUI clients, while the last two ncmpcpp during development. The first is a GUI client, and the second is a
are terminal clients. terminal client.
To stop Mopidy, press ``CTRL+C``. To stop Mopidy, press ``CTRL+C``.

View File

@ -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 This backend requires a Spotify premium account, and it requires you to get
an application key from Spotify before use. an application key from Spotify before use.
**TODO** Test and document installation on OS X.
Installing libspotify on Linux
Installing libspotify ==============================
=====================
Download and install libspotify 0.0.4 for your OS and CPU architecture from Download and install libspotify 0.0.4 for your OS and CPU architecture from
https://developer.spotify.com/en/libspotify/. 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 make install prefix=/usr/local
sudo ldconfig 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 <http://developer.apple.com/tools/xcode/>`_ and
`Homebrew <http://mxcl.github.com/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 Installing pyspotify
==================== ====================
Install pyspotify's dependencies. At Debian/Ubuntu systems:: 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:: Check out the pyspotify code, and install it::
git clone git://github.com/jodal/pyspotify.git git clone git://github.com/jodal/pyspotify.git
cd pyspotify/pyspotify/ cd pyspotify/pyspotify/
sudo python setup.py develop sudo python setup.py install
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``.
Testing the installation 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:: Test your libspotify setup::
examples/example1.py -u USERNAME -p PASSWORD 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',)

View File

@ -148,9 +148,6 @@ class LibspotifyStoredPlaylistsController(BaseStoredPlaylistsController):
def save(self, playlist): def save(self, playlist):
pass # TODO pass # TODO
def search(self, query):
pass # TODO
class LibspotifyTranslator(object): class LibspotifyTranslator(object):
@classmethod @classmethod

View File

@ -19,38 +19,36 @@ from mopidy.models import Playlist, Track, Album
from mopidy import settings from mopidy import settings
from mopidy.utils import parse_m3u, parse_mpd_tag_cache 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): def run(self):
gobject.MainLoop().run() gobject.MainLoop().run()
message_thread = GStreamerMessages() message_thread = LocalMessages()
message_thread.daemon = True message_thread.daemon = True
message_thread.start() message_thread.start()
class GStreamerBackend(BaseBackend): class LocalBackend(BaseBackend):
""" """
A backend for playing music from a local music archive. A backend for playing music from a local music archive.
Uses the `GStreamer <http://gstreamer.freedesktop.org/>`_ library. **Issues:** http://github.com/jodal/mopidy/issues/labels/backend-local
**Issues:** http://github.com/jodal/mopidy/issues/labels/backend-gstreamer
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(GStreamerBackend, self).__init__(*args, **kwargs) super(LocalBackend, self).__init__(*args, **kwargs)
self.library = GStreamerLibraryController(self) self.library = LocalLibraryController(self)
self.stored_playlists = GStreamerStoredPlaylistsController(self) self.stored_playlists = LocalStoredPlaylistsController(self)
self.current_playlist = BaseCurrentPlaylistController(self) self.current_playlist = BaseCurrentPlaylistController(self)
self.playback = GStreamerPlaybackController(self) self.playback = LocalPlaybackController(self)
self.uri_handlers = [u'file://'] self.uri_handlers = [u'file://']
class GStreamerPlaybackController(BasePlaybackController): class LocalPlaybackController(BasePlaybackController):
def __init__(self, backend): def __init__(self, backend):
super(GStreamerPlaybackController, self).__init__(backend) super(LocalPlaybackController, self).__init__(backend)
self._bin = gst.element_factory_make("playbin", "player") self._bin = gst.element_factory_make("playbin", "player")
self._bus = self._bin.get_bus() self._bus = self._bin.get_bus()
@ -64,12 +62,6 @@ class GStreamerPlaybackController(BasePlaybackController):
self.stop() 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): def _set_state(self, state):
self._bin.set_state(state) self._bin.set_state(state)
(_, new, _) = self._bin.get_state() (_, new, _) = self._bin.get_state()
@ -124,9 +116,9 @@ class GStreamerPlaybackController(BasePlaybackController):
del playbin del playbin
class GStreamerStoredPlaylistsController(BaseStoredPlaylistsController): class LocalStoredPlaylistsController(BaseStoredPlaylistsController):
def __init__(self, *args): def __init__(self, *args):
super(GStreamerStoredPlaylistsController, self).__init__(*args) super(LocalStoredPlaylistsController, self).__init__(*args)
self._folder = os.path.expanduser(settings.LOCAL_PLAYLIST_FOLDER) self._folder = os.path.expanduser(settings.LOCAL_PLAYLIST_FOLDER)
self.refresh() self.refresh()
@ -197,9 +189,9 @@ class GStreamerStoredPlaylistsController(BaseStoredPlaylistsController):
self._playlists.append(playlist) self._playlists.append(playlist)
class GStreamerLibraryController(BaseLibraryController): class LocalLibraryController(BaseLibraryController):
def __init__(self, backend): def __init__(self, backend):
super(GStreamerLibraryController, self).__init__(backend) super(LocalLibraryController, self).__init__(backend)
self._uri_mapping = {} self._uri_mapping = {}
self.refresh() self.refresh()

View File

@ -1,14 +1,14 @@
import unittest import unittest
import os import os
# FIXME Our Windows build server does not support Gstreamer yet # FIXME Our Windows build server does not support GStreamer yet
import sys import sys
if sys.platform == 'win32': if sys.platform == 'win32':
from tests import SkipTest from tests import SkipTest
raise SkipTest raise SkipTest
from mopidy import settings from mopidy import settings
from mopidy.backends.gstreamer import GStreamerBackend from mopidy.backends.local import LocalBackend
from mopidy.mixers.dummy import DummyMixer from mopidy.mixers.dummy import DummyMixer
from mopidy.models import Playlist, Track from mopidy.models import Playlist, Track
from mopidy.utils import path_to_uri 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 # FIXME can be switched to generic test
class GStreamerCurrentPlaylistControllerTest(BaseCurrentPlaylistControllerTest, class LocalCurrentPlaylistControllerTest(BaseCurrentPlaylistControllerTest,
unittest.TestCase): unittest.TestCase):
tracks = [Track(uri=generate_song(i), length=4464) tracks = [Track(uri=generate_song(i), length=4464)
for i in range(1, 4)] for i in range(1, 4)]
backend_class = GStreamerBackend backend_class = LocalBackend
class GStreamerPlaybackControllerTest(BasePlaybackControllerTest, class LocalPlaybackControllerTest(BasePlaybackControllerTest,
unittest.TestCase): unittest.TestCase):
tracks = [Track(uri=generate_song(i), length=4464) tracks = [Track(uri=generate_song(i), length=4464)
for i in range(1, 4)] for i in range(1, 4)]
backend_class = GStreamerBackend backend_class = LocalBackend
def setUp(self): def setUp(self):
super(GStreamerPlaybackControllerTest, self).setUp() super(LocalPlaybackControllerTest, self).setUp()
# Two tests does not work at all when using the fake sink # Two tests does not work at all when using the fake sink
#self.backend.playback.use_fake_sink() #self.backend.playback.use_fake_sink()
@ -64,10 +64,10 @@ class GStreamerPlaybackControllerTest(BasePlaybackControllerTest,
self.assertEqual(self.playback.state, self.playback.PLAYING) self.assertEqual(self.playback.state, self.playback.PLAYING)
class GStreamerStoredPlaylistsControllerTest(BaseStoredPlaylistsControllerTest, class LocalStoredPlaylistsControllerTest(BaseStoredPlaylistsControllerTest,
unittest.TestCase): unittest.TestCase):
backend_class = GStreamerBackend backend_class = LocalBackend
def test_created_playlist_is_persisted(self): def test_created_playlist_is_persisted(self):
path = os.path.join(settings.LOCAL_PLAYLIST_FOLDER, 'test.m3u') path = os.path.join(settings.LOCAL_PLAYLIST_FOLDER, 'test.m3u')
@ -136,10 +136,10 @@ class GStreamerStoredPlaylistsControllerTest(BaseStoredPlaylistsControllerTest,
raise SkipTest raise SkipTest
class GStreamerLibraryControllerTest(BaseLibraryControllerTest, class LocalLibraryControllerTest(BaseLibraryControllerTest,
unittest.TestCase): unittest.TestCase):
backend_class = GStreamerBackend backend_class = LocalBackend
def setUp(self): def setUp(self):
self.original_tag_cache = settings.LOCAL_TAG_CACHE 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_TAG_CACHE = data_folder('library_tag_cache')
settings.LOCAL_MUSIC_FOLDER = data_folder('') settings.LOCAL_MUSIC_FOLDER = data_folder('')
super(GStreamerLibraryControllerTest, self).setUp() super(LocalLibraryControllerTest, self).setUp()
def tearDown(self): def tearDown(self):
settings.LOCAL_TAG_CACHE = self.original_tag_cache settings.LOCAL_TAG_CACHE = self.original_tag_cache
settings.LOCAL_MUSIC_FOLDER = self.original_music_folder settings.LOCAL_MUSIC_FOLDER = self.original_music_folder
super(GStreamerLibraryControllerTest, self).tearDown() super(LocalLibraryControllerTest, self).tearDown()
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()