Giter Club home page Giter Club logo

mopidy-spotify's Introduction

Mopidy

Mopidy is an extensible music server written in Python.

Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. You edit the playlist from any phone, tablet, or computer using a variety of MPD and web clients.

Stream music from the cloud

Vanilla Mopidy only plays music from files and radio streams. Through extensions, Mopidy can play music from cloud services like Spotify, SoundCloud, and Google Play Music. With Mopidy's extension support, backends for new music sources can be easily added.

Mopidy is just a server

Mopidy is a Python application that runs in a terminal or in the background on Linux computers or Macs that have network connectivity and audio output. Out of the box, Mopidy is an HTTP server. If you install the Mopidy-MPD extension, it becomes an MPD server too. Many additional frontends for controlling Mopidy are available as extensions.

Pick your favorite client

You and the people around you can all connect their favorite MPD or web client to the Mopidy server to search for music and manage the playlist together. With a browser or MPD client, which is available for all popular operating systems, you can control the music from any phone, tablet, or computer.

Mopidy on Raspberry Pi

The Raspberry Pi is a popular device to run Mopidy on, either using Raspbian, Ubuntu, or Arch Linux. Pimoroni recommends Mopidy for use with their Pirate Audio audio gear for Raspberry Pi. Mopidy is also a significant building block in the Pi Musicbox integrated audio jukebox system for Raspberry Pi.

Mopidy is hackable

Mopidy's extension support and Python, JSON-RPC, and JavaScript APIs make Mopidy a perfect base for your projects. In one hack, a Raspberry Pi was embedded in an old cassette player. The buttons and volume control are wired up with GPIO on the Raspberry Pi, and are used to control playback through a custom Mopidy extension. The cassettes have NFC tags used to select playlists from Spotify.

Getting started

To get started with Mopidy, begin by reading the installation docs.

Contributing

Begin by reading the contributing section of our documentation. If you are a developer, please also read Development environment and/or Extension development. We welcome all kinds of help with bug fixing, testing, documentation, and supporting other users.

Project resources

Latest PyPI version CI build status Read the Docs build status Test coverage Chat on Zulip

mopidy-spotify's People

Contributors

adamcik avatar arybczak avatar beaverking1212 avatar carlosdagos avatar chigley avatar djmattyg007 avatar girst avatar jodal avatar kingosticks avatar l3viathan avatar simeg avatar telnet23 avatar trygveaa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mopidy-spotify's Issues

Max recursion depth reached and segfault if searching right after startup

To reproduce:

  1. Start Mopidy develop with Mopidy-Spotify develop
  2. Make a search as soon as possible

Variations:

  • I've managed to reproduce this several times. The crash is not in the search code path, as I sometime get the search result before the crash happens.
  • If I wait a few seconds extra after startup before doing the search, nothing crashes.

Crash output:

DEBUG    2015-03-24 16:39:59,771 [30542:SpotifyEventLoop] spotify.playlist
  Playlist update in progress
DEBUG    2015-03-24 16:39:59,771 [30542:SpotifyEventLoop] spotify.session
  libspotify log message: 15:39:59.771 W [playlist.cpp:45] Adding observer while updating
DEBUG    2015-03-24 16:39:59,772 [30542:SpotifyEventLoop] spotify.playlist
  Playlist update in progress
DEBUG    2015-03-24 16:39:59,772 [30542:SpotifyEventLoop] spotify.session
  libspotify log message: 15:39:59.772 W [playlist.cpp:45] Adding observer while updating
DEBUG    2015-03-24 16:39:59,772 [30542:SpotifyEventLoop] spotify.playlist
  Playlist update in progress
DEBUG    2015-03-24 16:39:59,773 [30542:SpotifyEventLoop] spotify.session
  libspotify log message: 15:39:59.773 W [playlist.cpp:45] Adding observer while updating
DEBUG    2015-03-24 16:39:59,773 [30542:SpotifyEventLoop] spotify.playlist
  Playlist update in progress
DEBUG    2015-03-24 16:39:59,773 [30542:SpotifyEventLoop] spotify.session
  libspotify log message: 15:39:59.773 W [playlist.cpp:45] Adding observer while updating
DEBUG    2015-03-24 16:39:59,774 [30542:SpotifyEventLoop] spotify.playlist
  Playlist update in progress
From callback <function log_message at 0x7f67769f68c0>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/session.py", line 1010, in log_message
    logger.debug('libspotify log message: %s', data)
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib/python2.7/logging/__init__.py", line 1252, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/lib/python2.7/logging/__init__.py", line 269, in __init__
    if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
RuntimeError: maximum recursion depth exceeded
Traceback (most recent call last):
  File "/home/jodal/dev/mopidy/mopidy/utils/log.py", line 166, in emit
