Add tracking of time position in track

This commit is contained in:
Stein Magnus Jodal 2009-12-26 05:08:51 +01:00
parent 4b13e4ad33
commit 077f13a5dd
4 changed files with 65 additions and 20 deletions

View File

@ -1,3 +1,5 @@
import time
class BaseBackend(object):
PLAY = u'play'
PAUSE = u'pause'
@ -5,6 +7,8 @@ class BaseBackend(object):
def __init__(self):
self.state = self.STOP
self._play_time_accumulated = 0
self._play_start = False
def current_song(self):
return None
@ -38,6 +42,19 @@ class BaseBackend(object):
return self.state
def status_time(self):
return u'%s:%s' % (
self.status_time_position(), self.status_time_total())
def status_time_position(self):
if self.state == self.PAUSE:
return self._play_time_accumulated
elif self.state == self.PLAY and self._play_start:
return self._play_time_accumulated + (
int(time.time()) - self._play_start)
else:
return 0
def status_time_total(self):
return 0
def status_xfade(self):
@ -49,21 +66,29 @@ class BaseBackend(object):
def pause(self):
self.state = self.PAUSE
self._play_time_accumulated += int(time.time()) - self._play_start
def play(self):
self.state = self.PLAY
self._play_time_accumulated = 0
self._play_start = int(time.time())
def play_pos(self, songpos):
self.state = self.PLAY
self._play_time_accumulated = 0
self._play_start = int(time.time())
def play_id(self, songid):
self.state = self.PLAY
self._play_time_accumulated = 0
self._play_start = int(time.time())
def previous(self):
pass
def resume(self):
self.state = self.PLAY
self._play_start = int(time.time())
def stop(self):
self.state = self.STOP

View File

@ -63,6 +63,10 @@ class SpotifyBackend(BaseBackend):
self._x_current_playlist_version = 0
return self._x_current_playlist_version
@property
def _current_track(self):
return self._current_playlist[self._current_song_id]
@property
def _current_song_id(self):
if not hasattr(self, '_x_current_song_id'):
@ -106,42 +110,47 @@ class SpotifyBackend(BaseBackend):
artist_names = [decode(artist.name) for artist in artists]
return u', '.join(artist_names)
# Control methods
def next(self):
self._current_song_id += 1
self.play_id(self._current_song_id)
self.play()
def pause(self):
self.state = self.PAUSE
super(SpotifyBackend, self).pause()
self.spotify.pause()
def play(self):
self.play_id(self._current_song_id)
if self.state == self.PAUSE:
return self.resume()
super(SpotifyBackend, self).play()
self.spotify.play(self._current_track)
def play_pos(self, songpos):
self.play_id(songpos)
super(SpotifyBackend, self).play_pos(songpos)
self._current_song_id = songpos
track = self._current_playlist[songid]
self.spotify.play(track)
def play_id(self, songid):
self.state = self.PLAY
super(SpotifyBackend, self).play_id(songid)
self._current_song_id = songid
track = self._current_playlist[songid]
self.spotify.play(track)
def previous(self):
self._current_song_id -= 1
self.play_id(self._current_song_id)
self.play()
def resume(self):
self.state = self.PLAY
super(SpotifyBackend, self).resume()
self.spotify.resume()
def stop(self):
if self.state is not self.STOP:
self.state = self.STOP
self.spotify.stop()
super(SpotifyBackend, self).stop()
self.spotify.stop()
### MPD handlers
# Unsorted
def current_song(self):
try:
@ -184,6 +193,7 @@ class SpotifyBackend(BaseBackend):
return self._format_playlist(self._current_playlist)
# Status methods
def status_playlist(self):
return self._current_playlist_version
@ -193,16 +203,14 @@ class SpotifyBackend(BaseBackend):
def status_song_id(self):
return self._current_song_id
def status_time(self):
if self.state is self.PLAY:
return u'0:00'
else:
return None
def status_time_total(self):
return self._current_track.length // 1000
def url_handlers(self):
return [u'spotify:', u'http://open.spotify.com/']
# Music database methods
def search(self, type, what):
result = self.spotify.search(encode(u'%s:%s' % (type, what)))
return self._format_playlist(result.playlist.tracks)

View File

@ -379,7 +379,7 @@ class MpdHandler(object):
@register(r'^status$')
def _status(self):
return [
result = [
('volume', self.backend.status_volume()),
('repeat', self.backend.status_repeat()),
('random', self.backend.status_random()),
@ -391,8 +391,10 @@ class MpdHandler(object):
('state', self.backend.status_state()),
('song', self.backend.status_song_id()),
('songid', self.backend.status_song_id()),
('time', self.backend.status_time()),
]
if self.backend.state in (self.backend.PLAY, self.backend.PAUSE):
result.append(('time', self.backend.status_time()))
return result
@register(r'^swap (?P<songpos1>\d+) (?P<songpos2>\d+)$')
def _swap(self, songpos1, songpos2):

View File

@ -73,7 +73,8 @@ class CommandListsTest(unittest.TestCase):
class StatusHandlerTest(unittest.TestCase):
def setUp(self):
self.h = handler.MpdHandler(backend=DummyBackend())
self.b = DummyBackend()
self.h = handler.MpdHandler(backend=self.b)
def test_clearerror(self):
result = self.h.handle_request(u'clearerror')
@ -137,6 +138,15 @@ class StatusHandlerTest(unittest.TestCase):
self.assert_('state' in result)
self.assert_(result['state'] in ('play', 'stop', 'pause'))
def test_status_method_when_playing(self):
self.b.state = self.b.PLAY
result = dict(self.h._status())
self.assert_('time' in result)
(position, total) = result['time'].split(':')
position = int(position)
total = int(total)
self.assert_(position <= total)
class PlaybackOptionsHandlerTest(unittest.TestCase):
def setUp(self):