Porthole

I want to make a porthole that shows different videos depending on which button you press…

Videos

So far my ideas for the views are:

Aquarium
https://www.youtube.com/watch?v=zJ7hUvU-d2Q

Space Travel
https://www.youtube.com/watch?v=XeUP83wRhjQ
https://www.youtube.com/watch?v=nGnX6GkrOgk
https://www.youtube.com/watch?v=bZNFRIwlQxQ
https://www.youtube.com/watch?v=NtOwzU5Rpp8 (Short Loop)

Earth Orbit / ISS
https://www.youtube.com/watch?v=Xjs6fnpPWy4

Polar / Winter Landscape
https://www.youtube.com/watch?v=9NmeAQruCgs
https://www.youtube.com/watch?v=fIrfF08azwc

Desert Landscape
https://www.youtube.com/watch?v=fvRkWO5g2HE
https://www.youtube.com/watch?v=1mexsOOHBSA (Short Loop)

Nature FlyBy
https://www.youtube.com/watch?v=BHACKCNDMW8

SciFi City
https://www.youtube.com/watch?v=Uj8DYegtrHg

Autumn
https://www.youtube.com/watch?v=oOhMGdFbYvU (Short Loop)
https://www.youtube.com/watch?v=eGD-5jYR9jk (Short Loop)

Sunset
https://www.youtube.com/watch?v=A9cHouJRGsU (Short Loop)

Clouds
https://www.youtube.com/watch?v=0_jNjpVxUt0 (Short Loop)
https://www.youtube.com/watch?v=rwfqnsK2M_s (Short Loop)

Components

I have some old spare TV screens, I have a Pi that I’m not currently using (so-long PiBot) and I’ve tracked down some instructions that could be good….

https://www.instructables.com/id/Play-Video-With-Python-and-GPIO/
https://www.raspberrypi.org/forums/viewtopic.php?t=101359

I like the first set of instructions but need to rejig them slightly so that its a momentary button press that triggers them or a rotary switch(?).

The thing that I am definitely missing is a porthole

Build Process

So it looks as thought the loop videos are going to work best, I’ve noted which are which above but I’ll have more of a play and find out whats happening. Now I just need to find some momentary switches…. to AliExpress!

Code so Far

This gives me 5 video buttons and an exit button. Currently you have to manually launch the code from a terminal window and the exit button only returns you to the Pi desktop.

#import the needed libraries
import os
import sys
import time
import subprocess
import RPi.GPIO as GPIO

#Set GPIO pin format
GPIO.setmode(GPIO.BCM)

#Setup the GPIO buttons
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) #YELLOW
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP) #RED
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP) #WHITE
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP) #BLUE
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP) #GREEN
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) #BLACK

#VARIABLES
movie1 = ("/home/pi/Videos/Loop_Videos/Space_u9TuAZHeziw_240p.mp4")
movie2 = ("/home/pi/Videos/Loop_Videos/Clouds_0_jNjpVxUt0_240p.mp4")
movie3 = ("/home/pi/Videos/Loop_Videos/Fish_A2WqvBVCUJQ_360p.mp4")
movie4 = ("/home/pi/Videos/Loop_Videos/Desert_1mexsOOHBSA_240p.mp4")
movie5 = ("/home/pi/Videos/Loop_Videos/Sunset_A9cHouJRGsU_240p.mp4")
Layer = 1 #this needs to be presented as a string not a variable
OMX1 = '' #Define them early so we can try and kill them even if they aren't running
OMX1_active = False
OMX2 = '' #Define them early so we can try and kill them even if they aren't running
OMX2_active = False
OMX3 = '' #Define them early so we can try and kill them even if they aren't running
OMX3_active = False
OMX4 = '' #Define them early so we can try and kill them even if they aren't running
OMX4_active = False
OMX5 = '' #Define them early so we can try and kill them even if they aren't running
OMX5_active = False

#and off we go...
os.system('killall omxplayer.bin') #kill OMX in case it is already running
#Space = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie2],stdin=subprocess.PIPE) #Load the 1st video
OMX1_active = True
OMX1 = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie1],stdin=subprocess.PIPE) #Load the 1st video
        
