Adam's blog
VideoLAN Jukebox Kiosk
Some time ago a company contacted me regarding a touchscreen display they had worked on for the lobby of a major software company in Silicon Valley. It seems that they were trying to use eight touchscreens connected to one computer to launch and control a video on a second computer connected to a large HD Display. Each touchscreen had it's own image, which when pressed, spawns player controls on the touchscreen and launches an associated video on the main display. Basically it was a fancy version of those old diner jukeboxes at your booth that would queue your song on the playlist.

So how do you meet the project goals without using Elo touch monitors or super expensive nVidia gamer machines? A combination of Ubuntu Linux, Firefox, and VLC running on nine of the cheapest machines available. Here's how:
First we download Ubuntu 7.10 Desktop (Gutsy Gibbon) iso image to burn on a CD. We want this particular version of Ubuntu because the 8.04 version uses a beta(5) version of Firefox(3) which doesn't support the plugins we will be using.
Next, burn the image to a CD using your favorite burner software and install it on all the machines. Name each computer something relevant, like it's position 'topfarleft' or 'bottomcenterright' or 'maindisplay'. This will be exceedingly useful later when we are dealing with multiple html, video, and image files on the server.
On the large main display:
- Select System - Administration - Synaptic Package Manager from the taskbar menu

Now to make them automatically launch at boot:
- Select System - Preferences - Sessions from the taskbar menu

- Add a new item and name it VLC
- Add to the command line section:
vlc -I http /usr/share/vlc/http/example.mov

Hopefully /usr/share/vlc/http/example.mov is obvious and you substituted the full path to your video. I used the VLC root http interface directory, /usr/share/vlc/http, for simplicity and because of folder and file permissions can get complicated fast. You can use the default home directory of the current user. The -I http is to launch the webserver remote control interface and you can use only this if you do not want a default video to launch.
- Add a new item and name it Unclutter
- Add to the command line section:
unclutter -idle 2

The option -idle 2 tells the OS to hide the mouse cursor after two seconds. Before you forget, set the machine to auto-login on boot.
- Select System - Administration - Login Window from the taskbar menu
- Select the Security tab
- Check the box Enable Automatic Login and select your user.

Now we can customize VLC.
- Select Applications - Sound & Video - VLC media player

- Select Settings - Preferences from the menu
- Make sure to enable the Advanced Settings checkbox in the lower right corner
- Expand the Interface directory and select Main interfaces
- Mark the box for HTTP remote control interface

- Select the Video directory
- Mark Fullscreen video output and Disable screensaver

Since this is a dedicated machine we can tell it to use as much of the system resources as it wants.
- Select the Advanced directory and mark Allow real-time priority

- Select Save preferences
Now you can customize the web interface for the touchscreens. We are going to make copies of all the documents we will be modifying.
- Select Applications - Accessories - Terminal from the taskbar menu

- Type
sudo chmod -R 777 /usr/share/vlc/http

- Type
cd /usr/share/vlc/http - Then type
cp index.html touch_template.html - Followed by
cp style.css touch_style.css
First let's customize our touch_template.html page.
- Select Applications - Accessories - Text Editor

- Open /usr/share/vlc/http/touch_template.html
- Change
<link href="style.css" rel="stylesheet" type="text/css" />to:
<link href="touch_style.css" rel="stylesheet" type="text/css" />

- Change
<body onload="loop_refresh();">to:
<body onload="loop_refresh();no_show();" style="cursor:crosshair;">

Adding style="cursor:crosshair;" is optional, but it centers the precise cursor location to the center of your finger instead of the upper left corner of your finger press. The no_show(); function we will be creating later to hide elements we do not want. Now we will create some static variables on the page to pass to the right javascript functions.
- Insert
<div id="bkgd_image" onclick="in_play();">
<img src="images/touch_0.jpg" onmousedown="return false;">
</div>
<input type="hidden" name="input_pl" id="input_pl" value="/usr/share/vlc/http/touch_0.mov" />

Obviously touch_0.jpg and touch_0.mov will be named whatever you choose. Make sure to place them in the correct folder. The default http interface looks like this in your browser:

