mopidy / mopidy-soundcloud

Mopidy extension for playing music from SoundCloud
https://mopidy.com/ext/soundcloud/
MIT License
183 stars 58 forks source link

Track parsing fails when attempting to load Soundcloud stream feed #47

Open khughitt opened 9 years ago

khughitt commented 9 years ago

Using ncmcpp as a front-end, whenever I try and load my liked stream, an exception is raised by the server, e.g.:

** Message: pygobject_register_sinkfunc is deprecated (GstObject)
INFO     Starting Mopidy 0.19.5
INFO     Loading config from builtin defaults
INFO     Loading config from /home/keith/.config/mopidy/mopidy.conf
INFO     Loading config from command line options
INFO     Enabled extensions: mpd, http, stream, softwaremixer, local, soundcloud
INFO     Disabled extensions: none
INFO     Starting Mopidy mixer: SoftwareMixer
INFO     Starting Mopidy audio
INFO     Starting Mopidy backends: LocalBackend, StreamBackend, SoundCloudBackend
INFO     Audio output set to "autoaudiosink"
INFO     Starting Mopidy core
INFO     Starting Mopidy frontends: HttpFrontend, MpdFrontend
INFO     HTTP server running at [::ffff:127.0.0.1]:6680
INFO     MPD server running at [::]:6600
INFO     New MPD connection from [::ffff:127.0.0.1]:35373
INFO     New MPD connection from [::ffff:127.0.0.1]:35374
INFO     New MPD connection from [::1]:48246
INFO     New MPD connection from [::ffff:127.0.0.1]:35376
INFO     New MPD connection from [::ffff:127.0.0.1]:35377
INFO     New MPD connection from [::ffff:127.0.0.1]:35378
INFO     New MPD connection from [::ffff:127.0.0.1]:35379
INFO     New MPD connection from [::ffff:127.0.0.1]:35380
INFO     New MPD connection from [::ffff:127.0.0.1]:35381
INFO     New MPD connection from [::ffff:127.0.0.1]:35382
INFO     New MPD connection from [::ffff:127.0.0.1]:35384
INFO     'The Mara (Duke Dumont Edit)- Kiwi' can't be streamed from SoundCloud
TRACK:
[]
ERROR    Unhandled exception in MpdSession (urn:uuid:29e95010-a156-48cd-9b94-16606594b9b2):
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/pykka/actor.py", line 200, in _actor_loop
    response = self._handle_receive(message)
  File "/usr/lib/python2.7/site-packages/pykka/actor.py", line 303, in _handle_receive
    return self.on_receive(message)
  File "/usr/lib/python2.7/site-packages/mopidy/utils/network.py", line 366, in on_receive
    self.on_line_received(line)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/session.py", line 33, in on_line_received
    response = self.dispatcher.handle_request(line)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 46, in handle_request
    return self._call_next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
    return next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 75, in _catch_mpd_ack_errors_filter
    return self._call_next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
    return next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 85, in _authenticate_filter
    return self._call_next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
    return next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 104, in _command_list_filter
    response = self._call_next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
    return next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 133, in _idle_filter
    response = self._call_next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
    return next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 146, in _add_ok_filter
    response = self._call_next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
    return next_filter(request, response, filter_chain)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 158, in _call_handler_filter
    response = self._format_response(self._call_handler(request))
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/dispatcher.py", line 172, in _call_handler
    return protocol.commands.call(tokens, context=self.context)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/protocol/__init__.py", line 178, in call
    return self.handlers[tokens[0]](context, *tokens[1:])
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/protocol/__init__.py", line 156, in validate
    return func(**callargs)
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/protocol/music_db.py", line 433, in lsinfo
    result.extend(translator.track_to_mpd_format(tracks[0]))
  File "/usr/lib/python2.7/site-packages/mopidy/mpd/translator.py", line 42, in track_to_mpd_format
    ('file', track.uri or ''),
AttributeError: 'list' object has no attribute 'uri'
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/mopidy/utils/network.py", line 272, in recv_callback
    self.actor_ref.tell({'close': True})
  File "/usr/lib/python2.7/site-packages/pykka/actor.py", line 437, in tell
    raise _ActorDeadError('%s not found' % self)
pykka.exceptions.ActorDeadError: MpdSession (urn:uuid:29e95010-a156-48cd-9b94-16606594b9b2) not found
INFO     New MPD connection from [::1]:48256
INFO     'The Mara (Duke Dumont Edit)- Kiwi' can't be streamed from SoundCloud
...

As far as I can tell though, the API response looks okay:

