Create your own inputmap

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 regular text file (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:

  1. A name for the remote
  2. An idmatcher regex string which matches what the remote presents itself with when trying to communicate with PMP
  3. 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)

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 "idmapper" 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:

  1. Connect your remote/controller to your machine
  2. Launch Plex Media Player and wait for the interface to fully load
  3. Press one of the buttons on the remote/controller
  4. Exit/quit Plex Media Player
  5. Open up the Plex Media Player.log 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:

  1. how the button identifies itself when pressed (i.e. the "button name")
  2. 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

  1. Launch Plex Media Player and wait for it to finish loading
  2. Press the desired button on your remote/controller
  3. 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 cursor
  • right - right cursor
  • up - up cursor
  • down - down cursor
  • enter - enter/select
  • play_pause - toggle between play and pause
  • pause - pause playback
  • stop - stop playback
  • back - navigate "back"
  • home - navigate "home"
  • cycle_audio - cycle forward between available audio streams
  • cycle_audio_back - cycle backward between available audio streams
  • cycle_subtitles - cycle forward between available subtitle streams
  • cycle_subtitles_back - cycle backward between available subtitle streams
  • toggle_subtitles - toggle whether to display (current) subtitles
  • increase_audio_delay - increase the audio delay by 25ms
  • decrease_audio_delay - decrease the audio delay by 25ms
  • increase_subtitles_delay - increase the subtitle delay by 100ms
  • decrease_subtitles_delay - decrease the subtitle delay by 100ms
  • seek_backward - step back 10 seconds
  • seek_forward - step forward 30 seconds
  • step_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 fullscreen
  • host:close - quit the app
  • host:reload - reload the interface in the app
  • host: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.

Important!: 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.

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.