Any more changes to the 'look and feel' will be made by altering touch_style.css elements directly. This project required a video to launch when you pushed anywhere on the screen. This is where you could use in_enqueue(); instead of in_play(); in the <div id="bkgd_image" onclick="in_play();"> tag to add a video to the playlist instead of interrupting and replacing the current video.
My particular project required only a Play/Pause button and a time-slider control about mid-screen. So we have to explicitly tell the section where it should appear and what elements it should display.
- Open touch_style.css using the text editor
- Insert section:
div#main {
position: absolute;
top: 500px;
left: 275px;
width: 325pt;
background: transparent;
border: none;
} - Insert line
display: none;into thediv.titlesection

Since each touchscreen had it's own image and associated video I altered the touch_template.html file eight times (touch_1.jpg, touch_8.mov, etc.) and saved them with useful names like topfarleft.html and bottomcenterright.html so I could easily known where I was making changes on the entire display.
On my project I had to spawn the player controls *only* on the touchscreen that launched the video. For this sort of dynamic filtering we have to alter the javascript file functions.js located in the /usr/share/vlc/http/js directory.
- Add to the global variable section
var pl_cur_video;on the line aftervar pl_cur_id; - Continuing on the next line insert the following:
function no_show()
{
var disappear= new Array(
"playlist",
"footer",
"btn_open",
"btn_stop",
"btn_previous",
"btn_next",
"btn_playlist",
"btn_info",
"btn_sout",
"btn_fullscreen",
"btn_snapshot",
"btn_volume_down",
"btn_volume_up",
"status",
"nowplaying"
);
for (key in disappear)
toggle_show(disappear[key]);
} - Find the
parse_playlist()function - Find
if( elt.getAttribute( 'current' ) == 'current' )and after the first parenthesis insertpl_cur_video = elt.getAttribute ( 'name' );
*immediately before* the lineif( elt.getAttribute( 'ro' ) == 'rw' )insert:
var showMain = document.getElementById( 'main' );
if( value( 'input_pl') != pl_cur_video )
{
showMain.style.display = 'none';
}
else
{
showMain.style.display = 'block';
}
This makes the player controls only appear on the touchscreen that launched the video. Now we have to customize the button and slider control images.
- Select Applications - Graphics - GIMP Image Editor
- Open and customize
/usr/share/vlc/http/images/play.png
/usr/share/vlc/http/images/slider_point.png
/usr/share/vlc/http/images/slider_bar.png
/usr/share/vlc/http/images/slider_left.png
/usr/share/vlc/http/images/slider_right.png
Remember that if you change the size of the images, you have to open /usr/share/vlc/http/dialogs/main and edit the width and height values of the images in the progress bar section so they match the new size.

Make sure to restart your machine and you're finished with the main display.
On the touchscreens:
First we need to download and install the eGalax touchkit drivers and configuration utility. If you are following my instructions, then you are using a 32Bit 2.6 Kernel and you need the driver found here. Otherwise, use the driver that matches your system from here.
- Select Applications - Accessories - Terminal from the taskbar menu
- Type
cd Desktop/TouchKitor the path to where you extracted the driver folder **WARNING** Case sensitive, so pay attention - Copy it by typing
sudo cp egalax_drv.so /usr/lib/xorg/modules/inputdirectory and entering your password at the prompt - Type
sudo gedit /etc/X11/xorg.conf - Add the line
InputDevice “EETI” “SendCoreEvents”to the"ServerLayout"section

- Insert:
Section "InputDevice"
Identifier "EETI"
Driver "egalax"
Option "Device" "usbauto"
Option "Parameters" "/var/lib/egalax.cal"
Option "ScreenNo" "0"
EndSection

- Save xorg.conf and close the text editor
- Plug in the touchscreen usb cable and follow any prompts with the affirmative
- Reboot the machine
- Select Applications - Accessories - Terminal from the taskbar menu
- Type
sudo touchcfgto launch the TouchKit configuration utility - Select Tools and run the 4 point calibration test
You might find with touchscreens that you would like to make the cursor disappear because it's unnecessary.
- Select System - Administration - Synaptic Package Manager from the taskbar menu
- Install unclutter
Now we can make it go fullscreen without a scrollbar. We will also stop triggering a taskbar or menubar near the edge of the screen.
- Select Applications - Internet - Firefox Web Browser
- Select Tools - Add-ons and click the Get Add-ons button

