Solved: Control Raspberry Pi media center (Kodi) with Roku TV’s remote over HDMI CEC

TL;DR if you already figured out the documented stuff: Enable 2-way CEC (keypresses from TV remote to attached device) in the Roku secret menu: Quickly (within ~ 5 seconds) press Home 5 times, rewind, down, fast forward, down, rewind, and “Enable CEC Remote Control”.

The options for viewing local content on my new Roku TV are somewhat lacking due to the limited set of file formats internally supported1. But long story short, Santa just brought me a Raspberry Pi 5, and setting it up as a lightweight home media server scratches several itches. One thing I’d like to avoid, though, is the neverending proliferation of device-specific remote controls and the training that goes with them, especially for the wife/kids/parents/guests. The TV already has an easy-to-use remote supporting the basic “10 foot interface” (directional arrows to scroll through media titles, OK/enter and playback controls)… wouldn’t it be great if you could just flip to the RPI media center’s input and then use that same remote, already in your hand, on its interface?

Long story short, yes, on many modern TVs you can totally hook up a Raspberry Pi running Kodi or a similar home theater interface over HDMI and, through the magic of HDMI-CEC, have the TV forward the remote keypresses over the HDMI cable. However, some (most? all?) Roku devices don’t enable this out-of-the-box and you need to enter a secret menu to fully enable it.

Setup steps:

Roku TV side:

  • First off, make sure HDMI-CEC is enabled in the first place. On my TV this was under Settings -> System -> Control other devices (CEC). The options in this menu are pretty basic, but it will show a list of detected devices by HDMI port, so you can at least rule out basic issues (bad/unsupported cable, not enabled Pi side, etc.) and see if the device is being detected here.
  • Confirm your Pi / playback device is plugged into an HDMI port that supports CEC; on some, particularly older Roku devices, there may be multiple HDMI inputs but only some of them support CEC (check for special marking on the port labeling). Note, this is unrelated to ARC/eARC, and you do not need to be plugged into the/a ARC port for it to work.
  • The secret ingredient! By default, many Roku devices only enable very basic, mainly 1-way (attached device to TV) communication, enough to e.g. switch to the correct input or control volume from the attached device. To enable 2-way communication of remote-control button presses, enter the Roku “TV Secret Screen”: Navigate to the home screen, then quickly (~ 5 seconds), on the remote press: Home 5 times, rewind, down, fast forward, down, rewind. This presents a secret menu with some decidedly developer-y stuff, and mixed in among it, the option to “Enable CEC Remote Control”. Select this option. When enabled, the text will change to “Disable CEC Remote Control”.
“Welcome to warp zone”

Raspberry Pi side:

  • On Raspberry Pi 5, there are two (micro-)HDMI ports, but only the leftmost one (HDMI0, nearest the USB-C power input) supports CEC. Be sure to plug into this one. You may need to reboot the Pi when changing outputs to ensure output is enabled to the correct port.
  • CEC is not natively supported on many desktop video cards or SBCs, likely including at least some older Raspberry Pi flavors. For these devices, there are workarounds such as the Pulse Eight USB adapter (preferred solution for Kodi/LibreELEC) or homeassistant-addon-pi-cec for HomeAssistant (software solution, sends the CEC equivalent data via TCP/IP instead).
  • Make sure libCEC is installed and any related settings are enabled in your preferred media software. I’ve only tested this with the specific combination of Kodi on the LibreELEC distro, but for the RPI5 distribution as of 12/27/2023 all the CEC stuff is basically set up and working out-of-the-box. For me, once the basic CEC link was functional (enabled in the TV’s non-secret menu), I was getting some notification sounds and a brief popup on the top-right corner of the screen refencing “Pulse Eight”, even when using the RPI5’s native CEC support.
    • For my particular Roku TV/remote combo, all the (supported) buttons were recognized and correcly mapped already, but YMMV for more obscure TVs/remotes To this day the official guidance for dealing with remotes with unrecognized button mappings is to enable a debug log, press all the keys in a specific order and manually chew threw 50-80KB of diagnostic log to find out what event codes were received, then manually poke these into an XML file somewhere. Reading this logfile natively from the Kodi interface is a…less than fun experience.

With this, the Roku TV’s remote smoothly navigates the Kodi UI. Not all remote buttons are passed through, but the most important ones at least are covered.

What works:

  • Directional (up/down/left/right) and “OK” buttons
  • Back button
  • Playback control buttons (play/pause/rewind/fastforward)

The remaining buttons, including reserved (“*”, Home, Power), volume and shortcut buttons are still handled by the TV itself and not passed through over CEC (at least, I could not see any unmapped codes by eyeballing Kodi’s debug log). It probably goes without saying that e.g. the Netflix button still just takes you to Netflix and can’t be repurposed for a custom Kodi function. I’d love to be proven wrong about this though.

There are many distinct devices referred to as “Roku TVs”; this was tested on the Best Buy exclusive “Class Select Series 4k” (50R4A5R), but the same secret menu is reported to be the missing ingredient for several others, including TCL and HiSense branded units.

Huge hat tip to this reddit thread for the hidden menu, which references an even older thread with the solution, neither of which came up readily with the usual search terms. Posting here as a note to my future self and in the vain hope it rises above the AI-generated noise in future searches.

  1. See https://developer.roku.com/docs/specs/media/streaming-specifications.md . In particular, older formats like MPEG2, let alone the usual mix of proprietary AVI/MOV/etc. are not supported. The developer API is consists of a scripting language that mostly deals with skinning and finding URLs, so 3rd party player apps (“channels”) are likewise limited to these formats – you can’t just port VLC to it and call it a day. ↩︎

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *