Designing a six channel 24/7 streaming video player for digital signage


So here are the design goals:

  • Provide atleast 6 channels of streaming video.
  • Allow “hot” switching between streams using a remote control.
  • Allow network to fail and be able to have the stream automatically recover.
  • Allow the Pi to autostart on a particular stream when powered.
  • Be flexible enough to potentially provide more than 6 channels of streaming video.
  • System will be hosted on a read-only Micro-SD card to lessen the chance of long term SD corruption.

Here are the assumptions:

  • System is based on Raspberry Pi 2 B+ as a minimum (old Pi 1 and Pi zero have not been tested, but should work).
  • System uses HDMI audio and or analogue audio out from Pi’s 3.5mm jack.
  • System is limited to 720p and 1080p output.
  • System has been tested with video streams up to 6Mb/s.
  • System works with rtmp streaming protocol. Tested with Wowza Streaming server providing 6 streams.

Requirements:

  • Pi 2 B+ or better.
  • Latest raspbian jessie or better.
  • HDMI monitor and cable for testing.
  • Good Pi power supply 5V@2A.
  • speaker or headphone for monitoring during testing phase.
  • 8 GB Micro-SD card.
  • USB keyboard and Mouse (for the building phase only).
  • Ethernet cable.
  • A simple remote control with number pad.
  • A Flirc IR receiver. There are other ways of getting IR into Pi, but this is by far the easiest.

Here we go……

  • So write the raspbian image file to sd.
  • Hook up everything and do your first boot.
  • Pi will boot up and resize the filesystem automatically and reboot. Then you’ll end up in X-windows.
  • Open up terminal and run “sudo raspi-config” command.
  • Change the hostname to something. I chose “signage” for mine.
  • Enable SSH (option 5/P2), enable CLI boot (option 3/B1/B1), change memory split to 128Mb (option 7/A3), change password (option 1) and anything you need under localization options.