while True:
    #Read states of the inputs
    button1 = GPIO.input(17) #Yellow
    button2 = GPIO.input(18) #Red
    button3 = GPIO.input(27) #Blue
    button4 = GPIO.input(22) #Green
    button5 = GPIO.input(23) #Black
    quit_video = GPIO.input(24) #White

    #If GPIO(17) is shorted to ground
    if button1 == False: #If button1 is pressed...
        if OMX1_active == False: #And movie1 is not already running
            #Play movie1
            Layer = Layer + 1
            OMX1_active = True
            OMX1 = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie1],stdin=subprocess.PIPE) #Load the 1st video
            time.sleep(5)
            if OMX2_active == True: #shutdown movie2 if it is playing
                OMX2.stdin.write('q')
                OMX2.stdin.flush()
                OMX2_active = False
            if OMX3_active == True: #shutdown movie3 if it is playing
                OMX3.stdin.write('q')
                OMX3.stdin.flush()
                OMX3_active = False
            if OMX4_active == True: #shutdown movie4 if it is playing
                OMX4.stdin.write('q')
                OMX4.stdin.flush()
                OMX4_active = False
            if OMX5_active == True: #shutdown movie4 if it is playing
                OMX5.stdin.write('q')
                OMX5.stdin.flush()
                OMX5_active = False

    elif button2 == False: #ElseIf button2 is pressed...
        if OMX2_active == False: #And movie1 is not already running
            #Play movie2
            Layer = Layer + 1
            OMX2_active = True
            OMX2 = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie2],stdin=subprocess.PIPE) #Load the 1st video
            time.sleep(5)
            if OMX1_active == True: #shutdown movie1 if it is playing
                OMX1.stdin.write('q')
                OMX1.stdin.flush()
                OMX1_active = False
            if OMX3_active == True: #shutdown movie3 if it is playing
                OMX3.stdin.write('q')
                OMX3.stdin.flush()
                OMX3_active = False
            if OMX4_active == True: #shutdown movie4 if it is playing
                OMX4.stdin.write('q')
                OMX4.stdin.flush()
                OMX4_active = False
            if OMX5_active == True: #shutdown movie4 if it is playing
                OMX5.stdin.write('q')
                OMX5.stdin.flush()
                OMX5_active = False
                
    elif button3 == False: #ElseIf button2 is pressed...
        if OMX3_active == False: #And movie1 is not already running
            #Play movie2
            Layer = Layer + 1
            OMX3_active = True
            OMX3 = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie3],stdin=subprocess.PIPE) #Load the 1st video
            time.sleep(5)
            if OMX1_active == True: #shutdown movie1 if it is playing
                OMX1.stdin.write('q')
                OMX1.stdin.flush()
                OMX1_active = False
            if OMX2_active == True: #shutdown movie3 if it is playing
                OMX2.stdin.write('q')
                OMX2.stdin.flush()
                OMX2_active = False
            if OMX4_active == True: #shutdown movie4 if it is playing
                OMX4.stdin.write('q')
                OMX4.stdin.flush()
                OMX4_active = False
            if OMX5_active == True: #shutdown movie4 if it is playing
                OMX5.stdin.write('q')
                OMX5.stdin.flush()
                OMX5_active = False
                
    elif button4 == False: #ElseIf button2 is pressed...
        if OMX4_active == False: #And movie1 is not already running
            #Play movie2
            Layer = Layer + 1
            OMX4_active = True
            OMX4 = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie4],stdin=subprocess.PIPE) #Load the 1st video
            time.sleep(5)
            if OMX1_active == True: #shutdown movie1 if it is playing
                OMX1.stdin.write('q')
                OMX1.stdin.flush()
                OMX1_active = False
            if OMX2_active == True: #shutdown movie3 if it is playing
                OMX2.stdin.write('q')
                OMX2.stdin.flush()
                OMX2_active = False
            if OMX3_active == True: #shutdown movie4 if it is playing
                OMX3.stdin.write('q')
                OMX3.stdin.flush()
                OMX3_active = False
            if OMX5_active == True: #shutdown movie4 if it is playing
                OMX5.stdin.write('q')
                OMX5.stdin.flush()
                OMX5_active = False
                
    elif button5 == False: #ElseIf button2 is pressed...
        if OMX5_active == False: #And movie1 is not already running
            #Play movie2
            Layer = Layer + 1
            OMX5_active = True
            OMX5 = subprocess.Popen(['omxplayer', '--loop', '--win', '600,100,900,400', '--layer', str(Layer), movie5],stdin=subprocess.PIPE) #Load the 1st video
            time.sleep(5)
            if OMX1_active == True: #shutdown movie1 if it is playing
                OMX1.stdin.write('q')
                OMX1.stdin.flush()
                OMX1_active = False
            if OMX2_active == True: #shutdown movie4 if it is playing
                OMX2.stdin.write('q')
                OMX2.stdin.flush()
                OMX2_active = False
            if OMX3_active == True: #shutdown movie3 if it is playing
                OMX3.stdin.write('q')
                OMX3.stdin.flush()
                OMX3_active = False
            if OMX4_active == True: #shutdown movie4 if it is playing
                OMX4.stdin.write('q')
                OMX4.stdin.flush()
                OMX4_active = False
                
    #If GPIO(24) is shorted to ground
    if quit_video == False:
        os.system('killall omxplayer.bin')
        exit()