From callback <function playlist_update_in_progress at 0x7f67769b1230>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/playlist.py", line 643, in playlist_update_in_progress
    logger.debug('Playlist update in progress')
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1279, in _log
    self.handle(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 1289, in handle
    self.callHandlers(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 1329, in callHandlers
    hdlr.handle(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 757, in handle
    self.emit(record)
  File "/home/jodal/dev/mopidy/mopidy/utils/log.py", line 171, in emit
    self.handleError(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 810, in handleError
    None, sys.stderr)
  File "/usr/lib/python2.7/traceback.py", line 125, in print_exception
    print_tb(tb, limit, file)
  File "/usr/lib/python2.7/traceback.py", line 69, in print_tb
    line = linecache.getline(filename, lineno, f.f_globals)
  File "/home/jodal/dev/virtualenvs/mopidy/lib/python2.7/linecache.py", line 14, in getline
    lines = getlines(filename, module_globals)
RuntimeError: maximum recursion depth exceeded
From callback <function log_message at 0x7f67769f68c0>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/session.py", line 1010, in log_message
    logger.debug('libspotify log message: %s', data)
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib/python2.7/logging/__init__.py", line 1252, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/lib/python2.7/logging/__init__.py", line 269, in __init__
    if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
  File "/home/jodal/dev/virtualenvs/mopidy/lib/python2.7/abc.py", line 132, in __instancecheck__
    if subclass is not None and subclass in cls._abc_cache:
  File "/home/jodal/dev/virtualenvs/mopidy/lib/python2.7/_weakrefset.py", line 72, in __contains__
    wr = ref(item)
RuntimeError: maximum recursion depth exceeded
DEBUG    2015-03-24 16:39:59,779 [30542:SpotifyEventLoop] spotify.playlist
  Playlist update in progress
From callback <function log_message at 0x7f67769f68c0>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/session.py", line 1010, in log_message
    logger.debug('libspotify log message: %s', data)
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib/python2.7/logging/__init__.py", line 1252, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
RuntimeError: maximum recursion depth exceeded while calling a Python object
From callback <function playlist_update_in_progress at 0x7f67769b1230>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/playlist.py", line 643, in playlist_update_in_progress
    logger.debug('Playlist update in progress')
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib/python2.7/logging/__init__.py", line 1252, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
RuntimeError: maximum recursion depth exceeded while calling a Python object
From callback <function log_message at 0x7f67769f68c0>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/session.py", line 1010, in log_message
    logger.debug('libspotify log message: %s', data)
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib/python2.7/logging/__init__.py", line 1252, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/lib/python2.7/logging/__init__.py", line 269, in __init__
    if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
RuntimeError: maximum recursion depth exceeded while calling a Python object
From callback <function playlist_update_in_progress at 0x7f67769b1230>:
Traceback (most recent call last):
  File "/home/jodal/dev/pyspotify2/spotify/playlist.py", line 643, in playlist_update_in_progress
    logger.debug('Playlist update in progress')
  File "/usr/lib/python2.7/logging/__init__.py", line 1148, in debug
    self._log(DEBUG, msg, args, **kwargs)
  File "/usr/lib/python2.7/logging/__init__.py", line 1278, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib/python2.7/logging/__init__.py", line 1252, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/lib/python2.7/logging/__init__.py", line 273, in __init__
    self.levelname = getLevelName(level)
  File "/usr/lib/python2.7/logging/__init__.py", line 168, in getLevelName
    return _levelNames.get(level, ("Level %s" % level))
RuntimeError: maximum recursion depth exceeded while getting the str of an object
[1]    30542 segmentation fault (core dumped)  mopidy -o soundcloud/enabled=false -o youtube/enabled=false -o  -o

Full debug log: https://gist.github.com/jodal/e1a3d64d9d34eaafa2e8

Searching for exact matches

When using MPD's find command the results are supposed to be an exact match of the query but due to limitations in Spotify's searching you actually get partial matches more akin to SQL's LIKE operator.

e.g. Searching for "Opposite of December" gives you results from two albums:

  • "Opposite of December"
  • "The Opposite Of December / Tear From The Red"

This is pretty annoying when you browse an artist's album in MPD clients and get wrong and duplicate tracks entries.

I know of no way to force exact matching in Spotify queries so maybe we could further filter the results returned to us in find_exact()? Similarly, we could also filter by the fields that Spotify queries don't support i.e. track_no. The motivation for this being that much larger amounts of data are returned to the client than are necessary and it just slows things down. This also combines with the first problem and you can get the full track info for loads of unwanted tracks!

Mopidy pauses playback of local tracks when it loses connection to Spotify.

I have a spotty internet connection at my house and Mopidy loses it's connection to Spotify quite frequently. (It gives this error: "ERROR Spotify connection error: Can not connect to Spotify")

Each time this happens, it pauses the song that I'm listening to, even if it's from my local library.

If this is a problem with Mopidy rather than Mopidy-Spotify, let me know and I'll create an issue there instead.

Spotify stutters on Pi

On the Raspberry Pi, including Pi MusicBox, playing music from Spotify sometimes stutters at the start of a track. Not always, but it does. I can see a small short burst of CPU usage when it happens. It does not happen with all files.
Sound does not stutter in the same configuration on any other extension, so this must have something to do with mopidy-spotify.
I made it stutter less by using a gstreamer cache for the output in the ini file:
output = alsasink buffer-time=200000 latency-time=10000
and setting mopidy to a high nice value (like 15 or 19)

Error: Ignoring unknown config section: spotify

Sorry, I might be missing out something very obvious here, but can't figure this out.
I think I've installed mopidy and mopidy-spotify correctly, and I've added

[spotify]
username = myusername
password = mypassword

to the config file, but still, even after uninstalling and reinstalling, I keep getting this message (when running mopidy -vv):

DEBUG 2015-04-18 19:56:07,838 [27901:MainThread] mopidy.config
Ignoring unknown config section: spotify

Which I guess it's what it's preventing the songs I select through mopify to actually load and play (there's no sign of any Spotify backend being started).

Any suggestion?

Support for the new "Your Music" container

Spotify upgraded the starring system to a more music-collection centric "Your Music" system. Giving us the ability to think more in terms of albums/artists. Starring will still be available.
I was wondering if there are any plans on supporting these "playlists" in the Spotify virtual filesystem.

Expose option for toggling Volume Normalization in mopidy-spotify

Hi, a feature request with urgency "nice to have, but in no way critical":

It would be really awesome to see some sort of configuration option for toggling audio normalization functionality - sometimes it is nice to not have tracks normalized :-)

Thanks!

(ref. IRC: option isn't exposed in pyspotify 1.x, however it is exposed in pyspotify 2.x).

Use new Extension.get_cache_dir()

  • Require Mopidy >= 1.1
  • Deprecate spotify/settings_dir, use Extension.get_config_dir()
  • Deprecate spotify/cache_dir, use Extension.get_cache_dir()
  • Add spotify/allow_cache config defaulting to true, to make it possible to disable caching

Spotify browsing gives "No tracks found..."

I go in Browsing -> Spotify Browse and select, for instance, Featured playlists. I click on any of them and all I get is "No tracks found..."
The same for top lists, "Genres & Moods" and so on.

1.x: Random segfault when searching on spotify

"Moving" mopidy/mopidy#1126 which @matztam filed, and @bootl0g confirmed.

When searching spotify for songs, mopidy occasionally crashes with a segmentation fault. This is not reproducible by some special search query or what ever, it just happens randomly.

Environment:
mopidy 1.0.0
mopidy-spotify 1.3.0
pyspotify 1.12
libspotify.so.12.1.51
Ubuntu 14.04 (3.13.0-48 x86_64)
python 2.7.6

Core dump:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd273b700 (LWP 14821)]
0x0000000000000000 in ?? ()
(gdb) where
#0  0x0000000000000000 in ?? ()
#1  0x00007fffee173a99 in sp_album_add_ref () from /usr/lib/libspotify.so.12
#2  0x00007fffee490660 in Album_FromSpotify (album=0x7fffc4000078, add_ref=add_ref@entry=1 '\001') at src/album.c:22
#3  0x00007fffee491225 in Results_albums (self=<spotify.Results at remote 0x7fff8c522690>) at src/search.c:82
#4  0x000000000052d432 in call_function (oparg=<optimized out>, pp_stack=0x7fffd2739a70) at ../Python/ceval.c:4004
#5  PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fffc85cebb0, for file /usr/local/lib/python2.7/dist-packages/mopidy_spotify/library.py, line 243, in callback (results=<spotify.Results at remote 0x7fff8c522690>, userdata=None), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#6  0x000000000056d0aa in PyEval_EvalCodeEx (closure=<optimized out>, defcount=<optimized out>, defs=0x7fff65fb7c28, kwcount=<optimized out>, kws=<optimized out>, argcount=-933434448, 
    args=<optimized out>, locals=0x0, globals=<optimized out>, co=<optimized out>) at ../Python/ceval.c:3252
#7  function_call (func=<optimized out>, arg=<optimized out>, kw=<optimized out>) at ../Objects/funcobject.c:526
#8  0x0000000000502be0 in PyObject_Call (kw=0x0, arg=(<spotify.Results at remote 0x7fff8c522690>, None), func=<function at remote 0x7fff65f96140>) at ../Objects/abstract.c:2529
#9  call_function_tail (args=(<spotify.Results at remote 0x7fff8c522690>, None), callable=<function at remote 0x7fff65f96140>) at ../Objects/abstract.c:2561
#10 PyObject_CallFunction (callable=<function at remote 0x7fff65f96140>, format=format@entry=0x7fffee495628 "NO") at ../Objects/abstract.c:2585
#11 0x00007fffee48e61c in Session_search_complete (search=0x7fffc409fdd0, data=0x7fffc409cea0) at src/session.c:199
#12 0x00007fffee17a7c7 in ?? () from /usr/lib/libspotify.so.12
#13 0x00007fffee0e2cbc in ?? () from /usr/lib/libspotify.so.12
#14 0x00007fffee0a4c8b in ?? () from /usr/lib/libspotify.so.12
#15 0x00007fffee1795b3 in sp_session_process_events () from /usr/lib/libspotify.so.12
#16 0x00007fffee48ed5f in Session_process_events (self=<spotify.Session at remote 0x7fffe4dde618>) at src/session.c:180
#17 0x000000000052d432 in call_function (oparg=<optimized out>, pp_stack=0x7fffd273a3d0) at ../Python/ceval.c:4004
#18 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fffd16fba28, for file /usr/local/lib/python2.7/dist-packages/spotify/manager/session.py, line 101, in loop (self=<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/...(truncated), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#19 0x000000000052cf32 in fast_function (nk=<optimized out>, na=<optimized out>, n=2, pp_stack=0x7fffd273a510, func=<function at remote 0x7fffee6cad70>) at ../Python/ceval.c:4106
#20 call_function (oparg=<optimized out>, pp_stack=0x7fffd273a510) at ../Python/ceval.c:4041
#21 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fffedfb3430, for file /usr/local/lib/python2.7/dist-packages/spotify/manager/session.py, line 81, in connect (self=<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xe...(truncated), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#22 0x000000000052cf32 in fast_function (nk=<optimized out>, na=<optimized out>, n=1, pp_stack=0x7fffd273a650, func=<function at remote 0x7fffee6cacf8>) at ../Python/ceval.c:4106
#23 call_function (oparg=<optimized out>, pp_stack=0x7fffd273a650) at ../Python/ceval.c:4041
#24 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fffe52cf770, for file /usr/local/lib/python2.7/dist-packages/mopidy_spotify/session_manager.py, line 67, in run_inside_try (self=<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x9...(truncated), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#25 0x000000000055c594 in PyEval_EvalCodeEx (co=0x7fffee6bf7b0, globals=<optimized out>, locals=locals@entry=0x0, args=<optimized out>, argcount=argcount@entry=1, kws=<optimized out>, 
    kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3252
#26 0x000000000052ca8d in fast_function (nk=<optimized out>, na=1, n=<optimized out>, pp_stack=0x7fffd273a830, func=<function at remote 0x7fffee6daa28>) at ../Python/ceval.c:4116
#27 call_function (oparg=<optimized out>, pp_stack=0x7fffd273a830) at ../Python/ceval.c:4041
#28 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x2ea3c80, for file /usr/local/lib/python2.7/dist-packages/mopidy/utils/process.py, line 64, in run (self=<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method re---Type <return> to continue, or q <return> to quit---
lease of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/\xa2\xee\x...(truncated), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#29 0x000000000055c594 in PyEval_EvalCodeEx (co=0x7fffefe0f830, globals=<optimized out>, locals=locals@entry=0x0, args=<optimized out>, argcount=argcount@entry=1, kws=<optimized out>, 
    kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:3252
#30 0x000000000052ca8d in fast_function (nk=<optimized out>, na=1, n=<optimized out>, pp_stack=0x7fffd273aa10, func=<function at remote 0x7fffefe1b500>) at ../Python/ceval.c:4116
#31 call_function (oparg=<optimized out>, pp_stack=0x7fffd273aa10) at ../Python/ceval.c:4041
#32 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fffc8000910, for file /usr/lib/python2.7/threading.py, line 810, in __bootstrap_inner (self=<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/\xa2\xee\xf1!\xf7\xcc...(truncated), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#33 0x000000000052cf32 in fast_function (nk=<optimized out>, na=<optimized out>, n=1, pp_stack=0x7fffd273ab50, func=<function at remote 0x7ffff7e41488>) at ../Python/ceval.c:4106
#34 call_function (oparg=<optimized out>, pp_stack=0x7fffd273ab50) at ../Python/ceval.c:4041
#35 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fffe5320c90, for file /usr/lib/python2.7/threading.py, line 783, in __bootstrap (self=<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/\xa2\xee\xf1!\xf7\xcc\xf3\x...(truncated), throwflag=throwflag@entry=0) at ../Python/ceval.c:2666
#36 0x000000000056d0aa in PyEval_EvalCodeEx (closure=<optimized out>, defcount=<optimized out>, defs=0x0, kwcount=<optimized out>, kws=<optimized out>, argcount=-449704816, 
    args=<optimized out>, locals=0x0, globals=<optimized out>, co=<optimized out>) at ../Python/ceval.c:3252
#37 function_call (func=func@entry=<function at remote 0x7ffff7e41398>, 
    arg=arg@entry=(<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/\xa2\xee\xf1!\xf7\xcc\xf3\xc9u\x90\x15?\xbb\xaa\xc2\xc9d9\x07\xd8W\x0f\t(qG\x04H\xf0T\x8eM\xd3+\xc3\xa3\xf8+"\xc1\xc2\x86...(truncated), kw=kw@entry=0x0) at ../Objects/funcobject.c:526
#38 0x00000000004d9854 in PyObject_Call (kw=0x0, 
    arg=(<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/\xa2\xee\xf1!\xf7\xcc\xf3\xc9u\x90\x15?\xbb\xaa\xc2\xc9d9\x07\xd8W\x0f\t(qG\x04H\xf0T\x8eM\xd3+\xc3\xa3\xf8+"\xc1\xc2\x86...(truncated), func=<function at remote 0x7ffff7e41398>)
    at ../Objects/abstract.c:2529
#39 instancemethod_call.8802 (func=<function at remote 0x7ffff7e41398>, func@entry=<instancemethod at remote 0x7fffef5c2500>, 
    arg=(<SpotifySessionManager(remember_me=False, _Thread__ident=140736724186880, buffer_timestamp=40402720830L, login_blob='', _Thread__started=<_Event(_Verbose__verbose=False, _Event__flag=True, _Event__cond=<_Condition(_Verbose__verbose=False, _Condition__lock=<thread.lock at remote 0x7fffe4c11e10>, acquire=<built-in method acquire of thread.lock object at remote 0x7fffe4c11e10>, _Condition__waiters=[], release=<built-in method release of thread.lock object at remote 0x7fffe4c11e10>) at remote 0x7fffd304b2d0>) at remote 0x7fffd304b290>, proxy_password=None, application_key='\x01\xcf\x89\x0f\xde\x9f\xd6!P\x16\x8e\xd43\x7fs\x82\xc1R\xc7N\x85G \x8dS\xb9"^=\xc5+\t\xe9\xcfd/d\x85\xcf\xc3K~\xeb8\x06(%n\xd1\xd5\xfeG\xf7~L\x90\x0e\x9f\xb8\x0b\x98\x1a\x14.$\xbf\xddqsm\xc5\xbd\xf3\xb2\x81\x9e\x10y|3\x13\xac0\x03\x97>t\x87\xb6\x95|\xc1\xead\x89\xe2\r\xde\xa2\xda\xb7\xbc\xf9+\xbb\xdf\xb2\x974\xce\xbby\xec/\xa2\xee\xf1!\xf7\xcc\xf3\xc9u\x90\x15?\xbb\xaa\xc2\xc9d9\x07\xd8W\x0f\t(qG\x04H\xf0T\x8eM\xd3+\xc3\xa3\xf8+"\xc1\xc2\x86...(truncated), arg@entry=(), kw=0x0) at ../Objects/classobject.c:2602
#40 0x00000000004da20b in PyObject_Call (kw=<optimized out>, arg=(), func=<instancemethod at remote 0x7fffef5c2500>) at ../Objects/abstract.c:2529
#41 PyEval_CallObjectWithKeywords (func=<instancemethod at remote 0x7fffef5c2500>, arg=(), kw=<optimized out>) at ../Python/ceval.c:3889
#42 0x00000000005872b2 in t_bootstrap.71638 (boot_raw=0x7fffc4000e40) at ../Modules/threadmodule.c:614
#43 0x00007ffff7bc4182 in start_thread (arg=0x7fffd273b700) at pthread_create.c:312
#44 0x00007ffff78f147d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

pip install fails under Arch

The installation via pip on Arch Linux (at least on armv6) fails because it depends on pkg-config, which is not necessarily installed.

Support to not load all playlist, but only those in a folder (or a specific playlist)

I have too many playlists on my Spotify account and would like an option to select which playlists I want to show up on my Modipy library.

Maybe a config setting that, if present, would tell modipy-spotify to load only that specific playlist as the library (or some playlists inside a folder).

This way it's easier to keep the library organized.

Wrong value returned in get_distinct

I'm getting big blocks of errors from Mopidy as it seems like calls to get_distinct are failing to return proper data, leaving a None value around the middle.

First what I assume to be a get_distinct('artist')

ERROR    SpotifyBackend backend returned bad data: Expected a list of unicode, not set([u'MIKA', u'Toto', ..., None, ..., u'Tears For Fears'])

And another one from what I can only assume is get_distinct('album')

ERROR    SpotifyBackend backend returned bad data: Expected a list of unicode, not set([u'90125', u'Toto', ..., None, ..., u'Happy Together'])

Login problems

When I start modipy it disconnects from spotify:

2015-05-19 07:44:29,815 - ERROR Spotify login error: Bad username and/or password
2015-05-19 07:44:29,820 - INFO Disconnected from Spotify

I double checked my credentials in the config, it's all correct!
Are there any known problems with a maximal lenght or certain symbols?

Cannot connect to spotify (Spotify login error)

[john@mfwsmusic mopidy]$ mopidy
** Message: pygobject_register_sinkfunc is deprecated (GstObject)
INFO     Starting Mopidy 1.0.4
INFO     Loading config from builtin defaults
INFO     Loading config from /home/john/.config/mopidy/mopidy.conf
INFO     Loading config from command line options
INFO     Enabled extensions: mopify, spotify, mpd, http, stream, spotify_tunigo, m3u, softwaremixer, moped, local, tunein, soundcloud
INFO     Disabled extensions: none
INFO     Starting Mopidy mixer: SoftwareMixer
INFO     Starting Mopidy audio
INFO     Starting Mopidy backends: SpotifyBackend, StreamBackend, M3UBackend, LocalBackend, SpotifyTunigoBackend, TuneInBackend, SoundCloudBackend
INFO     Mopidy uses SPOTIFY(R) CORE
INFO     Audio output set to "autoaudiosink"
INFO     Loaded 0 M3U playlists from /home/john/.local/share/mopidy/m3u
INFO     No local library metadata cache found at /home/john/.local/share/mopidy/local/library.json.gz. Please run `mopidy local scan` to index your local music library. If you do not have a local music collection, you can disable the local backend to hide this message.
INFO     Loaded 0 local tracks using json
INFO     Starting Mopidy core
INFO     Starting Mopidy frontends: MpdFrontend, HttpFrontend
INFO     MPD server running at [0.0.0.0]:6600
INFO     HTTP server running at [0.0.0.0]:6680
ERROR    Spotify login error: Cannot connect to Spotify
INFO     Disconnected from Spotify

I keep on getting disconnected from Spotify when I start Mopidy, I have triple checked my account details and they are definitely correct. Is there a way I can debug this?

Spotify does not logout fully

See mopidy/mopidy#442 for previous state.

When Mopidy is stopped the Spotify session starts to log out but the logged_out() callback does not get a chance to run and indicate the "logout has been processed" before Mopidy stops.

I don't have specific example of this causing a problem right now but terminating the Spotify thread before it's had a chance to fully write its data to disk may cause cache problems; particularly when we support playlist modifications and offline playlists in the future. The libspotify documentation states you must log out "Otherwise, the settings and cache may be lost", it seems sensible to let this write-back finish before terminating.

Removing the daemon property of process.BaseThread allows the callback to fire and displays the 'Disconnected from Spotify' log message before Mopidy stops. But I don't fully understand the implications of doing this so maybe some sort of wait is a better solution?

Browse directory structure

I'm working on the new Mopify client and noticed a slight difference in the way how opidy-spotify's directory structure is built up compared to the mopidy-soundcloud extension. Mopidy-soundcloud appends each newly clicked 'directory' after the uri, where mopidy-spotify radically changes the URI. Is there a reason for this, if not; would it be possible (and make more sense) to get this in line with each other?

For example when browsing through Spotify: spotify:directory changes to spotify:top:tracks instead of spotify:spotify:directory:top:tracks.

Make Spotify cover art available to clients

Spotify cover art should be made available to clients.

Possible approaches ranged from simple/heavy to smarter/lighter:

  • Add data: URIs with the covers to the Album objects. Not a good idea for clients already overloaded by Mopidy sending them too much data.
  • Add http:// URLs pointing to cover art hosted by a web extension provided by Mopidy-Spotify. This would be a lot better.
  • Wait for Mopidy core to implement a generic metadata lookup service or a more specific cover art lookup service and provide Spotify cover art through this service. The related Mopidy issue is mopidy/mopidy#263.

No longer seeing any Spotify Playlists

As of this evening, I am no longer seeing any Spotify playlists being loaded by mopidy. I've changed nothing on my installation, as far as I recall - and it's happening on 2 systems - so it must be something at Spotify. All my playlists are still there in the official client, and mopidy will search for and play spotify tracks.

Have Spotify mangled their API again so this no longer works?

Test methods when network/Spotify service isn't available

If I remember correctly, there's a couple of ways Mopidy-Spotify 2 can crash if the network/Spotify service isn't available. This should be fixed before 2.0.0 release.

To reproduce:

  1. Run mopidy -o spotify/allow_network=false
  2. Test various methods, like search, browse, etc.
  3. Fix crashes by checking session.connection.state before assuming we have working network.

Using websocket API?

Is it planned to allow the use of spotify-websocket-api instead of libspotify, or should it be a different project?

thanks

Browsing of playlists

To get a hierarchical view of the Spotify playlists, they should be made available through library.browse().

If the spotify/allow_playlists config is set to False, playlists should not be present in library.browse().

It may make sense to add a config for disabling playlists in the playlist view, and just show playlists through browse() to reduce noise in some MPD client UIs.

Use remember me feature of libspotify for auth blob

See mopidy/mopidy#305 previous state.

As mopidy/mopidy#116 points out we shouldn't be storing passwords in plain text. Since libspotify can give us an auth blob as a token to use to stay signed in without re-requesting the password be should look into adding this an alternative to storing the plain text password.

The flow if added would be to prompt the user for the missing credentials and then store the auth blob for use next time we log in. If the blob has expired we will of course need to log in again.

private_session causes error 'private_session can only be set when the session is logged '

With the latest version from develop I get the following error:

INFO     Loaded 0 local tracks using json
ERROR    Unhandled exception in SpotifyBackend (urn:uuid:e96f43c1-949a-46cd-ba53-c61273b235ad):
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 191, in _actor_loop
    self.on_start()
  File "/usr/local/lib/python2.7/dist-packages/Mopidy_Spotify-2.0.0-py2.7.egg/mopidy_spotify/backend.py", line 52, in on_start
    self._session = self._get_session(self._config)
  File "/usr/local/lib/python2.7/dist-packages/Mopidy_Spotify-2.0.0-py2.7.egg/mopidy_spotify/backend.py", line 77, in _get_session
    config['spotify']['private_session'])
  File "/usr/local/lib/python2.7/dist-packages/pyspotify-2.0.0b4-py2.7-linux-x86_64.egg/spotify/social.py", line 41, in private_session
    'private_session can only be set when the session is logged '
RuntimeError: private_session can only be set when the session is logged in. This is temporary workaround of a libspotify bug, causing the application to segfault otherwise.
INFO     Audio output set to "autoaudiosink"
INFO     Starting Mopidy core
ERROR    Uncaught exception
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/Mopidy-0.19.5-py2.7.egg/mopidy/commands.py", line 282, in run
    core = self.start_core(mixer, backends)
  File "/usr/local/lib/python2.7/dist-packages/Mopidy-0.19.5-py2.7.egg/mopidy/commands.py", line 365, in start_core
    return Core.start(mixer=mixer, backends=backends).proxy()
  File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 93, in start
    obj = cls(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/Mopidy-0.19.5-py2.7.egg/mopidy/core/actor.py", line 46, in __init__
    self.backends = Backends(backends)
  File "/usr/local/lib/python2.7/dist-packages/Mopidy-0.19.5-py2.7.egg/mopidy/core/actor.py", line 119, in __init__
    has_library = b.has_library().get()
  File "/usr/lib/python2.7/dist-packages/pykka/future.py", line 299, in get
    exec('raise exc_info[0], exc_info[1], exc_info[2]')
  File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 470, in ask
    self.tell(message)
  File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 437, in tell
    raise _ActorDeadError('%s not found' % self)
ActorDeadError: SpotifyBackend (urn:uuid:e96f43c1-949a-46cd-ba53-c61273b235ad) not found
INFO     Stopping Mopidy frontends
INFO     Stopping Mopidy core
INFO     Stopping Mopidy backends
INFO     Stopping Mopidy audio
INFO     Stopping Mopidy mixer

I have private_session = False in config.

New playlist remains in loading state

Moved from mopidy/mopidy#214:

To reproduce:

  1. Have Mopidy running
  2. Use e.g. the official Spotify client to add a new playlist
  3. See in the Mopidy log that Mopidy detects the change almost immediately
  4. The new playlist is listed as "[loading...]" until Mopidy is restarted

Note: If you can't see the new playlist at step 4, your client is probably caching the stored playlists. Try > restarting your client.

Should we solve this with a SpotifyPlaylist analogous to the existing SpotifyTrack solution for tracks?

Listen to playlist events

We don't cache playlists, so the results from our playlist provider should already be up to date, but we want to emit the playlists_loaded event when the playlists change, so Mopidy clients will now when to refetch the playlists.

This will be improved upon later, when Mopidy gets a more complete set of playlist events.

INFO Loaded Spotify Playlists

Between the hours of 10 and 11 UTC the following message is constantly outputted from mopidy.
INFO Loaded 30 Spotify playlists

During this time the songs don't stop playing, the current time on the song will go past the end time and it won't stop and I have to hit next for each song.

I have tried reloading the playlist and hitting next a lot of times but this didn't fix the issue.
Also how long the playlist has been running has no effect on this.

This has been going on for a good few months now.

Package details from dpkg -s
dpkg -s mopidy-spotify
Package: mopidy-spotify
Status: install ok installed
Priority: optional
Section: sound
Installed-Size: 130
Maintainer: Stein Magnus Jodal [email protected]
Architecture: all
Version: 1.4.0-0mopidy1
Depends: python-pkg-resources, mopidy, python-pykka, python-spotify (<< 2), python (>= 2.7)

dpkg -s mopidy
Package: mopidy
Status: install ok installed
Priority: optional
Section: sound
Installed-Size: 901
Maintainer: Stein Magnus Jodal [email protected]
Architecture: all
Version: 1.0.7-1
Depends: debconf (>= 0.5) | debconf-2.0, init-system-helpers (>= 1.18~), python (>= 2.7), python (<< 2.8), python-pkg-resources, python-pykka, python-tornado (>= 2.3), adduser, debconf, lsb-base, gstreamer0.10-plugins-good, python-gst0.10
Recommends: gstreamer0.10-alsa, gstreamer0.10-plugins-ugly, gstreamer0.10-pulseaudio, gstreamer0.10-tools
Suggests: mopidy-doc
Conffiles:
/etc/logrotate.d/mopidy a8e64ce52001ba5c673af6789a6c78ea
/etc/init.d/mopidy 3f5929723a2a438cc9a5f7589080bbb6
/etc/mopidy/mopidy.conf 9598973e8ee5bf54f1a288ae8e505a35
/etc/mopidy/logging.conf dbacd3800f63ef3c2a7135a6f3ee573d

Thanks :)

20 second lag when adding search results to current playlist using HEAD

I was interested in adding playlist configuration. So I pulled head of mopidy, pyspotify, and mopidy-spotify to get started on developing.

I've run into an odd performance regression. If I do a search in ncmpcpp (my client) the search goes fine but then when I click enter on the result (e.g. an artist name) to add those results to the current playlist ncmpcpp hangs for 20 seconds before the results are added and music starts playing.

So I checked out these commits:

mopidy-spotify:

commit 7197194ed455b2425c2e8ff993bf3819c15ef8ff
Author: Stein Magnus Jodal <[email protected]>
Date:   Mon Jul 21 02:03:22 2014 +0200

    Release v1.2.0

pyspotify:

commit 68cdfb5fbd405c71c9ffcad5ed2647fde4d9d92e
Author: Stein Magnus Jodal <[email protected]>
Date:   Sun May 4 23:22:09 2014 +0200

    docs: Release v2.0.0b3

And the problem goes away (e.g. items add near instantly as when using AUR version).

Had a few questions:

  • Are you accepting pull requests for playlist configuration? If so should I be developing against head? Not sure what its current state is given that I ran into this bug and wasn't able to find anything in the bug tracker.
  • Is it worth me tracking down why this is happening/have you seen this before?

Background info on my setup:

  • No local music library or other plugins used besides mopidy-spotify.
  • I removed everything except for my config file in ~/.config/mopidy to make sure I didn't have cache problems.
  • I'm on Arch. Packages are fully upgraded. Was previously running mopidy-spotify from AUR.
  • My ncmpcpp version is 0.6.2. Have not tried any other clients yet.
  • I did setup via sudo python2 setup.py develop for all three (mopidy, pyspotify, mopidy-spotify). Pulled pyspotify because it looks like mopidy-spotify depends on a version not available to pip.

Offline Playlists/Albums/Artists

I don't know what libspotify exposes nor what your roadmap looks like, but it would be extremely useful to be able to be able to cache music.

Can Spotify Connect be supported?

My guess is that Spotify has not added this feature to the library you are using.
I do not know whether its protocol has been reversed already.
Any thoughts on this?

1.x: Model validation breakage

Model validation broke how mopidy-spotify constructs models. Simple fix should be date = str(spotify_album.year()) in the translators.

@jodal, if you don't have time to get m-s 2.x out before Mopidy 1.1 this needs to be fixed.

Playback becomes silent after being paused for a long time

See mopidy/mopidy#457 for original state.

If I pause in the middle of a track for a long time (a couple of hours, maybe shorter as well), and then resume playback, it plays a couple of seconds and then goes silent for the rest of the track. It appears as playing, but I hear no sound. Seeking doesn't help, but if I change track it plays normally again.

sp_session_starred_create segmentation fault

Every time I connect to the Mopidy websocket with a webclient, Mopidy will crash with "Segmentation fault (core dumped)". I think this is caused by JsonRpcInspector finding get_playlists through the playlists property when core.describe is called.

(gdb) bt
#0  0x00007fd6dc00617c in ?? ()
#1  0x00007fd6ffdbfa8b in sp_session_starred_create () from /usr/lib/libspotify.so.12
#2  0x00007fd7000dde6c in _cffi_f_sp_session_starred_create (self=<optimised out>, arg0=<_cffi_backend.CData at remote 0x7fd6ff192508>) at build/temp.linux-x86_64-2.7/spotify._spotify.c:10979
#3  0x000000000052f936 in PyInt_AsUnsignedLongMask (op=()) at ../Objects/intobject.c:277
#4  0x00007fd6fda7c3d0 in ?? ()
#5  0x0000000000000000 in ?? ()

There is a verbose log at http://dpaste.com/1PD98M9. Removing my Spotify cache files doesn't appear to have any effect.

If I use mpc instead of a webclient, then all is fine up until I terminate Mopidy, at which point I get a different segmentation fault. I think the two seg faults are related since I found that changing PlaylistsController.get_playlists to include_tracks=False fixed everything and there were no seg faults in either scenario.

So my current best guess is this somehow related to the sp_playlist reference in a PlaylistTrack. Or that could be a red herring...

Spotify browsing with non-Premium account crashes system

As mentioned at pimusicbox/pimusicbox#184

I have a non premium spotify account and browsing through the spotify section of the webinterface brings up "no tracks" messages everywhere except for when I click on "Personal top tracks", which causes the playback to freeze immediately and also kills the webinterface. The pi is only reachable via ssh after that to issue a reboot.

Pauses other tracks when no connection to Spotify

If internet connectivity is lost while playing Spotify tracks (or before trying to start a Spotify track) then Mopidy-Spotify starts to pause playback each few seconds (most likely each time when Spotify connection error: Cannot connect to Spotify is being logged).
This behavior continues when playing local files and only way to stop it is restart of Mopidy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.