Screen streaming to multiple devices via network

Image for post
Image for post

I had a need to show dashboard with monitoring information on several screens in the office. There are several old Raspberry Pi Model B+ and a hypervisor with a virtually unlimited amount of resources.

Apparently the Raspberry Pi Model B+ does not have enough power to keep the browser running constantly and draw a large amount of graphics in it, which is why the page is partially buggy and often crashes.

I found a fairly simple and elegant solution, which I want to share with you.

As you know, all Raspberries have a quite powerful video processor, which is great for hardware video decoding. This is how the idea to launch a browser with dashboard somewhere else appeared, and to connect a stream with a rendered image to the respberry.

Plus, it should have simplified management, since in this case the whole setup will be performed on one virtual machine, which is easier to update and back up it.

No sooner said than done.

Server installation

We will use the ready Ubuntu Cloud Image. It does not require installation and contains everything you need to quickly deploy a virtual machine, Cloud Init Support helps you instantly configure your network, add ssh keys, and quickly prepare VM to run.

Now, let’s deploy a new virtual machine and install Xorg, nodm and fluxbox on it:

apt-get update
apt-get install -y xserver-xorg nodm fluxbox
sed -i 's/^NODM_USER=.*/NODM_USER=ubuntu/' /etc/default/nodm

Also we’ll use the config for Xorg, kindly provided by Diego Ongaro, and add the new resolution: 1920x1080, since all of our screens will use it:

cat > /etc/X11/xorg.conf <<\EOT
Section "Device"
Identifier "device"
Driver "vesa"

Section "Screen"
Identifier "screen"
Device "device"
Monitor "monitor"
DefaultDepth 16
SubSection "Display"
Modes "1920x1080" "1280x1024" "1024x768" "800x600"

Section "Monitor"
Identifier "monitor"
HorizSync 20.0 - 50.0
VertRefresh 40.0 - 80.0
Option "DPMS"

Section "ServerLayout"
Identifier "layout"
Screen "screen"

systemctl restart nodm

Now we will install Firefox, we will run it as a systemd service, so we also should write a unit-file for it:

apt-get install -y firefox xdotool

cat > /etc/systemd/system/firefox.service <<\EOT

ExecStart=/usr/bin/firefox -url ''
ExecStartPost=/usr/bin/xdotool search --sync --onlyvisible --class "Firefox" windowactivate key F11


systemctl enable firefox
systemctl start firefox

Xdotool is needed to launch firefox in full screen at once.
Using the -url parameter, you can specify any page so that it opens automatically when the browser starts.

At this stage, our kiosk is ready, and now we need to export the picture over the network to other screens and devices. To achieve this, we will use the Motion JPEG format, that is most commonly used for streaming video from most webcams.

We need two things: FFmpeg with the x11grab module, to capture the image from the X-server and streamEye, which will distribute it to our clients:

apt-get install -y make gcc ffmpeg 

cd /tmp/
tar xvf master.tar.gz
cd streameye-master/
make install

cat > /etc/systemd/system/streameye.service <<\EOT

ExecStart=/bin/sh -c 'ffmpeg -f x11grab -s 1920x1080 -i :0 -r 1 -f mjpeg -q:v 5 - 2>/dev/null | streameye'


systemctl enable streameye
systemctl start streameye

Since our picture does not require a quick refresh, I specified update rate: 1 frame per second (option -r 1) and compression quality: 5 (option -q:v 5)

Now we can try to go on http://your-vm:8080/, on the page you will see a constantly updated screenshot of the desktop. Cool! — that was what was needed.

Client installation

Luckily it’s even easier, as I said we will use the Raspberry Pi Model B+.

First we need to install Arch Linux ARM on it, for achieve this just follow the instruction on the official website.

We also need to allocate more memory for GPU chip, edit in /boot/config.txt:


Now let’s boot our new system and install OMXPlayer on it, do not forget to initialize the pacman keyring first:

pacman -Sy omxplayer

Remarkably, OMXPlayer can work without X-server, so all we need is to write a unit-file and run it:

cat > /etc/systemd/system/omxplayer.service <<\EOT

ExecStart=/usr/bin/omxplayer -r --live -b http://your-vm:8080/ --aspect-mode full


systemctl enable omxplayer
systemctl start omxplayer

We pass the URL of our server in the `-b http://your-vm:8080/` option.

That’s all, on the connected screen should immediately appear a picture from our server. In case of any problems, the stream will be automatically restarted, and clients will reconnect to it.

As a bonus, you can set this picture as a screensaver on all computers in the office. To do this, you need MPV and XScreenSaver:

mode:  one
selected: 0
programs: \
"Monitoring Screen" mpv --really-quiet --no-audio --fs \
--loop=inf --no-stop-screensaver \
http://your-vm:8080/ \n\
maze -root \n\
electricsheep --root 1 \n\

Now your colleagues will be very surprised :)

Written by

This mess is mine!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store