Skip to content

Instantly share code, notes, and snippets.

@ednisley ednisley/Streamer.py
Last active Jun 15, 2016

Embed
What would you like to do?
Python source code: Raspberry Pi Streaming Radio Player
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']],
'KEY_KP8' : ['Jazz',['mplayer','-playlist','http://stream2138.init7.net/listen.pls']],
'KEY_KP9' : ['WMHT',['mplayer','http://live.str3am.com:2070/wmht1']],
'KEY_KP4' : ['Classic 1000',['mplayer','-playlist','http://listen.radionomy.com/1000classicalhits.m3u']],
'KEY_KP5' : ['DCNY 911',['mplayer','-playlist','http://www.broadcastify.com/scripts/playlists/1/12305/-5857889408.m3u']],
'KEY_KP6' : ['WAMC',['mplayer','http://pubint.ic.llnwd.net/stream/pubint_wamc']],
'KEY_KP1' : ['60s',['mplayer','-playlist','http://listen.radionomy.com/all60sallthetime-keepfreemusiccom.m3u']],
'KEY_KP2' : ['50-70s',['mplayer','-playlist','http://listen.radionomy.com/golden-50-70s-hits.m3u']],
'KEY_KP3' : ['Soft Rock',['mplayer','-playlist','http://listen.radionomy.com/softrockradio.m3u']],
'KEY_KP0' : ['Zen',['mplayer','-playlist','http://listen.radionomy.com/zen-for-you.m3u']]
}
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!'
@ednisley

This comment has been minimized.

Copy link
Owner Author

ednisley commented Jun 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.