Friday, May 29, 2009

Choosing an HTPC Keyboard and Mouse

I have a home theater PC (HTPC) and have spent a lot of time trying to find an ideal means to control it. While there are a lot of options available on the market, almost all of them fall short in some area.

I have tried quite a few cordless peripherals that all used the standard RF interface via USB dongle. These devices utilize the already crowded 2.4 Ghz frequency band, which you may recognize as the same frequency used by Wifi, many cordless phones and baby monitors. All this interference from other devices means you will have a lot of problems with dropped signals, missed clicks, etc.

Furthermore, optical mice really suck to use on your lap, so I knew I would need something a little out-of-the-ordinary. I have tried a Gyration Air Mouse, which was really neat, but it used an RF dongle and suffered from the aforementioned signal dropouts. :-( Furthermore, the Air Mouse is a delicate piece of machinery with several gyroscopes inside that can get out of alignment if the device is dropped a few times, which is almost unavoidable if you place it on the arm of your couch or chair.

Based on these experiences, my requirements are: Bluetooth, integrated cursor control and Linux support (since I use Ubuntu for my media center). Now, you would think that this sort of thing would be easy to come by and that there would be hundreds of options to choose from among a variety of vendors, but this is simply not the case. In my experience, there are only two viable options: the Logitech Cordless MediaBoard Pro and the Logitech diNovo Mini.

While the diNovo Mini is very cool, it is expensive (approx. $120 at the writing of this review) and the keyboard is of a strangely awkward size that makes it slightly too large for thumb typing but far too small for touch-typing. Additionally, its trackpad thingie in the upper-right takes some getting used to. On the plus side, it's small enough to fit into couch-side storage along with regular TV remotes or even in your pocket. It also has an integrated, clamshell cover that nicely covers the keys when not in use.

However, the small keyboard and funky trackpad thingie make it unsatisfactory for general computing, such as Web browsing and typing, in my opinion.

In contrast, the MediaBoard Pro is much cheaper (approx. $60 currently), but it is marketed for the Playstation 3 rather than for standard PC use. Do not let this scare you away. It syncs fine with both Windows and Linux via the standard Bluetooth stacks with minimal fuss (notice: Logitech also makes a non-Pro MediaBoard that uses 2.4 Ghz RF; make sure you don't buy it on accident) and the PS3-specific media keys can be easily ignored or repurposed with key-mapping software.

The MediaBoard Pro is a full-sized keyboard with all of the keys you would expect, including F-keys, Del/Ins/Home/PgDwn/PgUp/End keys, etc. The only key that is missing is the Windows key, which has been replaced by dedicated keys for left- and right-clicking. It also has an integrated trackpad--similar to those found on most laptops--off to the right, where the keypad would normally be located.

I found the trackpad to be responsive, if a bit on the small side, and it has an area on the right side that is dedicated to scrolling (similar to the mouse wheel) and worked quite well without any configuring.

Some minor quibbles: this keyboard feels very light and somewhat cheaply made, but I guess that's what you get for $60. Also, it has a glossy black finish which looks really nice at first but attracts fingerprints and tiny scratches like nobody's business. Lastly, I have a feeling that the silver finish on the accents will quickly rub off, likely leaving an unsightly unfinished plastic instead.

All in all, I think the Logitech Cordless MediaBoard Pro is the best option for anyone who plans to do any actual computing (typing, navigating, Web browsing, etc.) with their HTPC. If you intend to use a media frontend, such as MythTV or XBMC, the diNovo Mini might be a better fit, since it feels more like a conventional remote and those interfaces do not require as much mouse/keyboard action.

Friday, May 1, 2009

Monitoring a Directory to Automatically Invoke HandBrake

I've seen this question pop up a lot on HandBrake's forums and IRC channel, so I thought I'd make an entry about it here (Mac users skip down to the bottom for your directions):

Many folks have expressed interest in being able to specify a directory for HandBrake to 'watch' for new files that it would then automatically attempt to convert with predefined settings. I think most people are wanting this for use with devices, such as iPods, PS3s and AppleTVs, which require specific settings for videos to work. While HB doesn't support this functionality on its own (and the devs don't sound too interested in adding it), you can accomplish much the same thing in Ubuntu Linux using HandBrakeCLI and a little shell scripting.
WARNING: I'm a novice at scripting and there is definitely a more effective and elegant way of doing this. If you have a suggestion, please leave a comment! Similar steps will also work on other platforms/distros, so feel free to leave a comment about your successes or failures.

First, we'll need to install a utility to enable monitoring of directories:
sudo aptitude install inotify-tools
Next, we'll make some new directories in our home folder to hold our scripts and conversions. In a terminal, type:
cd $HOME ; mkdir HandBrake ; mkdir HandBrake/convert
Navigate to the newly created HandBrake directory:
cd HandBrake
and type:
gedit monitor.sh
This is where we'll write our script to monitor the 'convert' directory and invoke another script to do the actual conversion:
#!/bin/bash

inotifywait --monitor -e moved_to -e create ~/HandBrake/convert | while read dir;
do
(~/HandBrake/convert.sh)

done
Save, exit and--again--type:
gedit convert.sh
Here we will create our conversion script (be sure to put your desired file extension and preset in place instead of the bracketed reminders):
#!/bin/bash
for file in ~/HandBrake/convert/*
do HandBrakeCLI -v -i "$file" -o "$file".converted.[FILE-EXTENSION-GOES-HERE] --preset [PRESET-NAME-GOES-HERE] ;

#uncomment next line to delete original
#rm $file

done
Save and exit, then type:
chmod +x *.sh
to make both scripts executable.

Now, you can start monitoring by typing:
sh ~/HandBrake/monitor.sh
or you can set the script to run as a startup item where it will run continuously in the background starting the next time you log on.

Henceforth, any file you move or copy into the 'convert' directory will automatically convert to the desired format. This script will only work on one file at a time (i.e., you have to wait for the encoding to finish before dropping in the next file to convert). Also of note: HB will choke if the file is weird in any way--e.g. no audio track--and you'll have no way of knowing it if the script is running in the background, since it won't print any output.

Good luck and let me know if you run into any problems.

Bulk Encoding on Macs


Update (06/01/09): There's been a lot of clamoring on the Mac board of the HandBrake forums asking for bulk input of files to be converted using a preset. The devs have no interest in adding such a feature at this time because of the tremendous support headache it could cause, but you Mac users can do scripting to accomplish the same thing.

Just like the Linux users, open a Terminal (Applications > Utilities > Terminal) and type:

cd Desktop ; nano convert.sh
then paste in this (shift+ctrl+v; be sure to put your desired file extension and preset in place instead of the bracketed reminders):
#!/bin/bash
for file in ./*
do ./HandBrakeCLI -v -i "$file" -o "$file".converted.[FILE-EXTENSION-GOES-HERE] --preset [PRESET-NAME-GOES-HERE] ;

#uncomment next line to delete original
#rm $file

done
Save and exit (ctrl+x), then type:
chmod +x *.sh
to make the script executable. Now, just put the script into a folder with your HandBrakeCLI binary and you should be able to invoke the script (navigate to its directory in the Terminal by typing cd [space after cd] and then dragging your conversion folder onto the Terminal window and hit 'Enter,' then type ./convert.sh) and automatically convert any files within the directory using the chosen preset. I would recommend just keeping a folder around that you use for conversions and keep the script and HandBrakeCLI binary in there at all times, then you can just drop in the files you want to convert, start the script and go along your merry way.

UPDATE (12/20/2013): An anonymous reader shared his script, which sounds much more robust than mine:
inotifywait -r --monitor --quiet -e moved_to -e close_write --format '%w%f' /mnt/public/convert/video/android-hq/ | while read -r FILE; do echo "File copy detected" echo "Starting HandBrake..." (sleep 15 && /usr/bin/HandBrakeCLI -v -i "$FILE" -o /mnt/public/convert/output/video/"$(echo "$FILE" | cut -c38- | rev | cut -c4-| rev)android-hq.mkv" -e x264 -x weightp=0:cabac=0 -b 650 --audio 1 --aencoder faac --ab 96 --mixdown stereo --gain 3 --width 720 --loose-crop --decomb --markers --turbo --two-pass --vfr --subtitle 1 --native-language eng && sleep 15 && rm -rf "$FILE")& done
UPDATE (9/27/2014): The same user (name is teeedubb, apparently) is back with an update. This was posted in the comments but got mangled, so I tried to piece it back together:
I'm back - I have revisited the above script because it had some glaring faults - it would start a handbrakecli process for each file, which when encoding a seasons worth of tv shows it would bring my pc to its knees, it didnt handle files in sub directories, didnt handle multiple profiles and probably would have given undesirable results if a file extension had more than 3 character, plus it was kinda messy. New version below solves these issues: It queues encodes using task-spooler (tsp package in ubuntu), works with sub-directories in the watch folder (and deletes any empty subdirectories within watch folders) and supports multiple profiles. Options are 'watch directory', 'output directory' and 'task-spooler slots' (concurrent jobs) which are set through the variables. You can set multiple handbrake profiles which the script uses based on which directory the files are copied into, if files are copied into the root watch directory the first profile is used. Options for profiles are: 'name', profile name which will be appended to the transcoded file (this needs to match the profile directory and be fairly unique - script searches the input file location for profile name, so a profile called 'android' could confuse the script when transcoding the movie 'android cop'), 'handbrake settings', settings for handbrake to use (I'm pretty sure you could use --preset XXXX here as well), 'file extension', file extension for handbrake to use on output file and 'delete source file', whether or not to delete the source video file. You can create extra profiles by adding variables beginning with PRESET2 etc and adding elif entries to the if/then statement in the script. By default the script attempts to delete any empty subdirectories *and its ancestors* when completing a transcode, so you need to ensure you profile directories are not empty - I have done this by creating a hidden file in each profile dir and making the file un-deletable (eg: profile1 dir is /mnt/public/convert/video/android-hq, run the command touch /mnt/public/convert/video/android-hq/.android-hq && sudo chattr +i /mnt/public/convert/video/android-hq/.android-hq).
and here's the script:
#!/bin/bash
#script to watch a directory for incoming files and pass them onto HandBrakeCLI

WATCH_DIR="/mnt/public/convert/video/"
OUTPUT_DIR="/mnt/public/convert/output/video/"
TASK_SPOOLER_SLOTS=2

##HANDBRAKE PROFILE 1
PRESET1_NAME="android-hq"
PRESET1_HANDBRAKE_SETTINGS=" -e x264 -x weightp=0:cabac=0 -b 650 --audio 1 --aencoder faac --ab 96 --mixdown stereo --gain 3 --width 720 --loose-crop --decomb --markers --turbo --two-pass --vfr --subtitle 1 --native-language eng"
PRESET1_FILE_TYPE="mkv"
PRESET1_DELETE_SOURCE="yes"

###########################

ts -S $TASK_SPOOLER_SLOTS
inotifywait --recursive --monitor --quiet -e moved_to -e close_write --format '%w%f' "$WATCH_DIR" | while read -r INPUT_FILE; do

PRESET_NAME="$PRESET1_NAME"
HANDBRAKE_SETTINGS="$PRESET1_HANDBRAKE_SETTINGS"
FILE_TYPE="$PRESET1_FILE_TYPE"
DELETE_SOURCE="$PRESET1_DELETE_SOURCE"

if [[ $(echo "$WATCH_DIR" | grep -i "$PRESET1_NAME") ]] ; then
PRESET_NAME="$PRESET1_NAME"
HANDBRAKE_SETTINGS="$PRESET1_HANDBRAKE_SETTINGS"
FILE_TYPE="$PRESET1_FILE_TYPE"
DELETE_SOURCE="$PRESET1_DELETE_SOURCE"
fi
FULL_FILE_NAME=$(echo ${INPUT_FILE##*/})
OUTPUT_FILE=$(echo ${FULL_FILE_NAME%.*})
tsp bash -c 'nice -n 19 /usr/bin/HandBrakeCLI -v -i "$0" -o "$1""$2"-"$3"."$4" "$5" && if [[ "$6" = yes ]] ; then sleep 15 ; rm -f "$0" ; fi ; rmdir -p "$(dirname "$0")"' "$INPUT_FILE" "$OUTPUT_DIR" "$OUTPUT_FILE" "$PRESET_NAME" "$FILE_TYPE" "$HANDBRAKE_SETTINGS" "$DELETE_SOURCE"
done