|
from evdev import InputDevice,ecodes,KeyEvent |
|
import subprocess32 as subprocess |
|
import select |
|
import re |
|
import sys |
|
import time |
|
|
|
Media = {'KEY_KP7' : ['Classical',['mplayer','-playlist','http://stream2137.init7.net/listen.pls'%5D%5D, |
|
'KEY_KP8' : ['Jazz',['mplayer','-playlist','http://stream2138.init7.net/listen.pls'%5D%5D, |
|
'KEY_KP9' : ['WMHT',['mplayer','http://live.str3am.com:2070/wmht1'%5D%5D, |
|
'KEY_KP4' : ['Classic 1000',['mplayer','-playlist','http://listen.radionomy.com/1000classicalhits.m3u'%5D%5D, |
|
'KEY_KP5' : ['DCNY 911',['mplayer','-playlist','http://www.broadcastify.com/scripts/playlists/1/12305/-5857889408.m3u'%5D%5D, |
|
'KEY_KP6' : ['WAMC',['mplayer','http://pubint.ic.llnwd.net/stream/pubint_wamc'%5D%5D, |
|
'KEY_KP1' : ['60s',['mplayer','-playlist','http://listen.radionomy.com/all60sallthetime-keepfreemusiccom.m3u'%5D%5D, |
|
'KEY_KP2' : ['50-70s',['mplayer','-playlist','http://listen.radionomy.com/golden-50-70s-hits.m3u'%5D%5D, |
|
'KEY_KP3' : ['Soft Rock',['mplayer','-playlist','http://listen.radionomy.com/softrockradio.m3u'%5D%5D, |
|
'KEY_KP0' : ['Zen',['mplayer','-playlist','http://listen.radionomy.com/zen-for-you.m3u'%5D%5D |
|
} |
|
|
|
CurrentKC = 'KEY_KP7' |
|
|
|
Controls = {'KEY_KPSLASH' : '//////', |
|
'KEY_KPASTERISK' : '******', |
|
'KEY_KPENTER' : ' ', |
|
'KEY_KPMINUS' : '<', |
|
'KEY_KPPLUS' : '>', |
|
'KEY_VOLUMEUP' : '*', |
|
'KEY_VOLUMEDOWN' : '/' |
|
} |
|
|
|
MuteDelay = 5.5 # delay before non-music track; varies with buffering |
|
UnMuteDelay = 7.3 # delay after non-music track |
|
|
|
MixerChannel = 'PCM' # which amixer thing to use |
|
|
|
# set up event inputs and polling objects |
|
# This requires some udev magic to create the symlinks |
|
|
|
k = InputDevice('/dev/input/keypad') |
|
k.grab() |
|
|
|
kp = select.poll() |
|
kp.register(k.fileno(),select.POLLIN + select.POLLPRI + select.POLLERR) |
|
|
|
v = InputDevice('/dev/input/volume') |
|
v.grab() |
|
|
|
vp = select.poll() |
|
vp.register(v.fileno(),select.POLLIN + select.POLLPRI + select.POLLERR) |
|
|
|
# set up files for mplayer pipes |
|
|
|
lw = open('/tmp/mp.log','w') # mplayer piped output |
|
lr = open('/tmp/mp.log','r') # … reading that output |
|
|
|
# set the mixer output low enough that the initial stream won't wake the dead |
|
|
|
subprocess.call(['amixer','sset',MixerChannel,'10']) |
|
|
|
# Start the player with the default stream |
|
|
|
print 'Starting mplayer on',Media[CurrentKC][0],' -> ',Media[CurrentKC][-1][-1] |
|
p = subprocess.Popen(Media[CurrentKC][-1], |
|
stdin=subprocess.PIPE,stdout=lw,stderr=subprocess.STDOUT) |
|
print ' … running' |
|
|
|
#——————– |
|
#— Play the streams |
|
|
|
while True: |
|
|
|
# pluck next line from mplayer and decode it |
|
|
|
text = lr.readline() |
|
if 'ICY Info: ' in text: # these lines may contain track names |
|
trkinfo = text.split(';') # also splits at semicolon embedded in track name |
|
for ln in trkinfo: |
|
if 'StreamTitle' in ln: # this part contains a track name |
|
if 2 == ln.count("'"): # exactly two single quotes = probably none embedded in track name |
|
trkhit = re.search(r"StreamTitle='(.*)'",ln) |
|
if trkhit: # true for valid search results |
|
TrackName = trkhit.group(1) # the string between the two quotes |
|
print 'Track name: ', TrackName |
|
if ('' == TrackName or 'TargetSpot' in TrackName) and 'radionomy' in Media[CurrentKC][-1][-1]: |
|
print ' … muting empty Radionomy track' |
|
time.sleep(MuteDelay) |
|
subprocess.call(['amixer','-q','sset',MixerChannel,'mute']) |
|
else: |
|
print ' … unmuting' |
|
time.sleep(UnMuteDelay) |
|
subprocess.call(['amixer','-q','sset',MixerChannel,'unmute']) |
|
else: |
|
print ' … semicolon in track name: ', ln |
|
else: |
|
print ' … quotes in track name: ', ln |
|
elif 'Exiting…' in text: |
|
print 'Got EOF / stream cutoff' |
|
print ' … killing dead mplayer' |
|
p.kill() |
|
print ' … flushing pipes' |
|
lw.truncate(0) |
|
print ' … discarding keys' |
|
while [] != kp.poll(0): |
|
kev = k.read |
|
print ' … restarting mplayer: ',Media[CurrentKC][0] |
|
p = subprocess.Popen(Media[CurrentKC][-1], |
|
stdin=subprocess.PIPE,stdout=lw,stderr=subprocess.STDOUT) |
|
print ' … running' |
|
continue |
|
|
|
# accept pending events from volume control knob |
|
|
|
if [] != vp.poll(10): |
|
vev = v.read() |
|
for e in vev: |
|
if e.type == ecodes.EV_KEY: |
|
kc = KeyEvent(e).keycode |
|
|
|
# print 'Volume kc: ',kc |
|
|
|
if kc in Controls: |
|
print 'Vol Control: ',kc |
|
try: |
|
p.stdin.write(Controls[kc]) |
|
except Exception as e: |
|
print "Can't send control: ",e |
|
print ' … restarting player: ',Media[CurrentKC][0] |
|
p = subprocess.Popen(Media[CurrentKC][-1], |
|
stdin=subprocess.PIPE,stdout=lw,stderr=subprocess.STDOUT) |
|
print ' … running' |
|
|
|
|
|
# accept pending events from keypad |
|
|
|
if [] != kp.poll(10): |
|
kev = k.read() |
|
for e in kev: |
|
if e.type == ecodes.EV_KEY: |
|
kc = KeyEvent(e).keycode |
|
|
|
if kc == 'KEY_NUMLOCK': |
|
continue |
|
|
|
# print 'Got: ',kc |
|
|
|
if (kc == 'KEY_BACKSPACE') and (KeyEvent(e).keystate == KeyEvent.key_hold): |
|
if True: |
|
print 'Backspace = shutdown!' |
|
p = subprocess.call(['sudo','shutdown','-HP','now']) |
|
else: |
|
print 'BS = bail from main, ssh to restart!' |
|
sys.exit(0) |
|
|
|
if KeyEvent(e).keystate != KeyEvent.key_down: |
|
continue |
|
|
|
if kc in Controls: |
|
print 'Control:', kc |
|
try: |
|
p.stdin.write(Controls[kc]) |
|
except Exception as e: |
|
print "Can't send control: ",e |
|
print ' … restarting player: ',Media[CurrentKC][0] |
|
p = subprocess.Popen(Media[CurrentKC][-1], |
|
stdin=subprocess.PIPE,stdout=lw,stderr=subprocess.STDOUT) |
|
print ' … running' |
|
|
|
if kc in Media: |
|
print 'Switching stream to ',Media[kc][0],' -> ',Media[kc][-1][-1] |
|
CurrentKC = kc |
|
print ' … halting player' |
|
try: |
|
p.communicate(input='q') |
|
except Exception as e: |
|
print 'Perhaps mplayer died?',e |
|
print ' … killing it for sure' |
|
p.kill() |
|
print ' … flushing pipes' |
|
lw.truncate(0) |
|
print ' … restarting player: ',Media[CurrentKC][0] |
|
p = subprocess.Popen(Media[CurrentKC][-1], |
|
stdin=subprocess.PIPE,stdout=lw,stderr=subprocess.STDOUT) |
|
print ' … running' |
|
|
|
print 'Out of loop!' |