Changeset - 25308bc6d767
[Not reviewed]
default
0 1 0
Drew Perttula - 18 years ago 2007-06-17 23:00:45
drewp@bigasterisk.com
cache filling now prints
1 file changed with 3 insertions and 1 deletions:
0 comments (0 inline, 0 general)
bin/ascoltami
Show inline comments
 
@@ -117,193 +117,195 @@ class Player:
 
        self.current_time = tk.DoubleVar()
 
        self.total_time = tk.DoubleVar()
 
        self.filename_var = tk.StringVar()
 
        self.song_uri = None
 

	
 
        self.pre_post_names = showconfig.prePostSong()
 

	
 
        self.last_poll_time = None
 
        self.last_autopause_time = None
 

	
 
        self.pollStatus()
 

	
 
        self.mpd_is_lying = False # mpd reports bad times in certain intervals
 

	
 
    def smoothCurrentTime(self):
 
        """like self.current_time.get, but more accurate"""
 

	
 
        if self.last_poll_time and self.state.get() == 'play':
 
            dt = time.time() - self.last_poll_time
 
        else:
 
            dt = 0
 
        return self.current_time.get() + dt
 

	
 
    def pollStatus(self):
 
        if self.state.get() == 'stop':
 
            self.current_time.set(-4)
 
            
 
        self.mpd.status().addCallback(self.pollStatus2)
 
        
 
    def pollStatus2(self, stat):
 
        try:
 
            if self.state.get() != stat.state:
 
                self.state.set(stat.state)
 

	
 
            if hasattr(stat, 'time_elapsed'):
 
                elapsed = stat.time_elapsed
 
                songnum = stat.song
 
                total = stat.time_total
 
                if self.mpd_is_lying and elapsed < 3:
 
                    self.mpd_is_lying = False
 

	
 
                # mpd lies about elapsed, song, and total during the last
 
                # .5sec of each song. so we coast through that part
 
                if elapsed > total - .75 or self.mpd_is_lying:
 
                    if not self.mpd_is_lying:
 
                        self.mpd_is_lying = True
 
                        self.true_song_total = songnum, total
 
                        self.marked_time = time.time()
 
                        self.marked_val = elapsed
 
                    elapsed = self.marked_val + (time.time() - self.marked_time)
 
                    songnum, total = self.true_song_total
 

	
 
                t = -1
 
                if songnum == 1:
 
                    t = elapsed
 
                elif songnum == 0:
 
                    t = elapsed - total
 
                elif songnum == 2:
 
                    t = self.total_time.get() + elapsed
 

	
 
                self.current_time.set(t)
 

	
 
                self.last_poll_time = time.time()
 

	
 
            self.check_autopause()
 
        finally:
 
            reactor.callLater(.05, self.pollStatus)
 

	
 
    def set_total_time(self, song):
 
        # currently only good for .wav
 
        p = showconfig.songOnDisk(song)
 
        self.total_time.set(wavelength.wavelength(p))
 

	
 
    def play(self, song=None):
 
        if song is None:
 
            self.mpd.play()
 
            return
 
    
 
        self.mpd.clear()
 
        self.mpd.add(showconfig.songInMpd(MUS['preSong']))
 
        self.mpd.add(showconfig.songInMpd(song))
 
        self.mpd.add(showconfig.songInMpd(MUS['postSong']))
 

	
 
        self.fillCache(song)
 
        
 
        self.filename_var.set(graph.value(song, L9['showPath']))
 
        self.song_uri = song
 

	
 
        self.set_total_time(song)
 
        self.seek_to(-4)
 

	
 
    def fillCache(self, song):
 
        """read the song's entire wav file into memory just before
 
        playing, so that mpd should never hit the disk during
 
        playback. On score in 2007, we had some mpd stutters that were
 
        always timed with a disk read."""
 
        open(showconfig.songOnDisk(song)).read()
 
        p = showconfig.songOnDisk(song)
 
        print "reading %s to prime the cache" % p
 
        open(p).read()
 

	
 
    def check_autopause(self):
 
        pause_time = self.total_time.get() + self.song_pad_time
 
        t = self.current_time.get()
 
        if (self.state.get() == "play" and
 
            self.last_autopause_time < pause_time < t):
 
            self.mpd.pause()
 
        self.last_autopause_time = t
 

	
 
    def stop(self):
 
        self.mpd.seek(seconds=0, song=0)
 
        self.mpd.stop()
 
        
 
    def seek_to(self, time):
 
        if time < 0:
 
            # seeking to anything within my 4-sec silence ogg goes
 
            # right to zero. maybe ogg seeking is too coarse?
 
            self.mpd.seek(seconds=time - (-4), song=0)
 
        elif time > self.total_time.get():
 
            self.mpd.seek(seconds=time - self.total_time.get(), song=2)
 
        else:
 
            self.mpd.seek(seconds=time, song=1)
 
        self.last_autopause_time = time
 

	
 
    def skip_intro(self):
 
        self.seek_to(0)
 

	
 
    def in_post(self):
 
        return (self.current_time.get() > self.total_time.get() +
 
                self.song_pad_time)
 

	
 
    def play_pause_toggle(self):
 
        def finish(status):
 
            if status.state == 'play':
 
                self.mpd.pause()
 
            else:
 
                self.mpd.play()
 
        self.mpd.status().addCallback(finish)
 

	
 
    def pause(self):
 
        self.mpd.pause()
 

	
 
    def skip_to_post(self):
 
        self.seek_to(self.total_time.get() + self.song_pad_time)
 
        self.play()
 

	
 

	
 
class GoButton:
 
    def __init__(self, player, statusLabel, songPaths):
 
        self.player = player
 
        self.statusLabel = statusLabel
 
        self.songPaths = songPaths
 

	
 
        self.player.current_time.trace("w", self.updateStatus)
 

	
 
    def _nextAction(self):
 
        state = self.player.state.get() 
 
        if state == 'stop':
 
            currentPath = self.player.song_uri
 
            try:
 
                i = self.songPaths.index(currentPath) + 1
 
            except ValueError:
 
                i = 0
 
            nextPath = self.songPaths[i]
 
            return ("next song %s" % shortSongPath(nextPath,
 
                                                   self.songPaths),
 
                    lambda: self.player.play(nextPath))
 

	
 
        if state == 'pause':
 
            return "play", self.player.play
 

	
 
        if state == 'play':
 
            if self.player.current_time.get() < 0:
 
                return "skip intro", self.player.skip_intro
 
            if self.player.in_post():
 
                return "<nothing>", lambda: None
 
            return "skip to post", self.player.skip_to_post
 
        
 
    def action(self):
 
        desc, func = self._nextAction()
 
        func()
 
        
 
    def updateStatus(self, *args):
 
        desc, func = self._nextAction()
 
        self.statusLabel.config(text=desc)
 
        
 

	
 

	
 
def buildsonglist(root, graph, songs, player):
 
    songlist=tk.Frame(root,bd=2,relief='raised',bg='black')
 

	
 
    maxsfwidth=max([len(graph.label(song)) for song in songs])
 

	
 
    for i,song in enumerate(songs):
 
        b=tk.Button(songlist,text=graph.label(song),width=maxsfwidth,
 
                    anchor='w',pady=0,bd=0,relief='flat',
0 comments (0 inline, 0 general)