Mercurial > code > home > repos > light9
annotate bin/ascoltami @ 522:e20419d637d5
initial vidref tests
Ignore-this: f3ca12ad8071d889ed71689be0716827
author | drewp@bigasterisk.com |
---|---|
date | Tue, 08 Jun 2010 06:52:59 +0000 |
parents | b0954240778d |
children | 880bfdd5deb0 |
rev | line source |
---|---|
217 | 1 #!/usr/bin/env python |
2 | |
3 # this is a fork from semprini/ascotalmi to use mpd | |
4 | |
5 """ a separate player program from Semprini.py. name means 'listen to | |
6 me' in italian. | |
7 | |
8 features and limitations: | |
9 | |
10 xmlrpc interface for: | |
11 getting the current time in the playing song | |
12 requesting what song is playing | |
13 saying what song should play | |
14 | |
357
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
15 |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
16 setup: |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
17 |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
18 get mpd root path correct |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
19 |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
20 run mpd that's been modified to give precise times: |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
21 dash(pts/21):/my/dl/modified/mpd% src/mpd --no-daemon |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
22 |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
23 tell it to scan |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
24 mpc update |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
25 (mpc listall to check) |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
26 |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
27 run ascoltami |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
28 |
7771f37252da
curvecalc persistence, wavecurve -a option
Drew Perttula <drewp@bigasterisk.com>
parents:
335
diff
changeset
|
29 |
217 | 30 todo: |
31 | |
32 | |
33 """ | |
34 | |
35 from __future__ import division,nested_scopes | |
36 | |
37 from optparse import OptionParser | |
429
41aa6895b3e6
ascoltami: local pympd import; cmdline ui
drewp@bigasterisk.com
parents:
423
diff
changeset
|
38 import sys, os,math,time |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
39 from rdflib import URIRef |
217 | 40 import Tkinter as tk |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
41 import logging |
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
42 log = logging.getLogger() |
432 | 43 log.setLevel(logging.INFO) |
217 | 44 |
45 from twisted.internet import reactor,tksupport | |
46 from twisted.internet.error import CannotListenError | |
47 from twisted.web import xmlrpc, server | |
48 | |
49 import run_local | |
243
fff8762db48a
finished incomplete patch- asco now measures the length of songs (only for .wav)
drewp@bigasterisk.com
parents:
242
diff
changeset
|
50 from light9 import networking, showconfig, wavelength |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
51 from light9.namespaces import L9, MUS |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
52 from light9.uihelpers import toplevelat |
217 | 53 |
429
41aa6895b3e6
ascoltami: local pympd import; cmdline ui
drewp@bigasterisk.com
parents:
423
diff
changeset
|
54 sys.path.append("/home/drewp/projects/pympd_0") |
434
c45ce0c1c733
another pympd search path for asco, since i seem to hate to install my own software
drewp@bigasterisk.com
parents:
432
diff
changeset
|
55 sys.path.append("/my/proj/pympd_0") |
217 | 56 from pympd import Mpd |
57 | |
58 appstyle={'fg':'white','bg':'black'} | |
59 | |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
60 def shortSongPath(song, all): |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
61 prefixlen = len(os.path.commonprefix(all)) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
62 # include to the last os.sep- dont crop path elements in the middle |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
63 prefixlen = all[0].rfind(os.sep)+1 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
64 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
65 return os.path.splitext(song[prefixlen:])[0] |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
66 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
67 |
217 | 68 class XMLRPCServe(xmlrpc.XMLRPC): |
69 def __init__(self,player): | |
70 xmlrpc.XMLRPC.__init__(self) | |
71 self.player=player | |
72 | |
73 def xmlrpc_echo(self,x): | |
74 return x | |
75 | |
76 def xmlrpc_playfile(self,musicfilename): | |
77 self.player.play(musicfilename) | |
78 return 'ok' | |
79 def xmlrpc_stop(self): | |
80 self.player.state.set('stop') | |
81 return 'ok' | |
276
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
82 def xmlrpc_seek_to(self,t): |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
83 self.player.seek_to(t) |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
84 return 'ok' |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
85 def xmlrpc_seekplay_or_pause(self,t): |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
86 """either seek to t and play; or pause. this is the |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
87 curvecalc click-play interface""" |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
88 if self.player.state.get() == "play": |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
89 self.player.pause() |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
90 return 'paused' |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
91 else: |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
92 self.player.seek_to(t) |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
93 self.player.play() |
77c39b6e71ab
new asco xmlrpc commands to seek/pause
drewp@bigasterisk.com
parents:
245
diff
changeset
|
94 return 'playing' |
217 | 95 def xmlrpc_gettime(self): |
96 """returns seconds from start of song""" | |
227 | 97 return float(self.player.smoothCurrentTime()) |
217 | 98 def xmlrpc_songlength(self): |
99 """song length, in seconds""" | |
100 return float(self.player.total_time.get()) | |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
101 |
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
102 def xmlrpc_song_uri(self): |
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
103 """song URI, or None""" |
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
104 return self.player.song_uri.encode('utf8') or "No song" |
217 | 105 |
106 class Player: | |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
107 """semprini-style access to mpd. in here is where we add the |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
108 padding""" |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
109 |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
110 song_pad_time = 10 |
217 | 111 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
112 def __init__(self): |
217 | 113 |
114 self.mpd = Mpd() | |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
115 args = (networking.mpdServer()+(self.mpd,)) |
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
116 log.info("connecting to %r", args) |
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
117 reactor.connectTCP(*args) |
217 | 118 |
119 self.state = tk.StringVar() | |
120 self.state.set("stop") # 'stop' 'pause' 'play' | |
121 | |
122 self.current_time = tk.DoubleVar() | |
123 self.total_time = tk.DoubleVar() | |
124 self.filename_var = tk.StringVar() | |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
125 self.song_uri = None |
217 | 126 |
227 | 127 self.pre_post_names = showconfig.prePostSong() |
128 | |
129 self.last_poll_time = None | |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
130 self.last_autopause_time = None |
227 | 131 |
217 | 132 self.pollStatus() |
227 | 133 |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
134 self.mpd_is_lying = False # mpd reports bad times in certain intervals |
227 | 135 |
136 def smoothCurrentTime(self): | |
137 """like self.current_time.get, but more accurate""" | |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
138 |
227 | 139 if self.last_poll_time and self.state.get() == 'play': |
140 dt = time.time() - self.last_poll_time | |
141 else: | |
142 dt = 0 | |
143 return self.current_time.get() + dt | |
144 | |
217 | 145 def pollStatus(self): |
227 | 146 if self.state.get() == 'stop': |
147 self.current_time.set(-4) | |
148 | |
217 | 149 self.mpd.status().addCallback(self.pollStatus2) |
150 | |
227 | 151 def pollStatus2(self, stat): |
292
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
152 try: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
153 if self.state.get() != stat.state: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
154 self.state.set(stat.state) |
227 | 155 |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
156 if hasattr(stat, 'time_elapsed'): |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
157 elapsed = stat.time_elapsed |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
158 songnum = stat.song |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
159 total = stat.time_total |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
160 if self.mpd_is_lying and elapsed < 3: |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
161 self.mpd_is_lying = False |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
162 |
292
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
163 # mpd lies about elapsed, song, and total during the last |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
164 # .5sec of each song. so we coast through that part |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
165 if elapsed > total - .75 or self.mpd_is_lying: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
166 if not self.mpd_is_lying: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
167 self.mpd_is_lying = True |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
168 self.true_song_total = songnum, total |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
169 self.marked_time = time.time() |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
170 self.marked_val = elapsed |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
171 elapsed = self.marked_val + (time.time() - self.marked_time) |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
172 songnum, total = self.true_song_total |
217 | 173 |
292
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
174 t = -1 |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
175 if songnum == 1: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
176 t = elapsed |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
177 elif songnum == 0: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
178 t = elapsed - total |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
179 elif songnum == 2: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
180 t = self.total_time.get() + elapsed |
227 | 181 |
292
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
182 self.current_time.set(t) |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
183 |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
184 self.last_poll_time = time.time() |
227 | 185 |
292
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
186 self.check_autopause() |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
187 finally: |
e841bea500c3
guard against some errors when mpd is playing other music
drewp@bigasterisk.com
parents:
276
diff
changeset
|
188 reactor.callLater(.05, self.pollStatus) |
217 | 189 |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
190 def set_total_time(self, song): |
243
fff8762db48a
finished incomplete patch- asco now measures the length of songs (only for .wav)
drewp@bigasterisk.com
parents:
242
diff
changeset
|
191 # currently only good for .wav |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
192 p = showconfig.songOnDisk(song) |
243
fff8762db48a
finished incomplete patch- asco now measures the length of songs (only for .wav)
drewp@bigasterisk.com
parents:
242
diff
changeset
|
193 self.total_time.set(wavelength.wavelength(p)) |
242
561b4202461d
fixing extra audio stutter - this is currently broken
drewp@bigasterisk.com
parents:
241
diff
changeset
|
194 |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
195 def play(self, song=None): |
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
196 if song is None: |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
197 self.mpd.play() |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
198 return |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
199 |
220
13c089886f61
added the forgotten curve.py; mpd song path fix
drewp@bigasterisk.com
parents:
218
diff
changeset
|
200 self.mpd.clear() |
308 | 201 self.mpd.add(showconfig.songInMpd(MUS['preSong'])) |
202 self.mpd.add(showconfig.songInMpd(song)) | |
203 self.mpd.add(showconfig.songInMpd(MUS['postSong'])) | |
403
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
204 |
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
205 self.fillCache(song) |
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
206 |
308 | 207 self.filename_var.set(graph.value(song, L9['showPath'])) |
208 self.song_uri = song | |
227 | 209 |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
210 self.set_total_time(song) |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
211 self.seek_to(-4) |
217 | 212 |
403
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
213 def fillCache(self, song): |
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
214 """read the song's entire wav file into memory just before |
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
215 playing, so that mpd should never hit the disk during |
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
216 playback. On score in 2007, we had some mpd stutters that were |
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
217 always timed with a disk read.""" |
404
25308bc6d767
cache filling now prints
Drew Perttula <drewp@bigasterisk.com>
parents:
403
diff
changeset
|
218 p = showconfig.songOnDisk(song) |
25308bc6d767
cache filling now prints
Drew Perttula <drewp@bigasterisk.com>
parents:
403
diff
changeset
|
219 print "reading %s to prime the cache" % p |
25308bc6d767
cache filling now prints
Drew Perttula <drewp@bigasterisk.com>
parents:
403
diff
changeset
|
220 open(p).read() |
403
26a73a4647cb
ascoltami cache filling
Drew Perttula <drewp@bigasterisk.com>
parents:
363
diff
changeset
|
221 |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
222 def check_autopause(self): |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
223 pause_time = self.total_time.get() + self.song_pad_time |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
224 t = self.current_time.get() |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
225 if (self.state.get() == "play" and |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
226 self.last_autopause_time < pause_time < t): |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
227 self.mpd.pause() |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
228 self.last_autopause_time = t |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
229 |
217 | 230 def stop(self): |
227 | 231 self.mpd.seek(seconds=0, song=0) |
217 | 232 self.mpd.stop() |
233 | |
234 def seek_to(self, time): | |
227 | 235 if time < 0: |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
236 # seeking to anything within my 4-sec silence ogg goes |
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
237 # right to zero. maybe ogg seeking is too coarse? |
227 | 238 self.mpd.seek(seconds=time - (-4), song=0) |
239 elif time > self.total_time.get(): | |
240 self.mpd.seek(seconds=time - self.total_time.get(), song=2) | |
241 else: | |
242 self.mpd.seek(seconds=time, song=1) | |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
243 self.last_autopause_time = time |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
244 |
331
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
245 def skip_intro(self): |
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
246 self.seek_to(0) |
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
247 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
248 def in_post(self): |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
249 return (self.current_time.get() > self.total_time.get() + |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
250 self.song_pad_time) |
217 | 251 |
252 def play_pause_toggle(self): | |
253 def finish(status): | |
254 if status.state == 'play': | |
255 self.mpd.pause() | |
256 else: | |
257 self.mpd.play() | |
258 self.mpd.status().addCallback(finish) | |
259 | |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
260 def pause(self): |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
261 self.mpd.pause() |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
262 |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
263 def skip_to_post(self): |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
264 self.seek_to(self.total_time.get() + self.song_pad_time) |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
265 self.play() |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
266 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
267 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
268 class GoButton: |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
269 def __init__(self, player, statusLabel, songURIs): |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
270 self.player = player |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
271 self.statusLabel = statusLabel |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
272 self.songURIs = songURIs |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
273 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
274 self.player.current_time.trace("w", self.updateStatus) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
275 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
276 def _nextAction(self): |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
277 state = self.player.state.get() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
278 if state == 'stop': |
363 | 279 currentPath = self.player.song_uri |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
280 try: |
461
b0954240778d
fix bogus asco error after last song. Untested.
drewp@bigasterisk.com
parents:
434
diff
changeset
|
281 nextPath = self.songURIs[self.songURIs.index(currentPath) + 1] |
b0954240778d
fix bogus asco error after last song. Untested.
drewp@bigasterisk.com
parents:
434
diff
changeset
|
282 except (ValueError, IndexError): |
b0954240778d
fix bogus asco error after last song. Untested.
drewp@bigasterisk.com
parents:
434
diff
changeset
|
283 nextPath = self.songURIs[0] |
b0954240778d
fix bogus asco error after last song. Untested.
drewp@bigasterisk.com
parents:
434
diff
changeset
|
284 |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
285 return ("next song %s" % shortSongPath(nextPath, self.songURIs), |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
286 lambda: self.player.play(nextPath)) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
287 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
288 if state == 'pause': |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
289 return "play", self.player.play |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
290 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
291 if state == 'play': |
331
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
292 if self.player.current_time.get() < 0: |
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
293 return "skip intro", self.player.skip_intro |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
294 if self.player.in_post(): |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
295 return "<nothing>", lambda: None |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
296 return "skip to post", self.player.skip_to_post |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
297 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
298 def action(self): |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
299 desc, func = self._nextAction() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
300 func() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
301 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
302 def updateStatus(self, *args): |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
303 desc, func = self._nextAction() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
304 self.statusLabel.config(text=desc) |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
305 |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
306 |
217 | 307 |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
308 def buildsonglist(root, graph, songs, player): |
217 | 309 songlist=tk.Frame(root,bd=2,relief='raised',bg='black') |
310 | |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
311 maxsfwidth=max([len(graph.label(song)) for song in songs]) |
217 | 312 |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
313 for i,song in enumerate(songs): |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
314 b=tk.Button(songlist,text=graph.label(song),width=maxsfwidth, |
217 | 315 anchor='w',pady=0,bd=0,relief='flat', |
235 | 316 font="arial 14 bold") |
217 | 317 b.bind("<Configure>",lambda ev,b=b: |
235 | 318 b.config(font="arial %d bold" % min(12,int((ev.height-3)*.8)))) |
217 | 319 try: |
320 # rainbow colors | |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
321 frac=i/len(songs) |
217 | 322 b.config(bg='black', |
323 fg="#%02x%02x%02x" % tuple([int(255*(.7+.3* | |
324 math.sin(frac*4+x)) | |
325 ) for x in 1,2,3])) | |
326 except Exception,e: | |
327 print "rainbow failed: %s"%e | |
328 | |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
329 b.config(command=lambda song=song: player.play(song)) |
217 | 330 b.pack(side='top',fill='both',exp=1,padx=0,pady=0,ipadx=0,ipady=0) |
331 | |
332 | |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
333 def color_buttons(x, y, z, song=song, b=b): |
217 | 334 name = player.filename_var.get() |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
335 if name == graph.value(song, L9['showPath']): |
217 | 336 b['bg'] = 'grey50' |
337 else: | |
338 b['bg'] = 'black' | |
339 player.filename_var.trace("w", color_buttons) | |
340 return songlist | |
218 | 341 |
217 | 342 |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
343 class TimeScale(tk.Scale): |
218 | 344 def __init__(self,master,player): |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
345 tk.Scale.__init__(self, master, orient="horiz", |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
346 from_=-4,to_=100, |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
347 sliderlen=20,width=20, |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
348 res=0.001, |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
349 showvalue=0, |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
350 troughcolor='black', |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
351 bg='lightblue3', |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
352 ) |
217 | 353 |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
354 self.player = player |
217 | 355 |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
356 self.dragging = False |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
357 self.button_down = False |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
358 self.drag_start_player_state = None |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
359 |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
360 self.bind("<ButtonPress-1>", self.b1down) |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
361 self.config(command=self.scale_changed) |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
362 self.bind("<ButtonRelease-1>", self.b1up) |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
363 |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
364 self.player.current_time.trace('w', self.current_time_changed) |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
365 |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
366 def current_time_changed(self, *args): |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
367 """attach player.current_time to scale (one-way)""" |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
368 if not self.dragging: |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
369 self.set(self.player.current_time.get()) |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
370 |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
371 def b1down(self,evt): |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
372 self.button_down = True |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
373 self.dragging = False |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
374 |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
375 def scale_changed(self, time): |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
376 if not self.button_down: |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
377 return |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
378 |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
379 if not self.dragging: |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
380 self.dragging = True |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
381 self.drag_start_player_state = self.player.state.get() |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
382 if self.drag_start_player_state == "play": |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
383 # due to mpd having to seemingly play a whole block at |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
384 # every new seek point, it is better to pause playback |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
385 # while the mouse is down |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
386 self.player.pause() |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
387 |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
388 # ok to seek around when paused. this keeps the displayed time |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
389 # up to date, which is how the user knows where he is |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
390 self.player.seek_to(float(time)) |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
391 |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
392 def b1up(self,evt): |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
393 self.button_down = False |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
394 self.dragging = False |
245
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
395 |
feb7910eb6d4
scrubbing while playing works pretty well now
drewp@bigasterisk.com
parents:
244
diff
changeset
|
396 if self.drag_start_player_state == "play": |
244
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
397 self.player.play() |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
398 |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
399 class Seeker(tk.Frame): |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
400 """includes scale AND labels below it""" |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
401 def __init__(self,master,player): |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
402 tk.Frame.__init__(self,master,bg='black') |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
403 |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
404 self.scl = TimeScale(self,player) |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
405 self.scl.pack(fill='x',side='top') |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
406 |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
407 self.buildstatus(player) |
1f7edb2e4724
asco scale now pauses while you seek (mostly)
drewp@bigasterisk.com
parents:
243
diff
changeset
|
408 |
217 | 409 |
218 | 410 def buildstatus(self,player): |
411 left_var=tk.DoubleVar() | |
412 for txt,var,fmt in (('Current',player.current_time,"%.2f"), | |
413 ('Song len',player.total_time,"%.2f",), | |
414 ('Left',left_var, "%.2f"), | |
415 ('Song',player.filename_var, "%s"), | |
416 ('State', player.state, "%s")): | |
417 tk.Label(self,text=txt, | |
418 relief='raised',bd=1,font='arial 9', | |
223 | 419 **appstyle).pack(side='left',fill='y') |
218 | 420 l = tk.Label(self,width=7, anchor='w', text=var.get(), |
331
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
421 relief='ridge',bd=1,font='arial 12 bold', |
223 | 422 padx=2,pady=2, |
218 | 423 bg='#800000',fg='white') |
424 l.pack(side='left',expand=1, fill='x') | |
425 | |
426 var.trace_variable('w', | |
427 lambda a,b,c,l=l,fmt=fmt,var=var: | |
428 l.config(text=fmt % var.get())) | |
429 | |
430 # update end time as the song changes | |
431 player.total_time.trace("w",lambda *args: ( | |
432 self.scl.config(to_=player.total_time.get()+15))) | |
217 | 433 |
218 | 434 def fixleft(*args): |
435 # update time-left variable | |
436 left_var.set(player.total_time.get()-player.current_time.get()) | |
437 | |
438 if player.current_time.get() < 0 or left_var.get() < 0: | |
439 self.scl['troughcolor'] = 'blue' | |
440 else: | |
441 self.scl['troughcolor'] = 'black' | |
442 | |
443 player.total_time.trace("w",fixleft) | |
444 player.current_time.trace("w",fixleft) | |
217 | 445 |
218 | 446 class ControlButtons(tk.Frame): |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
447 def __init__(self, master, goButton, player, root): |
218 | 448 tk.Frame.__init__(self,master,bg='black') |
449 self.statebuttons = {} # lowercased name : Button | |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
450 self.goButton = goButton |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
451 self.player = player |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
452 for tag, txt,cmd,key in [ |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
453 ('stop', |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
454 'Stop\nC-s', player.stop, "<Control-s>"), |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
455 ('pause', |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
456 'Pause\nC-p', player.play_pause_toggle, "<Control-p>"), |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
457 ('skip intro', |
331
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
458 'Skip Intro\nC-i', player.skip_intro, "<Control-i>"), |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
459 ('skip to post', |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
460 'Skip to Post\nC-t', player.skip_to_post, "<Control-t>"), |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
461 ('go', 'Go\nspace', self.goButton.action, "<Key-space>"), |
241
0a2239379466
added autopause. workaround for mpd's incorrect times
drewp@bigasterisk.com
parents:
235
diff
changeset
|
462 ]: |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
463 b = tk.Button(self, text=txt, command=cmd, |
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
464 font='arial 16 bold', |
218 | 465 height=3,**appstyle) |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
466 b.pack(side='left', fill='both', expand=True) |
218 | 467 # keyboard bindings |
468 root.bind(key, lambda evt, cmd=cmd: cmd()) | |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
469 self.statebuttons[tag] = b |
218 | 470 |
471 def update_state_buttons(self,*args): | |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
472 state = self.player.state.get() |
218 | 473 |
474 if state in ('stop', 'pause'): | |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
475 self.statebuttons['pause']['text'] = 'Play\nC-p' |
218 | 476 else: |
328
2961f5437f31
autopause now runs every time player passes the pad end
Drew Perttula <drewp@bigasterisk.com>
parents:
308
diff
changeset
|
477 self.statebuttons['pause']['text'] = 'Pause\nC-p' |
218 | 478 |
479 colors = {'stop' : 'red', | |
480 'play' : 'blue', | |
481 'pause' : 'green'} # very confusing -- play and pause supply colors | |
482 # for each other! | |
483 for name, button in self.statebuttons.items(): | |
484 if name == 'pause' and state not in ('stop', 'pause'): | |
485 name = 'play' | |
486 | |
487 if state == name: # name gets changed sometimes for 'pause' -- see right above | |
488 button['bg'] = colors.get(name, 'black') | |
489 else: | |
490 button['bg'] = 'black' | |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
491 self.goButton.updateStatus() |
217 | 492 |
493 ############################ | |
494 | |
304
5f9cf6174e62
ascoltami now uses rdf for config
Drew Perttula <drewp@bigasterisk.com>
parents:
292
diff
changeset
|
495 |
217 | 496 |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
497 def main(): |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
498 global graph |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
499 parser = OptionParser() |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
500 parser.add_option('--show', |
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
501 help='show URI, like http://light9.bigasterisk.com/show/dance2008') |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
502 graph = showconfig.getGraph() |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
503 (options, songfiles) = parser.parse_args() |
217 | 504 |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
505 if len(songfiles)<1: |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
506 graph = showconfig.getGraph() |
429
41aa6895b3e6
ascoltami: local pympd import; cmdline ui
drewp@bigasterisk.com
parents:
423
diff
changeset
|
507 if not options.show: |
41aa6895b3e6
ascoltami: local pympd import; cmdline ui
drewp@bigasterisk.com
parents:
423
diff
changeset
|
508 raise ValueError("missing --show http://...") |
423
2b2f5da47c5d
config file now lists paths in the same form you'd give to mpd. New cmdline on ascoltami to specify the song list from config.n3
drewp@bigasterisk.com
parents:
404
diff
changeset
|
509 playList = graph.value(URIRef(options.show), L9['playList']) |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
510 songs = list(graph.items(playList)) |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
511 else: |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
512 raise NotImplementedError("don't know how to make rdf song nodes from cmdline song paths") |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
513 |
217 | 514 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
515 root=tk.Tk() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
516 root.wm_title("ascoltami") |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
517 toplevelat("ascoltami", root) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
518 root.config(bg="black") |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
519 player=Player() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
520 |
334
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
521 songlist = buildsonglist(root, graph, songs, player) |
42e4c4728a66
ascoltami, subcomposer, keyboardcomposer use rdf show data; raise channel count to 270
drewp@bigasterisk.com
parents:
331
diff
changeset
|
522 songlist.pack(fill='both',exp=1) |
217 | 523 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
524 seeker = Seeker(root, player) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
525 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
526 goRow = tk.Frame(root) |
331
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
527 tk.Label(goRow, text="Go button action", |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
528 font='arial 9', **appstyle).pack(side='left', fill='both') |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
529 goStatus = tk.Label(goRow, font='arial 12 bold', **appstyle) |
331
c579174d73b2
go button now skips intros
Drew Perttula <drewp@bigasterisk.com>
parents:
330
diff
changeset
|
530 goStatus.config(bg='#800000', fg='white', relief='ridge') |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
531 goStatus.pack(side='left', expand=True, fill='x') |
217 | 532 |
335 | 533 go = GoButton(player, goStatus, songs) |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
534 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
535 buts = ControlButtons(root, go, player, root) |
217 | 536 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
537 songlist.pack(fill='both', expand=True) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
538 buts.pack(side='top', fill='x') |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
539 seeker.pack(side='top', fill='x') |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
540 goRow.pack(side='top', fill='x') |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
541 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
542 player.state.trace_variable('w', buts.update_state_buttons) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
543 buts.update_state_buttons() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
544 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
545 tksupport.install(root,ms=10) |
217 | 546 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
547 try: |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
548 reactor.listenTCP(networking.musicPort(),server.Site(XMLRPCServe(player))) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
549 print "started server on %s" % networking.musicPort() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
550 except CannotListenError: |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
551 print "no server started- %s is in use" % networking.musicPort() |
217 | 552 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
553 root.bind("<Destroy>",lambda ev: reactor.stop) |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
554 root.protocol('WM_DELETE_WINDOW', reactor.stop) |
217 | 555 |
330
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
556 reactor.run() |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
557 |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
558 if __name__ == '__main__': |
1a34a0e118cc
ascoltami: new 'go' button that does the Right Thing during a show
Drew Perttula <drewp@bigasterisk.com>
parents:
328
diff
changeset
|
559 main() |