In some cases, you may have an IR or Bluetooth remote control device that isn’t natively supported by Plex Media Player (PMP). 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 Media Player should interpret the button presses you use on the remote control device.
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 PMP - 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 which does 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)
Example Inputmap Files
A normal installation of Plex Media Player also comes with multiple example inputmaps that you can use as examples or references. You can find the example files in the following the default locations:
- Windows:
C:\Users\USERNAME\AppData\Local\PlexMediaPlayer\inputmaps\examples
- OS X:
~/Library/Application Support/Plex Media Player/inputmaps/examples
- Raspberry Pi2/OpenELEC:
/storage/.local/share/plexmediaplayer/inputmaps/examples
Remember that if you wish to use one of the example files as a starting point, do not edit and save the example file directly. Instead, make a copy of the file and save it in the location specified later, so that the app will actually use it.
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 Media Player and wait for the interface to fully load
- Press one of the buttons on the remote/controller
- Exit/quit Plex Media Player
- Open up the Plex Media Player Logs 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 Media Player 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 Media Player/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 Media Player/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 Media Player 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 Media Player 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 Media Player Logs
- Launch Plex Media Player and wait for it to finish loading
- Press the desired button on your remote/controller
- Look in the
Plex Media Player.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 Media Player forum. You can start with a search including inputmap
to see if your particular question has already been discussed. If not, post a new topic with your own details.
Here is a list of some of the more common function actions you might want to perform:
left
– left cursorright
– right cursorup
– up cursordown
– down cursorenter
– enter/selectplay_pause
– toggle between play and pausepause
– pause playbackstop
– stop playbackback
– navigate “back”home
– navigate “home”cycle_audio
– cycle forward between available audio streamscycle_audio_back
– cycle backward between available audio streamscycle_subtitles
– cycle forward between available subtitle streamscycle_subtitles_back
– cycle backward between available subtitle streamstoggle_subtitles
– toggle whether to display (current) subtitlesincrease_audio_delay
– increase the audio delay by 25msdecrease_audio_delay
– decrease the audio delay by 25ms
increase_subtitles_delay
– increase the subtitle delay by 100msdecrease_subtitles_delay
– decrease the subtitle delay by 100msseek_backward
– step back 10 secondsseek_forward
– step forward 30 secondsstep_backward
– jump forward 10 minutes (or to the next chapter, if available)step_forward
– jump back 10 minutes (or to the previous chapter, if available)host:fullscreen
– toggle the app between windowed and fullscreenhost:close
– quit the apphost:reload
– reload the interface in the apphost:toggleDebug
– toggle visibility of the debug overlay
The above are the ones found in the default “keyboard.json” inputmap file. There are, however, many additional function actions available that aren’t included in the default inputmap files. Here are just a few examples of other available values:
host:suspend
host:reboot
host:poweroff
host:player af toggle drc
host:player af toggle lavfi=[dynaudnorm=f=200]
host:player af toggle lavfi=[compand]
host:player add brightness 1
host:player add brightness -1
host:player add volume 1
host:player add volume -1
host:switch 24hz
host:switch 50hz
host:switch 60hz
host:script.py
host:player cycle-values video-aspect 16:9 4:3 2.35:1
As mentioned, there are many other function actions available. Plex Media Player 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 was used to understand how to specify the brightness commands above.
As a general thumb of rule, if you want to command the actual video/audio engine then use host:player
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
Related Page: Forums: Plex Media Player
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.
Warning!: The last active line of your button mapping cannot have a trailing comma (,
) at the end. If it does, it will render the inputmap invalid.
When specifying a multi-button mapping that includes the Meta
key, make sure that you list the Meta
key first. For example, Meta\\+Ctrl\\+9
instead of Ctrl\\+Meta\\+9
.
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\PlexMediaPlayer\inputmaps
- OS X:
~/Library/Application Support/Plex Media Player/inputmaps
- Raspberry Pi2/OpenELEC:
/storage/.local/share/plexmediaplayer/inputmaps
Once the file has been placed in the correct location, simply restart Plex Media Player so that the new inputmap is picked up.
Files