- Install Fullerscreen from the search box
- Select Edit - Preferences - Main and set the Firefox homepage to
http://maindisplay:8080/topfarleft.htmlreplacingmaindisplaywith the IP address of the main display machine and replacingtopfarleft.htmlwith the name of the machine you are working on - Go to Tools - Add-ons - Fullerscreen and select Options
- Uncheck everything and set the Threshold for edge detection to 1 pixel
These next steps gets rid of that annoying "Restore Session?" message box every time you reboot the machines.
- Type
about:configin the browser bar - Find
browser.sessionstore.enabledand set it tofalse
Now we can install the final add-on which will default to full screen, disable all menus, toolbars, key commands and right button menus.
- Install R-kiosk on Firefox from the Get Add-on search box
Now to make Firefox automatically launch at boot:
- Select System - Administration - Sessions from the taskbar menu
- Add a new item and name it Firefox
- Add to the command line section: firefox
This will automatically launch Firefox, fullscreen with no borders or scroll bars, just your image which, when pressed, launches a video on the main display. Before you forget, set the machine to auto-login on boot.
- Select System - Administration - Login Window from the taskbar menu
- Select the Security tab
- Check the box Enable Automatic Login and select your user
And that's it.
Money Talks
Due to some disbelief on the NUI Group forums about how my Logitech QuickCam™ Ultra Vision SE was stacking up to the Firefly/Dragonfly from Point Grey Research, I decided to make a little video showing the speed of the camera. Now, the lag of the trails that follow your fingers is the computer. If you move too fast and the camera loses your trails, then that's the camera.
I use the coins to show that I've reached a zero-force blob detection with the camera in normal room lighting down to the diameter of a dime. Unfortunately, my front surface mirror broke in a moment of sheer ecstasy and I haven't replaced it yet, so my projected screen area is cut in half. But that's trivial as the Logitech can fit the whole screen in it's view from less than 3 feet away and doesn't need to use the mirror.
I monkeyed around with the mouseDriver.exe thingy for a minute on the internet web browsing and such. Not much fun when you're itching to write code. So I'm off to go do that now.
Fiddling Around

I broke my mirror (and I'm not superstitious), so I have been testing at half the screen size and it's making me frustrated because it is reducing the clarity of my blobs while increasing their size. Zooming and cropping with my camera sucks. I can't wait for a Dragonfly Express or a Firefly MV from Point Grey Research. Having a smaller screen is not always a good thing. I might as well be testing on an iPhone or an iPod Touch.
Did you click on the Dragonfly link? 200fps at 640x480!!! That kicks ass! If I had problems tracking moving blobs, then this solution would fix it in 1/200th of a second. Simply awesome. Plus, it looks like Jeff Han is using a Dragonfly in this photo from the 2006 TED conference.

It's really out of my budget, so I have been looking for some contract jobs to make up the difference. *sigh* It's so painful to resume manual labor after a very long break. Not that I'm physically strained, but doing other people's coding is manual labor to me. Maybe I'll just make a Facebook plugin and retire.
Got Smoke?
There is no human reason why a child should not admire and emulate his teacher's ability to do sums, rather than the village bum's ability to whittle sticks and smoke cigarettes. The reason why the child does not is plain enough - the bum has put himself on an equality with him and the teacher has not. --Floyd Dell
Here I am testing the smoke app. My camera is not calibrated. The brightness, contrast, etc are all wacky, which is why I'm in the dark. I keep telling people I need absolute dark for my work and that's why the windows are covered in aluminum foil. I think they believe me. The voices say I can trust them.
The lag is bad for many, many reasons. I should be able to eliminate the lag with little effort. I'll post again when the silicone layer is dry enough to test.
Testing My Paitence
To do anything truly worth doing, I must not stand back shivering and thinking of the cold and danger, but jump in with gusto and scramble through as well as I can. --Og Mandino (1923 - 1996)
I've been tortuously waiting for my sleek Samsung SP-P310ME Digital Light Projector (DLP). It felt like the UPS guy was waterboarding me by making me sign for it. Just hand it over, brownie! Now that it's here, I've been tweaking this and that to align it with my acrylic. The wooden frame holding it up is weak and wobbly. Not a final product, but hey, I've been focusing more on the software.
Tomorrow I suppose I'll head down to the local hardware store to pick up some silicone caulk and toluene to make a compliant surface. After the compliant surface, maybe I'll order some Rosco Grey. After that, designing the table frame and internal structure to hold mirror, fans, and other secured components. I plan on making it as portable as possible. I'm going to need a sturdier front surface mirror. The one I have has already cracked a bit in the corner. Lame.
Yawn. It's late. There's always tomorrow.