Take the reboot at the end of this process. Once back you should have the signage login screen with “Welcome to PIXEL” graphic on the screen. Lets continue……

  • Since my workstation is on the same network as the Pi I can do the following, if you’re not, you can always login (remember the password) using keyboard and issue the command “sudo ifconfig” to find the IP address of your Pi.
  • Use “ssh pi@signage.local” to login to the Pi from your workstation (on windows you need a program like putty to facilitate ssh connections).
  • sudo to root and follow along
  • Update and upgrade to latest greatest
    pi@signage:~ $ sudo -i
    root@signage:~# apt-get update ; apt-get dist-upgrade 
    Get:1 http://mirrordirector.raspbian.org jessie InRelease [14.9 kB]
    Get:2 http://mirrordirector.raspbian.org jessie/main armhf Packages [8,981 kB]
    Get:3 http://archive.raspberrypi.org jessie InRelease [22.9 kB]            
    Get:4 http://archive.raspberrypi.org jessie/main armhf Packages [145 kB]   
    Get:5 http://archive.raspberrypi.org jessie/ui armhf Packages [57.9 kB]                                           
    Ign http://archive.raspberrypi.org jessie/main Translation-en_US                                                                                     
    Ign http://archive.raspberrypi.org jessie/main Translation-en                                                                                        
    Ign http://archive.raspberrypi.org jessie/ui Translation-en_US                                                                                       
    Ign http://archive.raspberrypi.org jessie/ui Translation-en                                                                                          
    Get:6 http://mirrordirector.raspbian.org jessie/contrib armhf Packages [37.5 kB]                                                                     
    Get:7 http://mirrordirector.raspbian.org jessie/non-free armhf Packages [70.3 kB]                                                                    
    Get:8 http://mirrordirector.raspbian.org jessie/rpi armhf Packages [1,356 B]                                                                         
    Ign http://mirrordirector.raspbian.org jessie/contrib Translation-en_US                                                                              
    Ign http://mirrordirector.raspbian.org jessie/contrib Translation-en                                                                                 
    Ign http://mirrordirector.raspbian.org jessie/main Translation-en_US                                                                                 
    Ign http://mirrordirector.raspbian.org jessie/main Translation-en                                                                                    
    Ign http://mirrordirector.raspbian.org jessie/non-free Translation-en_US                                                                             
    Ign http://mirrordirector.raspbian.org jessie/non-free Translation-en                                                                                
    Ign http://mirrordirector.raspbian.org jessie/rpi Translation-en_US                                                                                  
    Ign http://mirrordirector.raspbian.org jessie/rpi Translation-en                                                                                     
    Fetched 9,330 kB in 50s (185 kB/s)                                                                                                                   
    Reading package lists... Done
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    Calculating upgrade... Done
    The following packages will be upgraded:
      alacarte gstreamer1.0-alsa gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-x libaudiofile1
      libgstreamer-plugins-bad1.0-0 libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 libopenblas-base libpam-chksshpwd libpam-modules libpam-modules-bin
      libpam-runtime libpam0g libsmbclient libwbclient0 pi-greeter piclone pix-plym-splash raspberrypi-sys-mods raspberrypi-ui-mods raspi-config
      realvnc-vnc-server rpi-chromium-mods samba-common samba-libs wiringpi wolfram-engine
    30 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    Need to get 274 MB of archives.
    After this operation, 1,623 kB disk space will be freed.
    Do you want to continue? [Y/n] y
    Get:1 http://archive.raspberrypi.org/debian/ jessie/main libpam0g armhf 1.1.8-3.1+deb8u2+rpi3 [121 kB]
    Get:2 http://mirrordirector.raspbian.org/raspbian/ jessie/main libgstreamer1.0-0 armhf 1.4.4-2+deb8u1 [1,593 kB]
    Get:3 http://mirrordirector.raspbian.org/raspbian/ jessie/main libaudiofile1 armhf 0.3.6-2+deb8u2 [97.1 kB]
    Get:4 http://archive.raspberrypi.org/debian/ jessie/main libpam-modules-bin armhf 1.1.8-3.1+deb8u2+rpi3 [101 kB] 
    Get:5 http://archive.raspberrypi.org/debian/ jessie/main libpam-modules armhf 1.1.8-3.1+deb8u2+rpi3 [288 kB]
    Get:6 http://mirrordirector.raspbian.org/raspbian/ jessie/main libgstreamer-plugins-base1.0-0 armhf 1.4.4-2+deb8u1 [1,248 kB]
    Get:7 http://mirrordirector.raspbian.org/raspbian/ jessie/main libwbclient0 armhf 2:4.2.14+dfsg-0+deb8u4 [118 kB]
    Get:8 http://archive.raspberrypi.org/debian/ jessie/main wolfram-engine armhf 11.0.1+2017031701 [240 MB]           
    Get:9 http://mirrordirector.raspbian.org/raspbian/ jessie/main libsmbclient armhf 2:4.2.14+dfsg-0+deb8u4 [139 kB]
    Get:10 http://mirrordirector.raspbian.org/raspbian/ jessie/main samba-libs armhf 2:4.2.14+dfsg-0+deb8u4 [4,246 kB]
    Get:11 http://mirrordirector.raspbian.org/raspbian/ jessie/main gstreamer1.0-plugins-good armhf 1.4.4-2+deb8u3 [2,218 kB]
    Get:12 http://mirrordirector.raspbian.org/raspbian/ jessie/main gstreamer1.0-plugins-bad armhf 1.4.4-2.1+deb8u2 [2,231 kB]     
    Get:13 http://mirrordirector.raspbian.org/raspbian/ jessie/main gstreamer1.0-plugins-base armhf 1.4.4-2+deb8u1 [1,236 kB]                            
    Get:14 http://mirrordirector.raspbian.org/raspbian/ jessie/main samba-common all 2:4.2.14+dfsg-0+deb8u4 [243 kB]                                     
    Get:15 http://mirrordirector.raspbian.org/raspbian/ jessie/main libgstreamer-plugins-bad1.0-0 armhf 1.4.4-2.1+deb8u2 [1,299 kB]                      
    Get:16 http://mirrordirector.raspbian.org/raspbian/ jessie/main gstreamer1.0-alsa armhf 1.4.4-2+deb8u1 [790 kB]                                      
    Get:17 http://mirrordirector.raspbian.org/raspbian/ jessie/main gstreamer1.0-x armhf 1.4.4-2+deb8u1 [823 kB]                                         
    Get:18 http://archive.raspberrypi.org/debian/ jessie/main libpam-runtime all 1.1.8-3.1+deb8u2+rpi3 [213 kB]                                          
    Get:19 http://archive.raspberrypi.org/debian/ jessie/ui alacarte all 3.11.91-2+rpi4 [111 kB]                                                         
    Get:20 http://archive.raspberrypi.org/debian/ jessie/main libopenblas-base armhf 0.2.12-1+rpi1 [1,688 kB]                                            
    Get:21 http://archive.raspberrypi.org/debian/ jessie/main libpam-chksshpwd armhf 1.1.8-3.1+deb8u2+rpi3 [79.3 kB]                                     
    Get:22 http://archive.raspberrypi.org/debian/ jessie/ui pi-greeter armhf 0.4 [41.3 kB]                                                               
    Get:23 http://archive.raspberrypi.org/debian/ jessie/ui piclone armhf 0.4 [13.2 kB]                                                                  
    Get:24 http://archive.raspberrypi.org/debian/ jessie/ui pix-plym-splash armhf 0.9 [25.4 kB]                                                          
    Get:25 http://archive.raspberrypi.org/debian/ jessie/main raspberrypi-sys-mods all 20170313 [8,596 B]                                                
    Get:26 http://archive.raspberrypi.org/debian/ jessie/main realvnc-vnc-server armhf 6.0.2.26558 [5,305 kB]                                            
    Get:27 http://archive.raspberrypi.org/debian/ jessie/ui rpi-chromium-mods armhf 20170317 [9,185 kB]                                                  
    Get:28 http://archive.raspberrypi.org/debian/ jessie/main wiringpi armhf 2.44 [52.7 kB]                                                              
    Get:29 http://archive.raspberrypi.org/debian/ jessie/ui raspberrypi-ui-mods all 1.20170315 [426 kB]                                                  
    Get:30 http://archive.raspberrypi.org/debian/ jessie/main raspi-config all 20170307 [18.7 kB]                                                        
    Fetched 274 MB in 22min 41s (201 kB/s)                                                                                                               
    Reading changelogs... Done
    Preconfiguring packages ...
    (Reading database ... 112361 files and directories currently installed.)
    Preparing to unpack .../libpam0g_1.1.8-3.1+deb8u2+rpi3_armhf.deb ...
    Unpacking libpam0g:armhf (1.1.8-3.1+deb8u2+rpi3) over (1.1.8-3.1+deb8u2+rpi1) ...
    Processing triggers for libc-bin (2.19-18+deb8u7) ...
    Setting up libpam0g:armhf (1.1.8-3.1+deb8u2+rpi3) ...
    Processing triggers for libc-bin (2.19-18+deb8u7) ...
    (Reading database ... 112361 files and directories currently installed.)
    Preparing to unpack .../libpam-modules-bin_1.1.8-3.1+deb8u2+rpi3_armhf.deb ...
    Unpacking libpam-modules-bin (1.1.8-3.1+deb8u2+rpi3) over (1.1.8-3.1+deb8u2+rpi1) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Setting up libpam-modules-bin (1.1.8-3.1+deb8u2+rpi3) ...
    (Reading database ... 112361 files and directories currently installed.)
    Preparing to unpack .../libpam-modules_1.1.8-3.1+deb8u2+rpi3_armhf.deb ...
    Unpacking libpam-modules:armhf (1.1.8-3.1+deb8u2+rpi3) over (1.1.8-3.1+deb8u2+rpi1) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Setting up libpam-modules:armhf (1.1.8-3.1+deb8u2+rpi3) ...
    (Reading database ... 112361 files and directories currently installed.)
    Preparing to unpack .../libaudiofile1_0.3.6-2+deb8u2_armhf.deb ...
    Unpacking libaudiofile1:armhf (0.3.6-2+deb8u2) over (0.3.6-2+deb8u1) ...
    Preparing to unpack .../libgstreamer1.0-0_1.4.4-2+deb8u1_armhf.deb ...
    Unpacking libgstreamer1.0-0:armhf (1.4.4-2+deb8u1) over (1.4.4-2) ...
    Preparing to unpack .../libgstreamer-plugins-base1.0-0_1.4.4-2+deb8u1_armhf.deb ...
    Unpacking libgstreamer-plugins-base1.0-0:armhf (1.4.4-2+deb8u1) over (1.4.4-2) ...
    Preparing to unpack .../libwbclient0_2%3a4.2.14+dfsg-0+deb8u4_armhf.deb ...
    Unpacking libwbclient0:armhf (2:4.2.14+dfsg-0+deb8u4) over (2:4.2.14+dfsg-0+deb8u2) ...
    Preparing to unpack .../libsmbclient_2%3a4.2.14+dfsg-0+deb8u4_armhf.deb ...
    Unpacking libsmbclient:armhf (2:4.2.14+dfsg-0+deb8u4) over (2:4.2.14+dfsg-0+deb8u2) ...
    Preparing to unpack .../samba-libs_2%3a4.2.14+dfsg-0+deb8u4_armhf.deb ...
    Unpacking samba-libs:armhf (2:4.2.14+dfsg-0+deb8u4) over (2:4.2.14+dfsg-0+deb8u2) ...
    Preparing to unpack .../samba-common_2%3a4.2.14+dfsg-0+deb8u4_all.deb ...
    Unpacking samba-common (2:4.2.14+dfsg-0+deb8u4) over (2:4.2.14+dfsg-0+deb8u2) ...
    Preparing to unpack .../wolfram-engine_11.0.1+2017031701_armhf.deb ...
    wolfram-eula license has already been accepted
    Unpacking wolfram-engine (11.0.1+2017031701) over (11.0.1+2017022002) ...
    Preparing to unpack .../gstreamer1.0-plugins-good_1.4.4-2+deb8u3_armhf.deb ...
    Unpacking gstreamer1.0-plugins-good:armhf (1.4.4-2+deb8u3) over (1.4.4-2+deb8u2) ...
    Preparing to unpack .../gstreamer1.0-plugins-bad_1.4.4-2.1+deb8u2_armhf.deb ...
    Unpacking gstreamer1.0-plugins-bad:armhf (1.4.4-2.1+deb8u2) over (1.4.4-2.1+deb8u1) ...
    Preparing to unpack .../gstreamer1.0-plugins-base_1.4.4-2+deb8u1_armhf.deb ...
    Unpacking gstreamer1.0-plugins-base:armhf (1.4.4-2+deb8u1) over (1.4.4-2) ...
    Preparing to unpack .../libgstreamer-plugins-bad1.0-0_1.4.4-2.1+deb8u2_armhf.deb ...
    Unpacking libgstreamer-plugins-bad1.0-0:armhf (1.4.4-2.1+deb8u2) over (1.4.4-2.1+deb8u1) ...
    Preparing to unpack .../libpam-runtime_1.1.8-3.1+deb8u2+rpi3_all.deb ...
    Unpacking libpam-runtime (1.1.8-3.1+deb8u2+rpi3) over (1.1.8-3.1+deb8u2+rpi1) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Processing triggers for hicolor-icon-theme (0.13-1) ...
    Processing triggers for shared-mime-info (1.3-1) ...
    Processing triggers for gnome-menus (3.13.3-6) ...
    Processing triggers for desktop-file-utils (0.22-1) ...
    Processing triggers for mime-support (3.58) ...
    Setting up libpam-runtime (1.1.8-3.1+deb8u2+rpi3) ...
    (Reading database ... 112361 files and directories currently installed.)
    Preparing to unpack .../alacarte_3.11.91-2+rpi4_all.deb ...
    Unpacking alacarte (3.11.91-2+rpi4) over (3.11.91-2+rpi2) ...
    Preparing to unpack .../gstreamer1.0-alsa_1.4.4-2+deb8u1_armhf.deb ...
    Unpacking gstreamer1.0-alsa:armhf (1.4.4-2+deb8u1) over (1.4.4-2) ...
    Preparing to unpack .../gstreamer1.0-x_1.4.4-2+deb8u1_armhf.deb ...
    Unpacking gstreamer1.0-x:armhf (1.4.4-2+deb8u1) over (1.4.4-2) ...
    Preparing to unpack .../libopenblas-base_0.2.12-1+rpi1_armhf.deb ...
    Unpacking libopenblas-base (0.2.12-1+rpi1) over (0.2.12-1) ...
    Preparing to unpack .../libpam-chksshpwd_1.1.8-3.1+deb8u2+rpi3_armhf.deb ...
    Unpacking libpam-chksshpwd:armhf (1.1.8-3.1+deb8u2+rpi3) over (1.1.8-3.1+deb8u2+rpi1) ...
    Preparing to unpack .../pi-greeter_0.4_armhf.deb ...
    Unpacking pi-greeter (0.4) over (0.3) ...
    Preparing to unpack .../archives/piclone_0.4_armhf.deb ...
    Unpacking piclone (0.4) over (0.3) ...
    Preparing to unpack .../pix-plym-splash_0.9_armhf.deb ...
    Unpacking pix-plym-splash (0.9) over (0.8) ...
    Preparing to unpack .../raspberrypi-sys-mods_20170313_all.deb ...
    Unpacking raspberrypi-sys-mods (20170313) over (20170302) ...
    Preparing to unpack .../realvnc-vnc-server_6.0.2.26558_armhf.deb ...
    
    (gconftool-2:18645): GConf-WARNING **: Client failed to connect to the D-BUS daemon:
    Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
    Unpacking realvnc-vnc-server (6.0.2.26558) over (6.0.2.25562) ...
    Preparing to unpack .../rpi-chromium-mods_20170317_armhf.deb ...
    Unpacking rpi-chromium-mods (20170317) over (20170213) ...
    Preparing to unpack .../wiringpi_2.44_armhf.deb ...
    Unpacking wiringpi (2.44) over (2.42) ...
    Preparing to unpack .../raspberrypi-ui-mods_1.20170315_all.deb ...
    Unpacking raspberrypi-ui-mods (1.20170315) over (1.20170301) ...
    Preparing to unpack .../raspi-config_20170307_all.deb ...
    Unpacking raspi-config (20170307) over (20170228) ...
    Processing triggers for gnome-menus (3.13.3-6) ...
    Processing triggers for desktop-file-utils (0.22-1) ...
    Processing triggers for mime-support (3.58) ...
    Processing triggers for hicolor-icon-theme (0.13-1) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Processing triggers for libc-bin (2.19-18+deb8u7) ...
    Processing triggers for gconf2 (3.2.6-3) ...
    Processing triggers for shared-mime-info (1.3-1) ...
    Processing triggers for systemd (215-17+deb8u6) ...
    Setting up libaudiofile1:armhf (0.3.6-2+deb8u2) ...
    Setting up libgstreamer1.0-0:armhf (1.4.4-2+deb8u1) ...
    Setting up libgstreamer-plugins-base1.0-0:armhf (1.4.4-2+deb8u1) ...
    Setting up libwbclient0:armhf (2:4.2.14+dfsg-0+deb8u4) ...
    Setting up samba-libs:armhf (2:4.2.14+dfsg-0+deb8u4) ...
    Setting up libsmbclient:armhf (2:4.2.14+dfsg-0+deb8u4) ...
    Setting up samba-common (2:4.2.14+dfsg-0+deb8u4) ...
    Setting up wolfram-engine (11.0.1+2017031701) ...
    Setting up gstreamer1.0-plugins-base:armhf (1.4.4-2+deb8u1) ...
    Setting up gstreamer1.0-plugins-good:armhf (1.4.4-2+deb8u3) ...
    Setting up libgstreamer-plugins-bad1.0-0:armhf (1.4.4-2.1+deb8u2) ...
    Setting up gstreamer1.0-plugins-bad:armhf (1.4.4-2.1+deb8u2) ...
    Setting up alacarte (3.11.91-2+rpi4) ...
    Setting up gstreamer1.0-alsa:armhf (1.4.4-2+deb8u1) ...
    Setting up gstreamer1.0-x:armhf (1.4.4-2+deb8u1) ...
    Setting up libopenblas-base (0.2.12-1+rpi1) ...
    update-alternatives: using /usr/lib/libblas/libblas.so.3 to provide /usr/lib/libblas.so.3 (libblas.so.3) in auto mode
    update-alternatives: using /usr/lib/lapack/liblapack.so.3 to provide /usr/lib/liblapack.so.3 (liblapack.so.3) in auto mode
    Setting up libpam-chksshpwd:armhf (1.1.8-3.1+deb8u2+rpi3) ...
    Installing new version of config file /etc/profile.d/sshpwd.sh ...
    Setting up pi-greeter (0.4) ...
    Setting up piclone (0.4) ...
    Setting up pix-plym-splash (0.9) ...
    Setting up raspberrypi-sys-mods (20170313) ...
    Updating documentation URL in /boot/config.txt...
    Setting up realvnc-vnc-server (6.0.2.26558) ...
    Updating /etc/pam.d/vncserver
    Updating /etc/pam.conf... done
    Looking for font path... not found.
    Generating private key... done
    Installed systemd unit for VNC Server in Service Mode daemon
    Start or stop the service with:
      systemctl (start|stop) vncserver-x11-serviced.service
    Mark or unmark the service to be started at boot time with:
      systemctl (enable|disable) vncserver-x11-serviced.service
    
    Installed systemd unit for VNC Server in Virtual Mode daemon
    Start or stop the service with:
      systemctl (start|stop) vncserver-virtuald.service
    Mark or unmark the service to be started at boot time with:
      systemctl (enable|disable) vncserver-virtuald.service
    
    
    (gconftool-2:19580): GConf-WARNING **: Client failed to connect to the D-BUS daemon:
    Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
    gconfd-2: no process found
    Setting up rpi-chromium-mods (20170317) ...
    Setting up wiringpi (2.44) ...
    Setting up raspberrypi-ui-mods (1.20170315) ...
    Setting up raspi-config (20170307) ...
    Processing triggers for libc-bin (2.19-18+deb8u7) ...
    root@signage:~# 
    
  • Reboot in case there are Kernel changes or library updates.
  • Strip extra packages that we’ll never use
    root@signage:~# apt-get remove --purge wolfram-engine cron logrotate dphys-swapfile xserver-common lightdm
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    The following packages were automatically installed and are no longer required:
      coinor-libipopt1 dc fontconfig-infinality fonts-droid fonts-roboto gtk2-engines-clearlookspix libboost-filesystem1.55.0
      libboost-program-options1.55.0 libboost-regex1.55.0 libffi5 libgmime-2.6-0 libmumps-seq-4.10.0 liboauth0 libraw10 libxfce4util-bin
      libxfce4util-common libxfce4util6 libxfconf-0-2 pi-greeter pimixer pipanel pishutdown pix-icons pix-plym-splash pixel-wallpaper point-rpi
      wolframscript xfconf
    Use 'apt-get autoremove' to remove them.
    The following packages will be REMOVED:
      dphys-swapfile* lightdm* logrotate* raspberrypi-ui-mods* wolfram-engine* xserver-common* xserver-xorg* xserver-xorg-core* xserver-xorg-input-all*
      xserver-xorg-input-libinput* xserver-xorg-video-fbdev* xserver-xorg-video-fbturbo*
    0 upgraded, 0 newly installed, 12 to remove and 0 not upgraded.
    After this operation, 693 MB disk space will be freed.
    Do you want to continue? [Y/n] y
    (Reading database ... 112367 files and directories currently installed.)
    Removing dphys-swapfile (20100506-1) ...
    Purging configuration files for dphys-swapfile (20100506-1) ...
    Removing raspberrypi-ui-mods (1.20170315) ...
    update-alternatives: using /usr/bin/startlxde to provide /usr/bin/x-session-manager (x-session-manager) in auto mode
    update-alternatives: using /usr/share/libgksu/debian/gconf-defaults.libgksu-su to provide /usr/share/gconf/defaults/10_libgksu (libgksu-gconf-defaults) in auto mode
    Purging configuration files for raspberrypi-ui-mods (1.20170315) ...
    Removing lightdm (1.10.3-3+rpi) ...
    Purging configuration files for lightdm (1.10.3-3+rpi) ...
    Removing user `lightdm' ...
    Warning: group `lightdm' has no more members.
    Done.
    Removing logrotate (3.8.7-1) ...
    Purging configuration files for logrotate (3.8.7-1) ...
    Removing wolfram-engine (11.0.1+2017031701) ...
    Purging configuration files for wolfram-engine (11.0.1+2017031701) ...
    Removing xserver-xorg (1:7.7+16) ...
    Purging configuration files for xserver-xorg (1:7.7+16) ...
    Removing xserver-xorg-video-fbturbo (1.20161111~122359) ...
    Removing xserver-xorg-video-fbdev (1:0.4.4-1+rpi2) ...
    Removing xserver-xorg-input-all (1:7.7+16) ...
    Removing xserver-xorg-input-libinput (0.20.0-1) ...
    Removing xserver-xorg-core (2:1.18.4-2+rpi1) ...
    Purging configuration files for xserver-xorg-core (2:1.18.4-2+rpi1) ...
    rm: cannot remove ‘/var/log/Xorg.*.log.old’: No such file or directory
    Removing xserver-common (2:1.18.4-2+rpi1) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Processing triggers for gnome-menus (3.13.3-6) ...
    Processing triggers for desktop-file-utils (0.22-1) ...
    Processing triggers for mime-support (3.58) ...
    Processing triggers for shared-mime-info (1.3-1) ...
    Processing triggers for hicolor-icon-theme (0.13-1) ...
    root@signage:~# apt-get autoremove 
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    The following packages will be REMOVED:
      coinor-libipopt1 dc fontconfig-infinality fonts-droid fonts-roboto gtk2-engines-clearlookspix libboost-filesystem1.55.0
      libboost-program-options1.55.0 libboost-regex1.55.0 libepoxy0 libevdev2 libffi5 libgmime-2.6-0 libinput-bin libinput10 liblightdm-gobject-1-0
      libmumps-seq-4.10.0 liboauth0 libpciaccess0 libraw10 libwacom-common libwacom2 libxfce4util-bin libxfce4util-common libxfce4util6 libxfconf-0-2
      lightdm-gtk-greeter pi-greeter pimixer pipanel pishutdown pix-icons pix-plym-splash pixel-wallpaper point-rpi wolframscript xfconf
    0 upgraded, 0 newly installed, 37 to remove and 0 not upgraded.
    After this operation, 65.2 MB disk space will be freed.
    Do you want to continue? [Y/n] y
    (Reading database ... 102396 files and directories currently installed.)
    Removing coinor-libipopt1 (3.11.9-2) ...
    Removing dc (1.06.95-9) ...
    Removing fontconfig-infinality (20130104-0ubuntu0ppa1+rpi) ...
    Removing fonts-droid (1:4.4.4r2-6+rpi1) ...
    Removing fonts-roboto (1:4.4.4r2-6+rpi1) ...
    Removing gtk2-engines-clearlookspix:armhf (1:2.20.4) ...
    Removing wolframscript (1.0.1-19) ...
    Removing libboost-filesystem1.55.0:armhf (1.55.0+dfsg-3) ...
    Removing libboost-program-options1.55.0:armhf (1.55.0+dfsg-3) ...
    Removing libboost-regex1.55.0:armhf (1.55.0+dfsg-3) ...
    Removing libepoxy0 (1.2-1) ...
    Removing libinput10:armhf (1.5.0-1) ...
    Removing libevdev2 (1.3+dfsg-1) ...
    Removing libffi5:armhf (3.0.10-3+rpi1) ...
    Removing libgmime-2.6-0:armhf (2.6.20-1) ...
    Removing libinput-bin (1.5.0-1) ...
    Removing pi-greeter (0.4) ...
    update-alternatives: using /usr/share/xgreeters/lightdm-gtk-greeter.desktop to provide /usr/share/xgreeters/lightdm-greeter.desktop (lightdm-greeter) in auto mode
    Removing lightdm-gtk-greeter (1.8.5-2) ...
    Removing liblightdm-gobject-1-0 (1.10.3-3+rpi) ...
    Removing libmumps-seq-4.10.0 (4.10.0.dfsg-3+b2) ...
    Removing liboauth0:armhf (1.0.1-1) ...
    Removing libpciaccess0:armhf (0.13.2-3) ...
    Removing libraw10:armhf (0.16.0-9+deb8u2) ...
    Removing libwacom2:armhf (0.22-1) ...
    Removing libwacom-common (0.22-1) ...
    Removing libxfce4util-bin (4.10.1-2) ...
    Removing pimixer (0.20160527~090638-1) ...
    Removing libxfconf-0-2 (4.10.0-3) ...
    Removing xfconf (4.10.0-3) ...
    Removing libxfce4util6 (4.10.1-2) ...
    Removing libxfce4util-common (4.10.1-2) ...
    Removing pipanel (20161206~130650) ...
    Removing pishutdown (0.7) ...
    Removing 'diversion of /usr/bin/lxde-pi-shutdown-helper to /usr/bin/lxde-pi-shutdown-helper.old by pishutdown'
    Removing pix-icons (0.4) ...
    Removing pix-plym-splash (0.9) ...
    Removing pixel-wallpaper (0.3) ...
    Removing point-rpi (0.20160905) ...
    Processing triggers for libc-bin (2.19-18+deb8u7) ...
    Processing triggers for install-info (5.2.0.dfsg.1-6) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Processing triggers for fontconfig (2.11.0-6.3+deb8u1) ...
    Processing triggers for shared-mime-info (1.3-1) ...
    Processing triggers for hicolor-icon-theme (0.13-1) ...
    Processing triggers for udev (215-17+deb8u6) ...
    Processing triggers for gnome-menus (3.13.3-6) ...
    Processing triggers for desktop-file-utils (0.22-1) ...
    Processing triggers for mime-support (3.58) ...
    root@signage:~# 
    root@signage:~# insserv -r x11-common; apt-get autoremove --purge
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    root@signage:~# 
    
  • Replace log management with busybox logger. This will put log into circular memory buffer, you will able to see log using “logread” command.
    root@signage:~# apt-get install busybox-syslogd; dpkg --purge rsyslog
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    The following extra packages will be installed:
      busybox
    The following packages will be REMOVED:
      rsyslog
    The following NEW packages will be installed:
      busybox busybox-syslogd
    0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
    Need to get 396 kB of archives.
    After this operation, 714 kB disk space will be freed.
    Do you want to continue? [Y/n] y
    Get:1 http://mirrordirector.raspbian.org/raspbian/ jessie/main busybox armhf 1:1.22.0-9+deb8u1 [373 kB]
    Get:2 http://mirrordirector.raspbian.org/raspbian/ jessie/main busybox-syslogd all 1:1.22.0-9+deb8u1 [23.4 kB]
    Fetched 396 kB in 1s (352 kB/s)            
    (Reading database ... 100170 files and directories currently installed.)
    Removing rsyslog (8.4.2-1+deb8u2) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Selecting previously unselected package busybox.
    (Reading database ... 100122 files and directories currently installed.)
    Preparing to unpack .../busybox_1%3a1.22.0-9+deb8u1_armhf.deb ...
    Unpacking busybox (1:1.22.0-9+deb8u1) ...
    Selecting previously unselected package busybox-syslogd.
    Preparing to unpack .../busybox-syslogd_1%3a1.22.0-9+deb8u1_all.deb ...
    Unpacking busybox-syslogd (1:1.22.0-9+deb8u1) ...
    Processing triggers for man-db (2.7.0.2-5) ...
    Processing triggers for systemd (215-17+deb8u6) ...
    Setting up busybox (1:1.22.0-9+deb8u1) ...
    Setting up busybox-syslogd (1:1.22.0-9+deb8u1) ...
    Processing triggers for systemd (215-17+deb8u6) ...
    (Reading database ... 100143 files and directories currently installed.)
    Removing rsyslog (8.4.2-1+deb8u2) ...
    Purging configuration files for rsyslog (8.4.2-1+deb8u2) ...
    root@signage:~# 
  • Disable swap and filesystem check and make the system read-only. Edit /boot/cmdline.txt and add “fastboot noswap ro” to the end of the line (see below) to disable filesystem check at boot, turn off swap file usage and make the system read-only.
    dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait fastboot noswap ro
    
  • Move some system files to tmp filesystem
    root@signage:~# rm -rf /var/lib/dhcp/ /var/run /var/spool /var/lock /etc/resolv.conf
    root@signage:~# ln -s /tmp /var/lib/dhcp
    root@signage:~# ln -s /tmp /var/run
    root@signage:~# ln -s /tmp /var/spool
    root@signage:~# ln -s /tmp /var/lock
    root@signage:~# touch /tmp/dhcpcd.resolv.conf; ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf
    root@signage:~# 
    
  • The systemd file “random-seed” needs to be moved to a tmp filesystem as well. So do the following changes
    root@signage:~# rm /var/lib/systemd/random-seed
    root@signage:~# ln -s /tmp/random-seed /var/lib/systemd/random-seed
    root@signage:~# 
    
  • A small annoyance is the fact that sshd needs to read the logs and print out the Last Login information. We can disable that by modifying the file /etc/ssh/sshd_config and changing “PrintLastLog yes” to “PrintLastLog no”.
  • We also need to fix the DHCP startup script. Edit /etc/systemd/system/dhcpcd5 and change “PIDFile=/run/dhcpcd.pid” to “PIDFile=/var/run/dhcpcd.pid”. It should look like this when done:
    [Unit]
    Description=dhcpcd on all interfaces
    Wants=network.target
    Before=network.target
    
    [Service]
    Type=forking
    PIDFile=/var/run/dhcpcd.pid
    ExecStart=/sbin/dhcpcd -q -b
    ExecStop=/sbin/dhcpcd -x
    
    [Install]
    WantedBy=multi-user.target
    Alias=dhcpcd5
    
  • Now you need to fix the systemd service file to kickstart the random-seed service. For this we need to add the line ExecStartPre=/bin/echo "" >/tmp/random-seed to the service section of /lib/systemd/system/systemd-random-seed.service. The file will look like this once this is done:
    #  This file is part of systemd.
    #
    #  systemd is free software; you can redistribute it and/or modify it
    #  under the terms of the GNU Lesser General Public License as published by
    #  the Free Software Foundation; either version 2.1 of the License, or
    #  (at your option) any later version.
    
    [Unit]
    Description=Load/Save Random Seed
    Documentation=man:systemd-random-seed.service(8) man:random(4)
    DefaultDependencies=no
    RequiresMountsFor=/var/lib/systemd/random-seed
    Conflicts=shutdown.target
    After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
    Before=sysinit.target shutdown.target
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStartPre=/bin/echo "" >/tmp/random-seed
    ExecStart=/lib/systemd/systemd-random-seed load
    ExecStop=/lib/systemd/systemd-random-seed save
    
  • Run “systemctl daemon-reload” to reload and finalize the changes we just made.
  • Remove some of the startup scripts using “insserv -r bootlogs; insserv -r console-setup” and change the file /etc/fstab to reflect these changes. Mine looked like this to start with:
    proc            /proc           proc    defaults          0       0
    /dev/mmcblk0p1  /boot           vfat    defaults          0       2
    /dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
    # a swapfile is not a swap partition, no line here
    #   use  dphys-swapfile swap[on|off]  for that
    
  • Now it looks like this:
    proc            /proc           proc    defaults             0       0
    /dev/mmcblk0p1  /boot           vfat    defaults,ro          0       2
    /dev/mmcblk0p2  /               ext4    defaults,noatime,ro  0       1
    # Our tmpfs filesystems. Everything else (above) is read only.
    # To set system to Read-Write use:
    # mount -o remount,rw /
    # and to set it back to Read-Only:
    # mount -o remount,ro /
    tmpfs           /tmp            tmpfs   nosuid,nodev         0       0
    tmpfs           /var/log        tmpfs   nosuid,nodev         0       0
    tmpfs           /var/tmp        tmpfs   nosuid,nodev         0       0
    
  • At this point you can reboot, BUT you’ll come back in read-only mode. You could continue and take the reboot later. To change the filesystem between read-only (ro) and read-write (rw) you can use “mount -o remount,rw /” and “mount -o remount,ro /” commands.
  • To make life simpler we add the following to the end of /etc/bash.bashrc to introduce the “rw” and “ro” aliases and add filesystem mode indication to the shell prompt:
    # set variable identifying the filesystem you work in (used in the prompt below)
    set_bash_prompt(){
        fs_mode=$(mount | sed -n -e "s/^\/dev\/.* on \/ .*(\(r[w|o]\).*/\1/p")
        PS1='\[\033[01;32m\]\u@\h${fs_mode:+($fs_mode)}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    }
    
    alias ro='sudo mount -o remount,ro / ; sudo mount -o remount,ro /boot'
    alias rw='sudo mount -o remount,rw / ; sudo mount -o remount,rw /boot'
    alias reboot='sudo mount -o remount,rw / && history -a && sudo mount -o remount,ro / && sudo /sbin/reboot'
    
    # setup fancy prompt"
    PROMPT_COMMAND=set_bash_prompt
  • Also important is saving shell history before logout. So add the following to the file /etc/bash.bash_logout (it might not exist so create it):
    sudo mount -o remount,rw /
    history -a
    sudo fake-hwclock save
    sudo mount -o remount,ro /
    sudo mount -o remount,ro /boot
    
  • Okay so if you’ve made it this far you should be able to reboot and get a stable read-only system up and running after the reboot. Remember that “rw” and “ro” commands will allow you to toggle between read-only and read-write mode. I will not be mentioning this anymore after this point. You WILL need to be in read-write mode to perform the rest of these tutorial.
  • The main script that will run the show is below. Copy and paste it into /root/signage.sh (Yes, the name and location is very important as the script recursively calls itself. You can change this, but you need to edit the contents of the file aswell……you’ve been warned):
    #!/bin/bash
    ## OMXPlayer auto restart script
    ##
    ## Assign location of this script to variable
    ## Used to restart script after connection is lost
    signscript=/root/signage.sh
    
    ## Need this to kick omxplayer to play the stream when in background. If fifo pipe doesn't exist, create it.
    
    if [ ! -f /run/omxfifo ] ; then
    	mkfifo /run/omxfifo
    	chmod 700 /run/omxfifo
    fi
    
    ## If number of arguments is 0 then just start the default channel (equivalent to passing "fcad" as first argument).
    if [ $# -eq 0 ]
    then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/fcadsignage/live /dev/null 2>&1 &
     echo -n '' > /run/omxfifo
    ## If first argument is "fcad" switch to fcadsignage (default) channel
    elif [[ "$1" == fcad ]]; then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/fcadsignage/live /dev/null 2>&1 &
     echo -n '' > /run/omxfifo
    ## If first argument is "jrn" switch to jrnsignage channel
    elif [[ "$1" == jrn ]]; then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/jrnsignage/live /dev/null 2>&1 & 
    echo -n '' > /run/omxfifo
    ## If first argument is "gcn1" switch to GCN channel
    elif [[ "$1" == gcn1 ]]; then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/gcn1/live /dev/null 2>&1 & echo -
    n '' > /run/omxfifo
    ## If first argument is "gcn2" switch to RUTV channel
    elif [[ "$1" == gcn2 ]]; then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/gcn2/live /dev/null 2>&1 & echo -
    n '' > /run/omxfifo
    ## If first argument is "sl1" switch to spiritlive1 channel
    elif [[ "$1" == sl1 ]]; then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/spiritlive/live /dev/null 2>&1 & 
    echo -n '' > /run/omxfifo
    ## If first argument is "sl2" switch to spiritlive2 channel
    elif [[ "$1" == sl2 ]]; then
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/spiritlive/live1 /dev/null 2>&1 &
     echo -n '' > /run/omxfifo
    ## If first argument is anything else switch to Wowza's internal VOD sample stream
    else
    	/usr/bin/omxplayer -r --no-osd --no-keys --live -o both rtmp://blackwood.fcad.ryerson.ca:1935/vod/sample.mp4 /dev/null 2>&1 & e
    cho -n '' > /run/omxfifo
    fi
    
    sleep 0.2
    
    ## omxplayer.bin simply exits if the network dies. We need to monitor this and restart it.
    ## Loop to test if connection is present every 0.5 seconds
    while [ -n "$(/usr/bin/pgrep -f -u root omxplayer.bin)" ];
    do
    	sleep 0.5
    done
    
    
    ## If network connection connection dies execute this shell script itself (recursive) with the original 
    ## command line parameters (channel selection keyword) every 0.2 seconds until we are successful. As we 
    ## spawn new shells to execute the script the old shell is destroyed, so we don't have to worry about 
    ## running out of process space.
    sleep 0.2
    exec "$signscript" $@
    
  • Note that you can change the stream links above to whatever you want. Also the main if…elif…else…fi loop should be changed if you decide to use other command line parameters. But assuming you’re here and want to do a quick check, save the file (remember I’m assuming you’re in rw mode from here on), change it’s permissions via “chmod 700 signage.sh” and run it “./signage.sh”. Hopefully you have 5Mb/s bandwidth and in a few seconds can see the default signage from my school. If not stop here and troubleshoot the script. Use omxplayer from command line to see what’s going on.
  • Next we need to “teach” our FLIRC USB dongle what buttons do what. Grab the remote control you have and plugin the FLIRC dongle into a Mac or PC. Download the software to configure it from FLIRC’s website. Now use the software to configure the following correspondence:
    • F1 to 1 (on remote)
    • F2 to 2 (on remote)
    • ……
    • F10 to 0 (on remote)
  • You Can add more commands to the dongle later, this is just to get us started.
  • Take the dongle and plug it into the Pi. Run “thd –dump /dev/input/event0” and start pressing buttons on your remote. Did you get output like below (If yes continue, otherwise unplug all USB devices from the Pi and replug JUST the FLIRC into USB, this should force it to become “event0” input device)? Good……onwards……
  • Triggerhappy (thd) runs under nobody in raspbian, so we need to give nobody some special sudo privileges. There might be other ways to do this, but I found this simple enough. Create a new file “/etc/sudoers.d/020_nobody-nopasswd” with the following line in it:
    nobody ALL=(ALL) NOPASSWD: /usr/bin/pkill*,/bin/sleep*,/root/signage.sh*,/sbin/shutdown*,/bin/sync*
    
  • Now we need to tell thd what to do when we press buttons on our remote. Remember FLIRC turns IR commands to keyboard presses (F1-F10), so here we configure Triggerhappy to run commands based on buttons pushed (incidentally the commands in this file are the ones we specified above to allow nobody group to sudo. Anyways, edit /etc/triggerhappy/triggers.d/signage.conf” file and add the following contents to it:
    KEY_F1  1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F1  0       sudo sleep 0.2 ; sudo /root/signage.sh fcad
    KEY_F2  1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F2  0       sudo sleep 0.2 ; sudo /root/signage.sh jrn
    KEY_F3  1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F3  0       sudo sleep 0.2 ; sudo /root/signage.sh gcn1
    KEY_F4  1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F4  0       sudo sleep 0.2 ; sudo /root/signage.sh gcn2
    KEY_F5  1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F5  0       sudo sleep 0.2 ; sudo /root/signage.sh sl1
    KEY_F6  1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F6  0       sudo sleep 0.2 ; sudo /root/signage.sh sl2
    #KEY_F7 1       command
    #KEY_F7 0       command
    #KEY_F8 1       command
    #KEY_F8 0       command
    #KEY_F9 1       command
    #KEY_F9 0       command
    KEY_F10 1       sudo pkill -f -u root omxplayer.bin ; sudo pkill -f -u root signage.sh
    KEY_F10 0       sudo sleep 0.2 ; sudo /root/signage.sh sample
    
  • At this point if you want to auto start the signage at boot (with option to change the stream using remote) add the following line to your /etc/rc.local file:
  • We can take a reboot now and make sure things are working. Your default channel (from last step) should autoload now. You should also be able to switch channels using remote. If you disconnect the ethernet cable and reconnect it again later the same stream should continue playing.
  • You’re done……Congratulations. Might want to make a image of this microsd card and then run “rpi-update” to update to the latest firmware/kernel. This is sometimes risky hence why I said make a image first.