[hack day] Video Wall
Not happy with a 48” monitor for your presentation? No problem - just share your desktop across a 3x3 bank of them, and the whole world can watch!
I’ve just joined Talis as a developer, so two days of collaborative play came at the right time. The experience of a hack day served as a great introduction to the culture of the organisation. RichardG’s video wall proposal attracted votes at the eleventh hour, which put Alan, Andrew, Mark and myself on the project.
Our first priority was to hash out together what we wanted to achieve, keeping in mind the hardware we had available - a bunch of Mac and Dell laptops of varying ages and conditions. Here’s the list we came up with:
- Push images to individual screens
- Show a desktop over all screens
- Show a video across all screens
Given the amount of hardware sitting in the cupboard, we decided to stick with a 2x2 monitor configuration (though of course this could be expanded). Given that each laptop could trivially drive an external monitor, a 2x4 wall would be possible, or even an odd sized 3x3 with a corner missing! Our one purchase was a 5-port Gigabit switch to wire it all together on a LAN.
Various people suggested different approaches, with people either leading on an idea or assisting with web-based research, in a self-organising and organic fashion. Mark and Andrew took on X.Org, Alan sketched out some ideas using HTML5 video, and I looked into desktop sharing.
Exploring X solutions
X.Org was an obvious first place to look. Screens can be port-forwarded and displayed in chunks in all sorts of flexible ways at a driver level. Thus, a good deal of Mark and Andrew’s time on day one was spent looking at how this might be utilised.
Initial research suggested plenty of commercial solutions were available, but we were keen to use something that was free (in both senses of the word). Some projects were dual-licensed and were therefore explored, but these did not feel solid. The problem with the majority of these was a lack of, or incomplete, documentation.
Mark and Andrew moved on to look at Xdmx. There are two major versions of this, the second having been merged into X itself. Better luck was had here: a video was displayed across the screens of two laptops, with no visible screen tearing or lag. Minor configuration problems remained however, as the pointer could not be moved past the boundaries of the primary screen.
That in itself was not a deal-breaker, so attention was given to moving and resizing windows. This was necessary to either open a window across all screens, or to open windows on individual screens. Here wmctrl and xdotool were tried, but ran into problems: the former had difficulty finding window IDs for the X server, and the latter could not differentiate between two windows having the same title. Given our time constraints, this avenue was therefore abandoned, despite feeling frustratingly close!
In the meantime, Alan had expressed interest in looking at HTML5 video, zoomed up in a full-screen browser, and using divs to reveal the appropriate quadrant. This makes use of the Popcorn library from Mozilla, and loads a playlist via an AJAX call. This exhibits some minor screen tearing, likely due to the differing capabilities of our old machines, but nevertheless makes for a great quick-n-easy solution.
As the X.Org and browser-based video methods was being investigated I researched
into using VNC. Two broad strategies were appropriate for the results we required:
multiple VNC servers on the master, and a single server on
the master (using
-shared) with which slaves can communicate. As time was a limitation
the former was preferred as it looked to be able to provide a solution quickly. X11vnc
came to the rescue by having a
-clip switch built in.
This was prototyped on one machine using virtual boxes to start with, prior
to being tried on the laptop wall. The
master works out the screen dimensions of each section (a 2x2 uses quadrants,
but this could be trivially changed for other wall sizes). A server is then
brought up on a different, configurable port per screen section. Password-less SSH
was set up to each slave, so a viewer (
xtightvncviewer in our case) could be
brought up using switches to full-screen and scale each one up.
The end result is again easy to get working; for desktop broadcast across a wall it’s fine, though network latency means that it’s not suitable for video.
Prior to our demonstration, Mark put in a valiant effort tying all of our sub-projects together with Python duct-tape, with the rest of us sitting idly by and drinking tea. This offered a simple API service where external projects could request content to be displayed. A rough set of guidelines was created to define the attributes that the API should include.
We agreed as a team that the most extensible solution would be to allow the user to request for a web page to be presented. Another attribute which was later included was to define within the request if the browser window is displayed full screen over all the monitors, or one browser per monitor.
Flask felt like it was an advantageous micro-framework to use for prototyping due to its incredible simplicity and single threaded request model. This allowed the implementation to concentrate on the solution rather than worrying about multi-threading issues and how to bend the framework into place.
To provide a solution quickly a mixture of dynamic routes which includes data and get parameter attributes was used to pass the data. The format of the request was as follows:
wget http://127.0.0.1:5000/spawn_window/windowed?url=google.co.uk wget http://127.0.0.1:5000/spawn_window/fullscreen?url=stackoverflow.com
The idea was for the API to close the VNC connections if the user required to display their website on a indiviual screen, and to re-initialise VNC when it was required for full screen mode. The solution was never fully completed as debugging the solution (multiple PHP/Python scripts and SSH sessions) was expensive for our dwindling timeframe.
There’s plenty of stuff we’d have liked to do further work on, the Xdmx solution being at the top of the list. Commercial video wall solutions allow for arbitrary combinations of effects, so a 3x3 wall might have a 2x2 video, then browsers being opened on a round-robin basis in the remaining five. That would be good to add also.
The repo is incomplete at present, but we’ll get that ship-shape over the coming few days. We’d be pleased if some our of ideas help shape your own approaches, and if you want to share any code improvements you’ve made, we’d love to see ‘em.