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
namefor the remote - An
idmatcherregex 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.logfile 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:
backcycle_aspect_ratiocycle_audiocycle_audio_backcycle_subtitlescycle_subtitles_backdebug: Display debug information overlaydecrease_audio_delaydecrease_subtitles_delaydecrease_volumedownenterexithomeincrease_audio_delayincrease_subtitles_delayincrease_volumeinfojump+{letter}: Jumps to the specified letter (or number) in an alphabetical listleftmpv:{command}: Sends a raw command into mpv. Example:mpv:set sub-scale=2.next_pivot_tabpauseplayplay_pausepoweroffprevious_pivot_tabrebootrightsearchseek_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 10minstopsuspendtoggle_fullscreentoggle_subtitlestoggle_watchedup
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_LISTKEY_AN_RETURNKEY_ANGLEKEY_BACKKEY_BLUEKEY_CHANNEL_DOWNKEY_CHANNEL_UPKEY_CLEARKEY_CONTENTS_MENUKEY_DATAKEY_DOTKEY_DOWNKEY_DVD_MENUKEY_EJECTKEY_ELECTRONIC_PROGRAM_GUIDEKEY_ENTERKEY_F5KEY_FAVORITE_MENUKEY_GREENKEY_GUIDEKEY_HELPKEY_HOMEKEY_INFOKEY_INITIAL_CONFIGURATIONKEY_INPUT_SELECTKEY_LEFTKEY_MENUKEY_MUTE_FUNCTIONKEY_MUTEKEY_NEXT_FAVORITEKEY_NEXTKEY_NUMERIC_0KEY_NUMERIC_1KEY_NUMERIC_11KEY_NUMERIC_12KEY_NUMERIC_2KEY_NUMERIC_3KEY_NUMERIC_4KEY_NUMERIC_5KEY_NUMERIC_6KEY_NUMERIC_7KEY_NUMERIC_8KEY_NUMERIC_9KEY_PAGE_DOWNKEY_PAGE_UPKEY_PAUSE_PLAY_FUNCTIONKEY_PAUSE_RECORD_FUNCTIONKEY_PAUSE_RECORDKEY_PAUSEKEY_PLAY_FUNCTIONKEY_PLAYKEY_POWER_OFF_FUNCTIONKEY_POWER_ON_FUNCTIONKEY_POWER_TOGGLE_FUNCTIONKEY_POWERKEY_PREVKEY_PREVIOUS_CHANNELKEY_RECORD_FUNCTIONKEY_RECORDKEY_REDKEY_RESTORE_VOLUME_FUNCTIONKEY_RIGHTKEY_SEEKBCKKEY_SEEKFWDKEY_SELECT_AUDIO_INPUT_FUNCTIONKEY_SELECT_AV_INPUT_FUNCTIONKEY_SELECT_BROADCAST_TYPEKEY_SELECT_MEDIA_FUNCTIONKEY_SELECT_SOUND_PRESENTATIONKEY_SELECTKEY_SETUP_MENUKEY_SOUND_SELECTKEY_STOP_FUNCTIONKEY_STOP_RECORDKEY_STOPKEY_SUBTITLESKEY_TIMER_PROGRAMMINGKEY_TOP_MENUKEY_TUNE_FUNCTIONKEY_UPKEY_VIDEO_ON_DEMANDKEY_VOLUME_DOWNKEY_VOLUME_UPKEY_YELLOW
Joysticks
Joystick “Keys” are mostly named as KEY_BUTTON_n for the nth button and KEY_AXIS_m_UP for the mth 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