Code Improvements…

  • The script should fire up as the Pi loads up
  • The exit button should be a hidden button for troubleshooting
  • There should be a flag to set if the videos are full screen or window for debugging
  • There is a lot of repetitive code that could be written out especially if this can go up to 20 videos!
  • There should be a shutdown button that closes the videos and shuts down the Pi
  • The last one is a big one……. should this be a flight between destinations? As in should pressing a button play a take-off video / space video / landing video? At the moment it just loads whichever loop you select with no transition.

Draft Hardware

First I’ve soldered jumper cables and heat-shrink onto the switches. The cables are colour coded to make it easier to work out which is which when I’m looking at the other side.

Then I quickly knocked up a draft box to hold the switches while I’m doing my prototyping. I’ve made it over large so I can add additional switches.

Here’s the first draft. I should have thought this through more as it doesn’t quite fit the Pi in there as well! Oh well its only a draft and there will be a shiney box coming soon anyway.

Hardware Improvements

  • Larger slimmer case, probably based on the skeleton of a rack mount network switch (I work in IT, they are free for me!)
  • More switches
  • More lights
  • Add the Pi into the case
  • Add the unused ports as external ports to the box (power, 2x USB, Network, Audio, HDMI)

1st Round of Improvements

Now all my shiny switches are mounted in an old piece of networking hardware that was broken. I work in IT so stuff like this is easy to obtain for free but check out my scrounging post if you want some ideas on getting free stuff!
https://fearpig.icenidesign.com/scrounging-and-on-the-cheap/

The twelve switches down the left-hand side don’t currently do anything but my idea is to have them control audio clips (robots and dinosaurs is the boys request!)

The holes for the switches were all cut using a stepped drill bit which is awesome!

They are fairly cheap and definitely worth the investment.

I bought a stand-off kit from ebay to mount various electronics to the inside of the box! This project is starting to look expensive but I’ve pretty much got enough parts to build 10 of them! The kit that I bought is no longer available but if you google “standoff kit” there are loads out there.

One problem I have is that I’m mounting the hardware to the bottom of the case and the switches to the top of the case. So I’ve decided to link the top of the case to the bottom of the case with a few 9-pin serial cables. i decided on 9-pin as that is a standard more likely to be of use in the future, its cheap and I can run multiple cables when needed. I could have gone for 25 pin but they are really bulky.

I’ll probably end up mounting 3 or 4 of these on the top of the case and 3 or 4 on the bottom of the case. They are really cheap!
https://www.aliexpress.com/item/32838512514.html?spm=a2g0s.9042311.0.0.4d734c4dx3t83z