Mopidy: Undefined behavior when removing currently playing track from tracklist.

Created on 7 Jan 2017  ·  10Comments  ·  Source: mopidy/mopidy

TracklistController.remove() currently just removes the track and triggers the tracklist_changed event:

https://github.com/mopidy/mopidy/blob/2b7f12b8542d04190a85ed890edac1ce9192d9e8/mopidy/core/tracklist.py#L567-L572

I'm not sure that it makes sense to keep playing the current track if it was just removed from the tracklist - perhaps it would be better to call stop() or next() at that point instead?

https://github.com/mopidy/mopidy/blob/2b7f12b8542d04190a85ed890edac1ce9192d9e8/mopidy/core/playback.py#L304-L305

C-bug A-core

Most helpful comment

MPD removes the track and then jumps to the next one in the playlist if available. Otherwise playback stops.

All 10 comments

We should check what mpd does

MPD removes the track and then jumps to the next one in the playlist if available. Otherwise playback stops.

Anyone started to fix this bug? I can try to come up with a solution.

Nope, go for it. Since nobody has piped up I think we can assume mirroring MPD's behaviour is reasonable.

Ok. Some observations:

  • PlaybackController uses self._current_tl_track for finding other tracks, for example next(). If we want to continue to play from the tracklist after track deletion, then we need to relate self._current_tl_track to the remaining tracks in the tracklist (that does not include _current_tl_track anymore). A quite simple thing would be to look in the TracklistController.tl_tracks and play the track with a tlid value higher than the tlid of _current_tl_track. Let me know if I have missed something that would make the implementation of playing the next track more straight forward.
  • PlaybackController._on_about_to_finish() throws AttributeError when a playing track is deleted (i.e. _on_tracklist_change() should at least stop() when track has been removed):
    File "/home/aj/mopidy-dev/mopidy/mopidy/core/playback.py", line 270, in _on_about_to_finish self._last_position = self._current_tl_track.track.length AttributeError: 'NoneType' object has no attribute 'track'
  • Noticed that there are no unit tests for _on_tracklist_change(), probably some hints in the tests of _on_about_to_finish()
  • In contrast to MPD, VLC stops playing upon track deletion during playback

I've created a branch with a fix for this issue, which works with all tracks including streams, where there were some additional problems relating to gstreamer sending buffering messages on stop. It currently fails several of the tests but it works in practice. It's based on @kingosticks web api playlists branch, so it also includes that feature. It's here https://github.com/fatg3erman/mopidy/tree/fix/consume-current-track if anybody's interesting in trying it to get some more beta testing before I try to fix the tests.

Actually part of that comment is nonsense :) It's not based on the web-api-playlists branch, because that's mopidy-spotify and unrelated to this problem :) I haven't drunk enough tea yet today....

I'm on holiday right now but can review when I'm back next weekend (if you want and make a pull request).

Thanks. Addded PR 1689 for this.

still reproducible with mopidy 3.0.1

Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/mopidy/audio/actor.py", line 559, in _on_about_to_finish
    self._about_to_finish_callback()
  File "/usr/lib/python3.7/site-packages/mopidy/core/playback.py", line 178, in _on_about_to_finish_callback
    kwargs={},
  File "/usr/lib/python3.7/site-packages/pykka/_ref.py", line 114, in ask
    return future.get(timeout=timeout)
  File "/usr/lib/python3.7/site-packages/pykka/_threading.py", line 45, in get
    _compat.reraise(*self._data['exc_info'])
  File "/usr/lib/python3.7/site-packages/pykka/_compat/__init__.py", line 29, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/pykka/_actor.py", line 193, in _actor_loop
    response = self._handle_receive(envelope.message)
  File "/usr/lib/python3.7/site-packages/pykka/_actor.py", line 299, in _handle_receive
    return callee(*message.args, **message.kwargs)
  File "/usr/lib/python3.7/site-packages/mopidy/core/playback.py", line 190, in _on_about_to_finish
    self._last_position = self._current_tl_track.track.length
AttributeError: 'NoneType' object has no attribute 'track'

STR: remove currently playing track and wait for it to finish

with ncmpcpp: play multiple tracks; hover over any other track not currently playing; hit shift-c to remove all but hovered-over tracks; wait for current track to finish.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zopyx picture zopyx  ·  4Comments

ecoCuyo picture ecoCuyo  ·  3Comments

djselbeck picture djselbeck  ·  8Comments

handsomegui picture handsomegui  ·  12Comments

altano picture altano  ·  6Comments