With the numeric keypad producing events, and the USB audio box producing sound, the next steps involve starting mplayer
through Python’s subprocess interface and feeding keystrokes into it.
There’s not much to it:
- Raspberry Pi Model B+ running Raspbian Jessie Lite
- USB numeric keypad with sticky labels
- Behringer UCA202 USB Audio Interface (replacing the Creative Labs gadget)
- USB WiFi dongle (in power hog mode) on a short extension cable for better reception
As much hardware doc as you need:

The green plug leads off to a set of decent-quality PC speakers with far more bass drive than seems absolutely necessary in this context. The usual eBay vendor bungled an order for the adapter between the RCA line-out jacks and the 3.5 mm plug that will avoid driving the speakers from the UCA202’s headphone monitor output; I doubt that will make any audible difference. If you need an adapter with XLR female to 1/4 inch mono, let me know…
The keypad labels provide all the UI documentation there is:

The Python source code as a GitHub Gist:
from evdev import InputDevice,ecodes,KeyEvent | |
import subprocess32 | |
Media = {'KEY_KP7' : ['mplayer','http://relay.publicdomainproject.org:80/classical.aac'], | |
'KEY_KP8' : ['mplayer','http://relay.publicdomainproject.org:80/jazz_swing.aac'], | |
'KEY_KP9' : ['mplayer','http://live.str3am.com:2070/wmht1'], | |
'KEY_KP6' : ['mplayer','http://pubint.ic.llnwd.net/stream/pubint_wamc'], | |
'KEY_KP1' : ['mplayer','-playlist','http://dir.xiph.org/listen/5423257/listen.m3u'], | |
'KEY_KP2' : ['mplayer','-playlist','http://dir.xiph.org/listen/5197460/listen.m3u'], | |
'KEY_KP3' : ['mplayer','-playlist','http://dir.xiph.org/listen/5372471/listen.m3u'], | |
'KEY_KP0' : ['mplayer','-playlist','http://dir.xiph.org/listen/5420157/listen.m3u'] | |
} | |
Controls = {'KEY_KPSLASH' : '/', | |
'KEY_KPASTERISK' : '*', | |
'KEY_KPDOT' : ' ' | |
} | |
k=InputDevice('/dev/input/keypad') | |
print 'Starting mplayer' | |
p = subprocess32.Popen(Media['KEY_KP7'],stdin=subprocess32.PIPE) | |
print ' ... running' | |
for e in k.read_loop(): | |
if (e.type == ecodes.EV_KEY) and (KeyEvent(e).keystate == 1): | |
kc = KeyEvent(e).keycode | |
if kc == 'KEY_NUMLOCK': | |
continue | |
print "Got: ",kc | |
if kc == 'KEY_BACKSPACE': | |
print 'Backspace = shutdown!' | |
p = subprocess32.call(['sudo','halt']) | |
break | |
if kc in Controls: | |
print 'Control:', kc | |
p.stdin.write(Controls[kc]) | |
if kc in Media: | |
print 'Switching stream to ',Media[kc] | |
print ' ... halting' | |
p.communicate(input='q') | |
print ' ... restarting' | |
p = subprocess32.Popen(Media[kc],stdin=subprocess32.PIPE) | |
print ' ... running' | |
print "Out of loop!" |
The Media
dictionary relates keycodes with the command line parameters required to fire mplayer
at the streaming stations. With that running, the Controls
dictionary turns keycodes into mplayer
keyboard controls.
There’s no display: you have no idea what’s going on. I must start the program manually through an ssh
session and can watch mplayer
‘s console output.
Poking the Halt
button forcibly halts the RPi, after which you squeeze the Reset button to reboot the thing. There’s no indication that it’s running, other than sound coming out of the speakers, and no way to tell it fell of the rails other than through the ssh
session.
The loop blocks on events, so it can’t also extract stream titles from the (not yet implemented) mplayer stdout pipe / file and paste them on the (missing) display; that’s gotta go.
There’s a lot not to like about all that, of course, but it’s in the tradition of getting something working to discover how it fails and, in this case, how it sounds, which is even more important.
XLR to 1/4″? That’s an oddball (I have a couple of them I occasionally use, but I’m always getting into odd audio situations). I’m guessing what you wanted was double (i.e. stereo) male RCA to male 3.5mm stereo? That’s not even close. If you need the two-RCA to 3.5mm cable, I can send you one.
When I opened the package, I wondered what I was thinking when I ordered them. Turns out the bag labels were correct: somebody stuffed the wrong parts inside. I urged the seller to verify the replacements matched their own picture, but I have the sinking suspicion that I’ll eventually have ten XLR-to-1/4-inch adapters (after the eBay resolution window closes, because Chinese New Year).
The heap spat out some adapters sporting a long cord between their RCA and 3.5 mm ends to prove feasibility. I hoped smaller adapters would improve the, mmmmm, user experience by reducing the cable clutter…