{
  "kind": "track",
  "id": 161789203,
  "created_at": "2014/08/05 11:47:06 +0000",
  "user_id": 337162,
  "duration": 244058,
  "commentable": true,
  "state": "finished",
  "original_content_size": 9762540,
  "last_modified": "2015/02/20 15:53:07 +0000",
  "sharing": "public",
  "tag_list": "house pop club blaseboysclub \"duke dumont\" remix kiwi \"the mara\" mara",
  "permalink": "the-mara-duke-dumont-edit-kiwi",
  "streamable": false,
  "embeddable_by": "all",
  "downloadable": false,
  "purchase_url": "https://itunes.apple.com/gb/album/the-mara-single/id899382762?ign-mpt=uo%3D4",
  "label_id": null,
  "purchase_title": "BUY NOW",
  "genre": "Techno",
  "title": "The Mara (Duke Dumont Edit)- Kiwi",
  "description": "facebook.com/kiwidj\r\n\r\nChart topping dance music sensation Duke Dumont presents a new offering from his imprint and artist collective with ‘The Mara EP’ coming courtesy of fellow London-based producer and DJ, Kiwi. \r\n\r\nA sterling three-tracker, ‘The Mara’ can be heard alongside an edit from the label boss Duke Dumont himself and b-side addition ‘Gerenuk’.  \r\n\r\n'Hearing the demo of ‘The Mara’, it made me regress to the time I spent in the rainforest, chilling with the Chieftains and drinking ayahuasca,” explains the Duke. \r\n\r\n“The obscure sounds of exotic bird mating calls which I heard are replicated in the synth chirps and tonal aspects of this track. Ultimately though, I signed the song because of the unique character Kiwi has created sonically. Character within electronic music is usually hard to find, but Kiwi has achieved this effortlessly.”",
  "label_name": "",
  "release": "",
  "track_type": "",
  "key_signature": "",
  "isrc": "",
  "video_url": null,
  "bpm": null,
  "release_year": null,
  "release_month": null,
  "release_day": null,
  "original_format": "mp3",
  "license": "all-rights-reserved",
  "uri": "https://api.soundcloud.com/tracks/161789203",
  "user": {
    "id": 337162,
    "kind": "user",
    "permalink": "kiwidj",
    "username": "Kiwi_",
    "last_modified": "2015/02/09 16:41:29 +0000",
    "uri": "https://api.soundcloud.com/users/337162",
    "permalink_url": "http://soundcloud.com/kiwidj",
    "avatar_url": "https://i1.sndcdn.com/avatars-000126916754-khxsye-large.jpg"
  },
  "permalink_url": "http://soundcloud.com/kiwidj/the-mara-duke-dumont-edit-kiwi",
  "artwork_url": "https://i1.sndcdn.com/artworks-000087192976-9bgjpu-large.jpg",
  "waveform_url": "https://w1.sndcdn.com/oIBHlzZonvF8_m.png",
  "playback_count": 265433,
  "download_count": 0,
  "favoritings_count": 10009,
  "comment_count": 126,
  "attachments_uri": "https://api.soundcloud.com/tracks/161789203/attachments",
  "policy": "ALLOW"
}

I couldn't figure out how to spawn a PDB session at that point (any suggestions?), but adding a print statement showed that the track is an empty list, "[]".

System info:

** Message: pygobject_register_sinkfunc is deprecated (GstObject)
Platform: Linux-3.18.6-1-ARCH-x86_64-with-glibc2.2.5
Python: CPython 2.7.9 from /usr/lib/python2.7
Mopidy: 0.19.5 from /usr/lib/python2.7/site-packages
  setuptools: 12.2 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.0 from /usr/lib/python2.7/site-packages
  tornado>=2.3: 4.1 from /usr/lib/python2.7/site-packages
Mopidy-SoundCloud: 1.2.5 from /usr/lib/python2.7/site-packages
  setuptools: 12.2 from /usr/lib/python2.7/site-packages
  Mopidy>=0.18: 0.19.5 from /usr/lib/python2.7/site-packages
    setuptools: 12.2 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.0 from /usr/lib/python2.7/site-packages
    tornado>=2.3: 4.1 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.0 from /usr/lib/python2.7/site-packages
  requests>=2.0.0: 2.5.1 from /usr/lib/python2.7/site-packages
GStreamer: 0.10.36.0 from /usr/lib/python2.7/site-packages/gst-0.10/gst
  Detailed information: 
    Python wrapper: gst-python 0.10.22.0
    Relevant elements:
      Found:
        uridecodebin
        souphttpsrc
        appsrc
        alsasink
        osssink
        oss4sink
        pulsesink
        id3demux
        id3v2mux
        lame
        mad
        vorbisdec
        vorbisenc
        vorbisparse
        oggdemux
        oggmux
        oggparse
        flacdec
        flacparse
        shout2send
      Not found:
        flump3dec
        mp3parse

Any suggestions? I'm happy to help track down the issue, but not sure of how to get into PDB. I tried both hard-coding a 'import pdb; pdb.set_trace()' and launching from the CLI:

python2 -m pdb `which mopidy`

But perhaps because of the threading used, It does not open up PDB.

baumgartnerniels commented 9 years ago

Same here. Somehow lookup_future.get()in lsinfo in mopidy/mpd/protocol/music_db.py returns [] for some songs. I have no idea why. I looked at all the Track elements returned by SoundCloudClient.get_user_stream() and they seem just fine.

As a dirty fix this worked for me:

replace

    result = []
    for path, lookup_future in context.browse(uri, recursive=False):
        if not lookup_future:
            result.append(('directory', path.lstrip('/')))
        else:
            tracks = lookup_future.get()
            if tracks:
                result.extend(translator.track_to_mpd_format(tracks[0]))

with

    result = []
    for path, lookup_future in context.browse(uri, recursive=False):
        if not lookup_future:
            result.append(('directory', path.lstrip('/')))
        else:
            tracks = lookup_future.get()
            if filter(None, tracks):
                result.extend(translator.track_to_mpd_format(tracks[0]))

in the lsinfo function of mopidy/mpd/protocol/music_db.py