core: Correctly handle missing duration in seek.

Seeks will now fail when the duration is None, this is an approximation to if
the track is seekable or not. This check is need as otherwise seeking a radio
stream will trigger the next track.

If the track truly isn't seekable despite having a duration we should still
fail as GStreamer will reject the seek.
This commit is contained in:
Thomas Adamcik 2015-03-15 11:29:07 +01:00
parent 51b83f0f05
commit 6adeea6009
5 changed files with 19 additions and 1 deletions

View File

@ -361,6 +361,9 @@ class PlaybackController(object):
if not self.core.tracklist.tracks:
return False
if self.current_track and self.current_track.length is None:
return False
if self.get_state() == PlaybackState.STOPPED:
self.play()

View File

@ -325,7 +325,7 @@ class Track(ImmutableObject):
:param date: track release date (YYYY or YYYY-MM-DD)
:type date: string
:param length: track length in milliseconds
:type length: integer
:type length: integer or :class:`None` if there is no duration
:param bitrate: bitrate in kbit/s
:type bitrate: integer
:param comment: track comment

View File

@ -34,6 +34,8 @@ def track_to_mpd_format(track, position=None, stream_title=None):
result = [
('file', track.uri or ''),
# TODO: only show length if not none, see:
# https://github.com/mopidy/mopidy/issues/923#issuecomment-79584110
('Time', track.length and (track.length // 1000) or 0),
('Artist', artists_to_mpd_format(track.artists)),
('Title', track.name or ''),

View File

@ -38,6 +38,7 @@ class CorePlaybackTest(unittest.TestCase):
Track(uri='dummy2:a', length=40000),
Track(uri='dummy3:a', length=40000), # Unplayable
Track(uri='dummy1:b', length=40000),
Track(uri='dummy1:c', length=None), # No duration
]
self.core = core.Core(mixer=None, backends=[
@ -46,6 +47,7 @@ class CorePlaybackTest(unittest.TestCase):
self.tl_tracks = self.core.tracklist.tl_tracks
self.unplayable_tl_track = self.tl_tracks[2]
self.duration_less_tl_track = self.tl_tracks[4]
def test_get_current_tl_track_none(self):
self.core.playback.set_current_tl_track(None)
@ -478,6 +480,15 @@ class CorePlaybackTest(unittest.TestCase):
self.assertFalse(self.playback1.seek.called)
self.assertFalse(self.playback2.seek.called)
def test_seek_fails_for_track_without_duration(self):
self.core.playback.current_tl_track = self.duration_less_tl_track
self.core.playback.state = core.PlaybackState.PLAYING
success = self.core.playback.seek(1000)
self.assertFalse(success)
self.assertFalse(self.playback1.seek.called)
self.assertFalse(self.playback2.seek.called)
def test_seek_play_stay_playing(self):
self.core.playback.play(self.tl_tracks[0])
self.core.playback.state = core.PlaybackState.PLAYING

View File

@ -34,6 +34,8 @@ class TrackMpdFormatTest(unittest.TestCase):
mtime.undo_fake()
def test_track_to_mpd_format_for_empty_track(self):
# TODO: this is likely wrong, see:
# https://github.com/mopidy/mopidy/issues/923#issuecomment-79584110
result = translator.track_to_mpd_format(Track())
self.assertIn(('file', ''), result)
self.assertIn(('Time', 0), result)