Wednesday, 8 July 2015

Commandline VLC with global hotkeys (using QuickSilver and Karabiner)

TL;DR;

Create a trigger in QuickSilver that pipes the word 'pause' to the rcold interface of VLC.

Details

Imagine having a Mac and not wanting to use iTunes.  Imagine hating iTunes so much that you'd rather use an interface that looks like this:
Unlikely, I realise, but that's where I'm at.  I really don't need or want a complicated media center [sic] application that puts the kettle on while it tries to download album art, so I use the VLC NCurses interface.  It's far from perfect, but I really, really hate iTunes, so this it's an OK option.

However, what I do miss is having a single key to pause music play back, whether the player has focus or not i.e. what I used to have with the F8/play-pause in iTunes. It turns out there are ways to achieve this.

First up, this is how I launch VLC
vlc -I ncurses --browse-dir /Path/To/Your/Music --extraintf oldrc --rc-unix /tmp/vlc.sock
view raw launch_vlc hosted with ❤ by GitHub

Which basically says, launch VLC using the NCurses interface, starting in the following browse directory, also use an extra interface, Old Remote Control and while you're at it create a socket to communicate with it called /tmp/vlc.sock. Which means that I now have two interfaces controlling VLC: NCurses, which I use to browse for music from my music library, and oldrc, which I use to be able to stop and start playback using a global hotkey.

As I mainly use my laptop keyboard I'm missing a few function keys that would be really handy here.  Enter Karabiner which allows me to map Fn + SPACE to F13, with something like this in the private.xml
<?xml version="1.0"?>
<root>
<devicevendordef>
<vendorname>APPLE_COMPUTER</vendorname>
<vendorid>0x05ac</vendorid>
</devicevendordef>
<deviceproductdef>
<productname>LAPTOP_INPUT</productname>
<productid>0x0253</productid>
</deviceproductdef>
<item>
<name>Enable extra function keys</name>
<identifier>private.enablefunctionkeys</identifier>
<device_only>DeviceVendor::APPLE_COMPUTER,DeviceProduct::LAPTOP_INPUT</device_only>
<autogen>__KeyToKey__ KeyCode::SPACE, ModifierFlag::FN, KeyCode::F13</autogen>
<autogen>__KeyToKey__ KeyCode::X, ModifierFlag::FN, KeyCode::F16</autogen>
<autogen>__KeyToKey__ KeyCode::A, ModifierFlag::FN, KeyCode::F17</autogen>
<autogen>__KeyToKey__ KeyCode::S, ModifierFlag::FN, KeyCode::F18</autogen>
</item>
</root>

The final step is to create a hotkey using QuickSilver which is done in the Triggers section of the QuickSilver Configuration. Click the '+' symbol and select 'HotKey'.  Paste the following
printf pause | nc -U /tmp/vlc.sock
into the 'Select an item' field and set the action to 'Run Command in Shell'.

Job done, every time I hit 'Fn + SPACE' I send the command 'pause' to that socket.  On the other end of that socket the VLC rc interface understands that and toggles pause/play. Unfortunately there is a minor irritation in that the rc interface produces output like this:
status change: ( play state: 3 )
pause: returned 0 (no error)
status change: ( pause state: 3 ): Pause

that is then dumped out onto the NCurses console space (which looks terrible).  A simple solution is to hit 'Ctrl + l' to clear the UI.  Ideally I'd stop this happening at all, but I haven't figured out how.  Yet.

No comments:

Post a Comment