In some cases, you may have an IR or Bluetooth remote control device that isn’t natively supported by Plex HTPC or you simply want to change the default actions for a remote. In that case, you can create an “inputmap” for the device so that you can not only use the device, but also customize how it works.
An inputmap is a plain text file, with contents in the JSON format (saved with a .json
suffix), which defines how Plex HTPC should interpret the button presses you use on the remote control device.
Default Inputmap Files
A normal installation of Plex HTPC also comes with multiple default inputmaps that you can use as examples for reference. You can find the files in the following the default locations:
- Windows:
C:\Users\USERNAME\AppData\Local\Plex HTPC\inputmaps\defaults
- macOS:
~/Library/Application Support/Plex HTPC/inputmaps/defaults
- linux:
~/snap/plex-htpc/common/inputmaps
- Flatpak:
$HOME/.var/app/tv.plex.PlexHTPC/data/plex/inputmaps
If you wish to use one of the example files as a starting point, do not edit and save the example file directly in this “defaults” folder as they will get overwritten whenever the app launches. Instead, make a copy of the file and save it in the “inputmaps” folder.
Inputmap File Basics
There are three parts to the file that are crucial for an inputmap to work:
- A
name
for the remote - An
idmatcher
regex string which matches what the remote presents itself with when trying to communicate with Plex HTPC - Button
mapping
, which controls what function is performed by a particular button
This is how the json file could look when you are done creating an inputmap with only two buttons and functions in it:
{
"name": "PS3 Controller",
"idmatcher": "PLAYSTATION(R)3.*",
"mapping":
{
"KEY_BUTTON_14": "enter",
"KEY_BUTTON_15": "stop"
}
}
We recommend that you download this controller skeleton json file (also attached at the end of the article) to use as a starting point. Open it up in a good text editor. Do not use a text editor set to rich text formatting. There are many text editors you can use, but you can see some popular choices below.
Tip!: Make sure that your text editor is in “plain text” mode (not rich text editing).
Related Page: Notepad++ (Windows; free)
Related Page: TextWrangler (OS X; free)
Related Page: Sublime Text (multi-platform; paid)
Customizing the Inputmap File
Now that you have the basics of inputmap files and the controller skeleton to help you start, you’ll need to customize it for your own use.
Name
Choose whatever name you want. However make sure it is a name that clearly identifies which device it is. The name we choose in the working example below for the PS3 controller is PS3 Controller
.
The “idmatcher” String
The string for idmatcher
is very important, since it’s what is used to identify and differentiate separate remote controls. When you connect a remote/controller to your machine, it will present itself with a name. We need to be able to identify that name.
This is done by using a regular expression (regex) that denotes a particular pattern to match.
Finding the Controller Name
The easiest way to locate the identifier for the remote/controller device is to:
- Connect your remote/controller to your machine
- Launch Plex HTPC and wait for the interface to fully load
- Press one of the buttons on the remote/controller
- Exit/quit Plex HTPC
- Open up the Plex HTPC log file and look through the beginning of the log
In most cases, a list of detected devices will be found in the first couple of seconds of the log. Here is an example of the log:
2016-01-20 00:40:29 [ INFO ] main.cpp @ 233 - Starting Plex HTPC version: 1.0.4.153-7d0b1dcc build date: 20160119
2016-01-20 00:40:29 [ INFO ] main.cpp @ 234 - Running on: OS X El Capitan (10.11) [15.2.0] arch x86_64
2016-01-20 00:40:29 [ INFO ] main.cpp @ 235 - Qt Version: 5.6.0 [x86_64-little_endian-lp64]
2016-01-20 00:40:29 [ DEBUG ] UpdateManager.cpp @ 59 - No valid/applicable update found.
2016-01-20 00:40:29 [ INFO ] ComponentManager.cpp @ 39 - Component: settings inited
2016-01-20 00:40:29 [ INFO ] InputMapping.cpp @ 117 - Loading inputmaps from: ":/inputmaps"
2016-01-20 00:40:29 [ INFO ] InputMapping.cpp @ 117 - Loading inputmaps from: "/Users/sarah/Library/Application Support/Plex HTPC/inputmaps"
2016-01-20 00:40:29 [ INFO ] InputComponent.cpp @ 42 - Successfully inited input: Keyboard
2016-01-20 00:40:29 [ INFO ] LocalJsonServer.cpp @ 33 - Listening to socket: "/tmp/pmp_inputSocket_plex.sock"
2016-01-20 00:40:29 [ INFO ] InputComponent.cpp @ 42 - Successfully inited input: socket
2016-01-20 00:40:29 [ DEBUG ] InputAppleRemote.mm @ 24 - Added remote: "IOSPIRIT GmbH-IOSPIRIT IR Receiver Emulation"
2016-01-20 00:40:29 [ INFO ] InputComponent.cpp @ 42 - Successfully inited input: AppleRemote
2016-01-20 00:40:29 [ INFO ] InputComponent.cpp @ 42 - Successfully inited input: AppleMediaKeys
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 229 - SDL found 1 joysticks
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 238 - JoyStick # 0 is PLAYSTATION(R)3 Controller with 19 buttons and 4 axes
2016-01-20 00:40:29 [ INFO ] InputComponent.cpp @ 42 - Successfully inited input: SDL
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 117 - SDL detected device was added.
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 229 - SDL found 1 joysticks
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 238 - JoyStick # 0 is PLAYSTATION(R)3 Controller with 19 buttons and 4 axes
2016-01-20 00:40:29 [ INFO ] InputCEC.cpp @ 103 - libCEC was successfully initialized, found version 196609
2016-01-20 00:40:29 [ INFO ] InputComponent.cpp @ 42 - Successfully inited input: CEC
2016-01-20 00:40:29 [ INFO ] ComponentManager.cpp @ 39 - Component: input inited
2016-01-20 00:40:29 [ INFO ] ComponentManager.cpp @ 39 - Component: system inited
In this case, you’ll note that the app looks through the /Users/sarah/Library/Application Support/Plex HTPC/inputmaps
directory to find available inputmaps. The first one it finds is “Keyboard” (from the “keyboard.json” inputmap), followed by “IOSPIRIT GmbH-IOSPIRIT IR Receiver Emulation”, “AppleRemote”, and “AppleMediaKeys”.
The interesting part comes after that, with the two lines:
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 229 - SDL found 1 joysticks
2016-01-20 00:40:29 [ INFO ] InputSDL.cpp @ 238 - JoyStick # 0 is PLAYSTATION(R)3 Controller with 19 buttons and 4 axes
This indicates that an available device was found and the second line specifically lists the identifier that the device uses – in this case, PLAYSTATION(R)3 Controller
.
Generating a RegEx For Matching
Now that we know the identifier (“PLAYSTATION(R)3 Controller”) for the device we want to set up, we need to turn that into something that Plex HTPC can actually use. As mentioned earlier, this is done by creating a regex for the matching.
Now, we could be lazy and just do a literal match against the string “PLAYSTATION”. If we did that and you then, for example, started using a “PLAYSTATION(R)4” controller, the inputmap could be incorrectly applied to a device it doesn’t match. So, let’s be more specific in the matching.
In the PlayStation 3 controller case above, the correct way to do it is to create the following idmatcher regex string:
"idmatcher": "PLAYSTATION\(R\)3.*",
The combination of the .
and *
characters (.*
) in that particular order can basically be thought of as a wildcard. As long as everything before that “wildcard” matches, then anything can come after and still be matched. Here, (
and )
are special characters and thus need some special treatment. Specifically, they need to be escaped by the addition of \
before them.
So, with the above idmatcher, all of the following would be valid matches, which is just what we want:
- PLAYSTATION(R)3 Controller
- PLAYSTATION(R)3 Super Duper l33t Controller
- PLAYSTATION(R)3 Special Edition Controller
Related Page: Regular-Expressions.info
Related Page: RegExr
Related Page: RegEx 101
Button Mapping
The third part of the inputmap file is the list of how buttons are mapped to actions. To do this, you need two pieces of information:
- how the button identifies itself when pressed (i.e. the “button name”)
- the action you want performed
Continue on to find information on how to gather both pieces of information.
Button Name
The typical way to gather the “name” for a particular button is to press the button on the remote and then to look in the Plex HTPC log file to see how the press is reported. The log will tell you the name of the button that was pressed, which you can then use for your inputmap file.
Related Page: Plex HTPC Logs
- Launch Plex HTPC and wait for it to finish loading
- Press the desired button on your remote/controller
- Look in the
Plex HTPC.log
file to see the button information
For instance, in the below log snippet, the PlayStation 3 controller was used. The X button was pressed first, then two seconds later the Square button was pressed.
2016-01-20 13:33:38 [ DEBUG ] InputComponent.cpp @ 86 - Input received: source: "PLAYSTATION(R)3 Controller" keycode: "KEY_BUTTON_14"
2016-01-20 13:33:40 [ DEBUG ] InputComponent.cpp @ 86 - Input received: source: "PLAYSTATION(R)3 Controller" keycode: "KEY_BUTTON_15"
From the log, we see that:
- X corresponds to
KEY_BUTTON_14
- Square corresponds to
KEY_BUTTON_15
With that information, you can then go to your skeleton inputmap file and change out the text BUTTON_NAME_HERE
to read KEY_BUTTON_14
(or whatever button name you saw in the logs) instead. Repeat the process for other buttons.
Function
After you know the correct name for a button, you need to decide what action it is you want that button to perform. Maybe it’s the ‘Stop’ button (so you want it to stop) or you want the ‘Menu’ button to navigate back.
The available function actions range from easy and obvious to really complicated. If you’re looking to do something advanced or really specific, you may be best off starting with in our Plex player forum.
Plex HTPC supports keyboard literals (such as A
) as well as a set of commands. The set of supported commands is:
back
cycle_aspect_ratio
cycle_audio
cycle_audio_back
cycle_subtitles
cycle_subtitles_back
debug
: Display debug information overlaydecrease_audio_delay
decrease_subtitles_delay
decrease_volume
down
enter
exit
home
increase_audio_delay
increase_subtitles_delay
increase_volume
info
jump+{letter}
: Jumps to the specified letter (or number) in an alphabetical listleft
mpv:{command}
: Sends a raw command into mpv. Example:mpv:set sub-scale=2
.next_pivot_tab
pause
play
play_pause
poweroff
previous_pivot_tab
reboot
right
search
seek_backward
: Seek back 10sseek_forward
: Seek forward 10sskip_previous
: Skip to previous playback item (or beginning of current if more than 10s into it)skip_next
: Skip to next playback item in play queuestep_backward
: Seek to previous chapter stop or if there are no chapters seek back 10minstep_forward
: Seek to next chapter stop or if there are no chapters seek forward 10minstop
suspend
toggle_fullscreen
toggle_subtitles
toggle_watched
up
Keys
The set of keys for some inputs is restricted to a pre-defined set. Sometimes guessing the key for a particular input action can go awry so if this is in doubt, check the application logs; it will log the input it sees even if it doesn’t have an action to take on it. Some examples of known inputs are provided below:
Keyboard
Keyboard keys are typically the raw key that is pressed along with modifiers. Modifiers are prefixed with the modifier string followed by a +
and the actual key. See https://doc.qt.io/qt-5/qkeysequence.html#toString for more information on the format of this string. Note: On the Mac the modifiers are not always named as you expect. The cmd
key is named Ctrl
, the opt
key is named Alt
, and the ctrl
key is named Meta
. Pressing cmd-ctrl-opt-shft-h
results in the input key: Ctrl+Meta+Alt+Shift+H
(respectively).
CEC
Note: Particular CEC setups may not send certain keys into the application; this is the full set of keys the library currently supports and could potentially make it into the application.
KEY_AN_CHANNELS_LIST
KEY_AN_RETURN
KEY_ANGLE
KEY_BACK
KEY_BLUE
KEY_CHANNEL_DOWN
KEY_CHANNEL_UP
KEY_CLEAR
KEY_CONTENTS_MENU
KEY_DATA
KEY_DOT
KEY_DOWN
KEY_DVD_MENU
KEY_EJECT
KEY_ELECTRONIC_PROGRAM_GUIDE
KEY_ENTER
KEY_F5
KEY_FAVORITE_MENU
KEY_GREEN
KEY_GUIDE
KEY_HELP
KEY_HOME
KEY_INFO
KEY_INITIAL_CONFIGURATION
KEY_INPUT_SELECT
KEY_LEFT
KEY_MENU
KEY_MUTE_FUNCTION
KEY_MUTE
KEY_NEXT_FAVORITE
KEY_NEXT
KEY_NUMERIC_0
KEY_NUMERIC_1
KEY_NUMERIC_11
KEY_NUMERIC_12
KEY_NUMERIC_2
KEY_NUMERIC_3
KEY_NUMERIC_4
KEY_NUMERIC_5
KEY_NUMERIC_6
KEY_NUMERIC_7
KEY_NUMERIC_8
KEY_NUMERIC_9
KEY_PAGE_DOWN
KEY_PAGE_UP
KEY_PAUSE_PLAY_FUNCTION
KEY_PAUSE_RECORD_FUNCTION
KEY_PAUSE_RECORD
KEY_PAUSE
KEY_PLAY_FUNCTION
KEY_PLAY
KEY_POWER_OFF_FUNCTION
KEY_POWER_ON_FUNCTION
KEY_POWER_TOGGLE_FUNCTION
KEY_POWER
KEY_PREV
KEY_PREVIOUS_CHANNEL
KEY_RECORD_FUNCTION
KEY_RECORD
KEY_RED
KEY_RESTORE_VOLUME_FUNCTION
KEY_RIGHT
KEY_SEEKBCK
KEY_SEEKFWD
KEY_SELECT_AUDIO_INPUT_FUNCTION
KEY_SELECT_AV_INPUT_FUNCTION
KEY_SELECT_BROADCAST_TYPE
KEY_SELECT_MEDIA_FUNCTION
KEY_SELECT_SOUND_PRESENTATION
KEY_SELECT
KEY_SETUP_MENU
KEY_SOUND_SELECT
KEY_STOP_FUNCTION
KEY_STOP_RECORD
KEY_STOP
KEY_SUBTITLES
KEY_TIMER_PROGRAMMING
KEY_TOP_MENU
KEY_TUNE_FUNCTION
KEY_UP
KEY_VIDEO_ON_DEMAND
KEY_VOLUME_DOWN
KEY_VOLUME_UP
KEY_YELLOW
Joysticks
Joystick “Keys” are mostly named as KEY_BUTTON_n
for the n
th button and KEY_AXIS_m_UP
for the m
th axis (with DOWN
instead of UP
to indicate a “downwards” direction). Note that the numbers for n
and m
can differ across controllers and even different mechanims of accessing the same controller. Check the logs when unsure about the naming of keys.
Some joysticks are disabled by default (by commenting out the idmatcher
) because they can cause conflicts if enabled by default. See individual json files for details.
LIRC
LIRC keys names come directly from the LIRC mapping. If an IR command is configured in LIRC to send the key KEY_LALALA
, then the key in the input mapping will be KEY_LALALA
.
There are many other function actions available. Plex HTPC uses “mpv” for the playback engine, so if you want to control something related to playback, then you can refer to the mpv options page for available options and values. For example, the equalizer section could be used to understand how to specify brightness, contrast, or similar commands.
As a general rule of thumb, if you want to command the actual video/audio engine then use mpv:
at the beginning. af
stands for audio filter and vf
for video filter. toggle
means just that: it toggles the current state between on and off
Related Page: mpv options
Combining the Button Name and Action
Now that you have both the name of the button and the action you want to perform, you need to combine them together in your inputmap file. From our PlayStation 3 example, imagine that we decide that we want the X button to perform the enter/select action and the Square button to stop. So, we would put that in the inputmap file appropriately:
"KEY_BUTTON_14": "enter",
"KEY_BUTTON_15": "stop",
You then just continue to fill in the buttons and actions you want.
You can open the finished PlayStation 3 controller inputmap (attached at the end of the article) to see an example. You’ll note that the last line does not have a comma. Here is the last active line of that json file to make it even more clear for you:
"KEY_AXIS_2_VAL_UP": "increase_audio_delay"
Start Using your Inputmap
Once you’ve completed creating your inputmap file, you can try using it. First, you need to place the file in the correct location. The following are the default locations:
- Windows:
C:\Users\USERNAME\AppData\Local\Plex HTPC\inputmaps
- macOS:
~/Library/Application Support/Plex HTPC/inputmaps
Once the file has been placed in the correct location, simply restart Plex HTPC so that the new inputmap is picked up.
Files