Voteshow – an interactive photo jury system

How to start a company in 30 days

Voteshow – an interactive photo jury system

This was one of my best projects so far. It includes both software and hardware components and some tricky technical solutions as well. The system is part of the photo contest software stack, which was I create for the Hungarian nature photographer of the year 2016 contest.


The jury process of the contest contains 3 stages. The first stage is when the members of the jury are evaluating all of the uploaded images with 3 different vote types: Yes, No or Maybe which are equals of 9, 5 and 1 points. This stage is handled by the contest software as I described it in the first post. The stage is not public, and the members of the jury can vote for the images independently from each other.

The 2nd and 3rd stages, however, are handled by the Voteshow. These sessions are usually take 1-1 full day, all the jury members are gathered together and the event is live streamed on the internet. The jurying process is also real time broadcasted on the contest’s website, on a Facebook-wall like surface.


The Voteshow system contains software and hardware components as well. You can see the parts on the image below:

Voteshow system

Voteshow system schematics

At the beginning a numeric keypad is getting assigned to each member of the jury. They will use their designated keyboards to send in their vote for the images.

The system also contains a projector which is used to project the current image and the votes of the jury. The control monitor is used to display the current image’s raw camera file. Sometimes the jury wants to check how the submitted image was differs from the original frame.


Since Voteshow is a web-based software running in a browser, but the input devices are simple keyboards, somehow it needs to be able to differentiate their inputs in order to assign each vote to the appropriate member of the jury. Unfortunately a browser can not identify the various USB keyboards which are connected to a computer, so I had to find a solution which I try to outline like this:

Voteshow - software

Voteshow software components


Voteshow client

Voteshow client getting votes

The client program is running on the Voteshow machine. It’s made in Delphi XE and since it’s executed by the operating system, it has low level access to the connected peripherials, like the USB keyboards. The Client’s only task is to gather the inputs from the keyboards then forward them to the Middleware, extended with the keyboard’s hardware ID.

On the attached screen you can see the hardware ID of the connected keyboard and the pressed keys.

Source of the Client:



Middleware is triggering JS events

The middleware connects the Client with the Voteshow software. The middleware starts a TCP/IP server, which is used by the Client to send over the inputs. When it’s started, the Middleware also instantiates a Chrome window through the Selenium webdriver. Later, when there is incoming input from the Client, the Middleware dispatching a custom Javascript event within that Chrome window and it passes the keyboard ID and the appropriate number which is pressed by the jury.

When it’s needed, the Middleware is also able to open the actual image in an external image viewer, like IrfanView.

Source of the Middleware:

Voteshow software

Voteshow software

An image and the votes from the jury

This is the main part of the software which actually can display the images, it can process the incoming votes and tracks the whole jury process. It can list the images of the contest, ordered and filtered in many ways. It accepts the Middleware’s messages through plain Javascript events.

How the Client communicates with the Middleware

During the startup process the administrator has to start the Middleware initially. It will open a TCP server on the port 5000, which listen to any incoming connection. When the TCP server is up, the administrator can start the Client, which will connect to the Middleware.

The Client will set up a low level keyboard hook which can capture every keystroke that is made on a keyboard, connected to the Voteshow machine. When it captures a keystroke, it will filter the input in order to send only the valid keys, which are from the numeric 0 (zero) to numeric 9.  When a valid keystroke is captured, the Client will simply write the following string to the TCP socket:


Upon an incoming data, the Middleware will try to understand the message. The message can be a vote event (when a jury pressed a key on it’s keyboard) or it can be a “heartbeat” event. I’ll talk about the hearbeat later.

Sometimes, when two or more jury press their keys at the same time, it is possible that the client will send 2 or more vote events at once. In this case, the Middleware has to separate the messages.

var messages = message.split("\r\n");

Afther that, it iterates through the lines of the message. Since the client only accepts vote events and the heartbeat, if the message is not a heartbeat it has to be a vote event.

How the Middleware communicates with the Voteshow

Upon an incoming vote event, the Middleware will split up the message to two parts: it parses out the keyboard’s ID and the vote value. Then it will execute 1 line of Javascript through the Webdriver:

driver.executeScript("document.dispatchEvent(new CustomEvent('vote', {detail: {keyboard: " + keyboard + ", key:" + vote + "}}))");

As you can see, I defined a custom JS event which is called “vote”, and it has a detail objects with 2 properties: the keyboard’s ID and the vote. The Voteshow software listens to this type of custom events, and it will pass to the root scope of the Angular app, like this:

document.addEventListener('vote', function(e) {
    $rootScope.$emit("vote", {
        key: e.detail.key,
        keyboard: e.detail.keyboard

More about CustomEvents here:

See it in live

You can see the Voteshow in motion on this recorded live stream:

Web developer, traveler, problem solver and future company owner. Lately a blogger.