Changeset - 2961f5437f31
[Not reviewed]
default
0 1 0
Drew Perttula - 19 years ago 2006-06-18 23:12:48
drewp@bigasterisk.com
autopause now runs every time player passes the pad end
1 file changed with 38 insertions and 28 deletions:
0 comments (0 inline, 0 general)
bin/ascoltami
Show inline comments
 
@@ -29,13 +29,12 @@ import Tkinter as tk
 
from twisted.internet import reactor,tksupport
 
from twisted.internet.error import CannotListenError
 
from twisted.web import xmlrpc, server
 

	
 
import run_local
 
from light9 import networking, showconfig, wavelength
 
from light9.namespaces import L9, MUS
 

	
 
from pympd import Mpd
 

	
 
appstyle={'fg':'white','bg':'black'}
 

	
 
class XMLRPCServe(xmlrpc.XMLRPC):
 
@@ -74,13 +73,16 @@ class XMLRPCServe(xmlrpc.XMLRPC):
 

	
 
    def xmlrpc_song_uri(self):
 
        """song URI, or None"""
 
        return self.player.song_uri.encode('utf8') or "No song"
 

	
 
class Player:
 
    """semprini-style access to mpd. in here is where we add the padding"""
 
    """semprini-style access to mpd. in here is where we add the
 
    padding"""
 

	
 
    song_pad_time = 10
 
    
 
    def __init__(self, app, playlist, media=None):
 

	
 
        self.mpd = Mpd()
 
        reactor.connectTCP(*(networking.mpdServer()+(self.mpd,)))
 

	
 
@@ -92,16 +94,16 @@ class Player:
 
        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.autopausedthissong = False # a song only autopauses once
 
        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':
 
@@ -118,19 +120,15 @@ class Player:
 
        
 
    def pollStatus2(self, stat):
 
        try:
 
            if self.state.get() != stat.state:
 
                self.state.set(stat.state)
 

	
 
        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
 
@@ -163,30 +161,29 @@ class Player:
 

	
 
    def play(self, song=None):
 
        if song is None:
 
            self.mpd.play()
 
            return
 
    
 
        self.autopausedthissong = False
 
        self.mpd.clear()
 
        self.mpd.add(showconfig.songInMpd(MUS['preSong']))
 
        self.mpd.add(showconfig.songInMpd(song))
 
        self.mpd.add(showconfig.songInMpd(MUS['postSong']))
 
        self.filename_var.set(graph.value(song, L9['showPath']))
 
        self.song_uri = song
 

	
 
        self.set_total_time(song)
 
        self.mpd.seek(seconds=0, song=0)
 
        self.seek_to(-4)
 

	
 
    def check_autopause(self):
 
        pause_time = self.total_time.get() + 10
 
        if (not self.autopausedthissong and
 
            self.state.get() == "play" and
 
            self.current_time.get() > pause_time):
 
            self.autopausedthissong = True
 
        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):
 
@@ -195,32 +192,39 @@ class Player:
 
            # 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 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()
 
        
 

	
 

	
 
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,
 
    for i,sf in enumerate(songfiles):
 
        b=tk.Button(songlist,text=sf[prefixlen:],width=maxsfwidth,
 
                    anchor='w',pady=0,bd=0,relief='flat',
 
                    font="arial 14 bold")
 
        b.bind("<Configure>",lambda ev,b=b:
 
               b.config(font="arial %d bold" % min(12,int((ev.height-3)*.8))))
 
        try:
 
            # rainbow colors
 
@@ -324,14 +328,12 @@ class Seeker(tk.Frame):
 
                     relief='raised',bd=1,font='arial 9',
 
                     **appstyle).pack(side='left',fill='y')
 
            l = tk.Label(self,width=7, anchor='w', text=var.get(),
 
                         relief='sunken',bd=1,font='arial 12 bold',
 
                         padx=2,pady=2,
 
                         bg='#800000',fg='white')
 
            if txt == 'Song':
 
                l.config(anchor='e')
 
            l.pack(side='left',expand=1, fill='x')
 

	
 
            var.trace_variable('w',
 
                               lambda a,b,c,l=l,fmt=fmt,var=var:
 
                               l.config(text=fmt % var.get()))
 

	
 
@@ -353,31 +355,38 @@ class Seeker(tk.Frame):
 

	
 
class ControlButtons(tk.Frame):
 
    def __init__(self,master):
 
        tk.Frame.__init__(self,master,bg='black')
 
        
 
        self.statebuttons = {} # lowercased name : Button
 
        for txt,cmd,key in [
 
            ('Stop', player.stop, "<Control-s>"),
 
            ('Pause', player.play_pause_toggle, "<Control-p>"),
 
            ('Skip Intro',lambda: player.seek_to(0), "<Control-i>"),
 
        for tag, txt,cmd,key in [
 
            ('stop',
 
             'Stop\nC-s', player.stop, "<Control-s>"),
 
            ('pause',
 
             'Pause\nC-p', player.play_pause_toggle, "<Control-p>"),
 
            ('skip intro',
 
             'Skip Intro\nC-i',lambda: player.seek_to(0),
 
             "<Control-i>"),
 
            ('skip to post',
 
             'Skip to Post\nC-t', player.skip_to_post, "<Control-t>"),
 
            ]:
 
            b = tk.Button(self, text=txt, command=cmd, font='arial 16 bold',
 
            b = tk.Button(self, text=txt, command=cmd,
 
                          font='arial 16 bold',
 
                          height=3,**appstyle)
 
            b.pack(side='left', fill='x', expand=1)
 
            # keyboard bindings
 
            root.bind(key, lambda evt, cmd=cmd: cmd())
 
            self.statebuttons[txt.lower()] = b
 
            self.statebuttons[tag] = b
 

	
 
    def update_state_buttons(self,*args):
 
        state = player.state.get()
 

	
 
        if state in ('stop', 'pause'):
 
            self.statebuttons['pause']['text'] = 'Play'
 
            self.statebuttons['pause']['text'] = 'Play\nC-p'
 
        else:
 
            self.statebuttons['pause']['text'] = 'Pause'
 
            self.statebuttons['pause']['text'] = 'Pause\nC-p' 
 

	
 
        colors = {'stop' : 'red',
 
                  'play' : 'blue',
 
                  'pause' : 'green'} # very confusing -- play and pause supply colors
 
                                     # for each other!
 
        for name, button in self.statebuttons.items():
 
@@ -404,12 +413,13 @@ if len(songfiles)<1:
 
else:
 
    raise NotImplementedError("don't know how to make rdf song nodes from cmdline song paths")
 

	
 
root=tk.Tk()
 
root.wm_title("ascoltami")
 
#root.wm_geometry("+1270+440")
 
toplevelat("ascoltami", root)
 
root.config(bg="black")
 
player=Player(None,None)
 

	
 
songlist = buildsonglist(root, graph, songs, player)
 
songlist.pack(fill='both',exp=1)
 

	
0 comments (0 inline, 0 general)