Using the TV remote to control omxplayer on Raspberry Pi
I have a Raspberry Pi connected to my TV via HDMI. Despite having tried OpenELEC as a media center, I have other services running on that machine and I am just too console-oriented to select media through a graphical interface. I use a laptop to start films, but I was missing a way to pause or rewind playback. I finally solved it in a elegant way, using HDMI CEC.
HDMI is not just a standard for transferring video — it also supports control commands. For example, a TV can ask the player to pause using the TV's own remote, instead of needing a separate one. The RPi can also ask the TV to switch on and change to the relevant HDMI input. Fantastic.
The challenges:
- Get the input from the remote.
cec-clientprovides push/release events. On Raspbian:apt-get install cec-client. - Send commands to the running
omxplayer. We use terminal mixer (tm), written by Lluís Batlle i Rossell. The idea is simple: runtm -wt omxplayer, then send commands from anywhere withecho -n COMMAND | tm -t. Install with./configure && make && make install.
This script uses bash coprocesses, a beautiful feature of the shell:
#! /bin/bash -eu
# Launch a coprocessor that provides CEC input data.
# "pow 0" powers on the display at start. Then we wait for events.
# --line-buffered is essential for real-time response.
coproc cecclient { echo -e 'pow 0\nas'| cec-client |
grep -e "key pressed" -e "key released" --line-buffered ; }
function cmd {
# Start tm if not running yet
[ ${tm_PID:-0} != 0 ] || coproc tm { tm -t; }
# Send command, ignore errors (common when omxplayer ends)
echo -ne "$1" >&"${tm[1]}" || echo -e "Cannot send command\a"
}
# Read from the coprocessor's output
while read -u ${cecclient[0]} L
do
echo $L ## Debugging
K=$(sed -n 's/.*key pressed: \([^ ]*\).*$/\1/p' <<< "$L" )
R=$(sed -n 's/.*key released: \([^ ]*\).*$/\1/p' <<< "$L" )
case $K in
select|pause) cmd ' ' ;;
backward|rewind) cmd '\e[D' ;;
forward|Fast) cmd '\e[C' ;;
up) cmd '+' ;;
down) cmd '-' ;;
left) cmd i ;;
right) cmd o ;;
F1) cmd 'n' ;;
F2) cmd 'm' ;;
F3) cmd 's' ;;
F4) cmd 'k' ;;
exit) sudo reboot ;;
*) echo Unknown press: $K ;;
esac
case $R in
stop) cmd q ;;
*) echo Unknown release: $R ;;
esac
doneLaunching omxplayer
Modify the omxplayer wrapper script to prefix the omxplayer.bin invocation with tm -wt. Alternatively, always run tm -wt omxplayer ... or set up an alias.
Configuring the TV
Enable CEC on your TV (usually found in HDMI settings, sometimes called "Anynet+", "Bravia Sync", "SimpLink", etc.).
Future work
A nice improvement would be to launch cec-client only while omxplayer is running, saving processor time and avoiding interference with other CEC clients. The challenge is cleanly killing this script — including its two coprocesses — when omxplayer exits.