Living Portrait Scare for Halloween Using a Raspberry Pi, PIR and Python

15,440

196

70

Introduction: Living Portrait Scare for Halloween Using a Raspberry Pi, PIR and Python

Lets make a living portrait effect for Halloween, and scare some people.The goal is to have the portrait remain still until the motion sensor is triggered and to do this without a blank space between videos, the scare or the reset of the image. Many of the triggerable media players aren’t seamless and for those that are its quite expensive.The cheaper ones results in a black screen in between scares or even between scenes, which totally ruin the effect.Here we will use a raspberry pi and python3, and by the end of this you too can have a wonderful Halloween prop, and scare anyone that comes close.

Parts needed:

  • Raspberry pi 2|3: $35.00
  • 5v PIR (Passive InfraRed) sensor: $5.00
  • I got mine from amazon for around 8.00 (now 11.00) but it comes with 5 from Amazon
  • Unliving portrait video: $8.00 AtmosFX
  • TV|Monitor: you have this laying around
  • Wood or old frame to cover monitor


Software Needed:

  • Python: pre-installed on Raspbian
  • Omxplayer: pre-installed on Raspbian
  • Omxplayer-wrapper library

Step 1: Software and Connections

I’m not going to go into how to setup a pi, there are plenty of documents around that, but if you need it here is the documentation on how to install Raspbian. I recommend using SSH and setting up wifi to make it easy to test and start the script. How to setup SSH on windows and Raspbian here.

Now we need to install Omxplayer-wrapper and grab a script from my github.

Open a terminal in Raspbian and enter

  • sudo python3 -m pip install omxplayer-wrapper
    • this should install all the requirements and should be all you need to set it up
  • Grab my portrait player script from My github page or attached to this instructable.
  • Copy your living portrait video to the pi somewhere.
  • Once this is done, omxplayer-wrapper is installed, and all the files are ready turn off the pi and continue on.
  • To set up the PIR to work with the PI you need to connect the Sensor.
    • PIR VCC to 5v(pin2)
    • PIR Out to GPIO4(pin7)
    • PIR GND to GND(pin6).


Your PIR might be different in layout please ensure its correct. Also turn all the potentiometers counter clockwise which should be all the way down, you can adjust sensitivity later if needed. If you need a narrow field of view from the sensor I recommend removing the plastic cover from the PIR.

Step 2: Testing

With this hooked up start up the pi and navigate to the folder where the living_portrait.py script is, depending on your settings you may need to adjust the screen width or screen height. In the living_portrait.py script change the swidth and slength variables to match your monitor. Mine was 1440x900.

To start the effect run:

  • python3 living_portrait.py filename
  • for example:
    • python3 living_portrait.py UP_Gent_LivingNightmare_TV_V.mp4

It is important to note that what happens in this effect is the player starts the video and then pauses it immediately before the scare happens. Make sure you pick a video that when un-paused it will produce the effect you want.

Lastly, we need to frame our monitor, you can either use an old frame that fits or you can make your own for pretty cheap. Buy some molding from Home Depot cut it on 45-degree angles and either nail or staple it together. I also mounted to L-brackets to my frame so I can hang it on the monitor. For a final touch I drilled a hole for the PIR sensor, but this isn't necessary and sometimes takes some trial and error to make the trigger work to ones desire.

Step 3: The Result

Simple and great effect. Check out the video and go scare someone! if you liked this please vote for me in the halloween contest.

3 People Made This Project!

Recommendations

  • Furniture Contest 2018

    Furniture Contest 2018
  • Metalworking Contest

    Metalworking Contest
  • Fix It! Contest

    Fix It! Contest

70 Discussions

It's possible to play more video or just one?

2 replies

Something like this. quick and dirty :)


#!/usr/bin/env python3

#Created by scarethetots

from gpiozero import MotionSensor

import sys

from omxplayer.player import OMXPlayer

from pathlib import Path

from time import sleep

files = sys.argv[1]

slength = '1920'

swidth = '1200'

print("Starting up....")

tgr = 0

try:

player = OMXPlayer('Downloads/famal.mp4', args=['--no-osd', '--loop', '--win', '0 0 {0} {1}'.format(slength, swidth)])

pir = MotionSensor(4)

sleep(1)

print("Ready to trigger")

while True:

player.pause()

if pir.motion_detected and tgr == 2:

player.quit()

player = OMXPlayer(Path('Downloads/man.mp4'), args=['--no-osd', '--loop', '--win', '0 0 {0} {1}'.format(slength, swidth)])

player.play()

player.play()

print("New video count {}".format(tgr))

sleep(player.duration())

tgr = tgr + 1

elif pir.motion_detected and tgr == 4:

player.quit()

player = OMXPlayer(Path('Downloads/girl1.mp4'), args=['--no-osd', '--loop', '--win', '0 0 {0} {1}'.format(slength, swidth)])

player.play()

player.play()

print("New video count {}".format(tgr))

sleep(player.duration())

tgr = tgr + 1

elif pir.motion_detected and tgr == 6:

player.quit()

player = OMXPlayer(Path('Downloads/girl1.mp4'), args=['--no-osd', '--loop', '--win', '0 0 {0} {1}'.format(slength, swidth)])

player.play()

player.play()

print("New video count {}".format(tgr))

sleep(player.duration())

tgr = 1

elif pir.motion_detected:

print("trigger count {}".format(tgr))

player.play()

sleep(player.duration())

tgr = tgr + 1

else:

pass

player.set_position(0.0)

except KeyboardInterrupt:

player.quit()

sys.exit()

master.withdraw() # if you want to bring it back

sys.exit() # if you want to exit the entire thing

Yes, however that would require the script to be altered. I thought about having it change videos every 10 plays or so. soit would be different if you change every scare you might have the black screen when it switches. I'll look into it though.

Nice projekt, works fine :)

How do you get the video to start automatically when you turn on the Raspberry Pi, are there autostart like in windows.

Newbie and receiving input error no module named omxplayer

I can run manually from omxplayer from command line so I know that works and video plays. Just not sure why failing with script.

2 replies

Figured it out from other posts. Thx. Great project.

I want this to trigger multiple times. Is there anything special I’d need to do so it will just keep going off when motion is detected?

glad to see you got it. mine triggers multiple times. I am not sure why yours would trigger just once

Great Instructable. I found this last year and finally had time to get it ready for this Halloween. I am a total newbie at this but your directions were clear and easy to follow. I just need to frame out the monitor. I would love it if it could play multiple clips, maybe run one video for a certain number of triggers and then move to the next one, but I wouldn't know where to start. I was just excited to get it running without too much difficulty. Thanks.

1 reply

yes you could, it would involve tweaking the python code a bit, it probably wouldn't be a smooth transition from one video to the next

Will this work using a Raspberry Pi B+?

1 reply

It 'may' there really isn't anything specific to the pi3. but you may run into issues that I haven't seen or predicted.

Import Error: dbus : I found the Solution on a forum when I searched for dbus and python 3 not related to Raspberry Pi, but Ubuntu -- and luckily I didn't need to reinstall:

sudo apt-get update
sudo apt-get install python3-dbus

After those commands, the program is now playing video -- I am very happy. And a BTW for those that want to reset the video, I put a sleep(0.5) between the set position and pause so that the commands have time to be processed.

Happy Halloween! ;-) Thanks again for posting this project!

1 reply

Nice! glad you figured it out and thanks for sharing your solution.

Thanks for posting this project; I need help with using it on a Raspberry Pi Zero W, the error message from apt-get is "E: unable to locate package libdbus-1"; however I was able to install the libdbus-1-dev package and make the wrapper for Python 3. When I run the code I get an ImportError: No module named 'dbus' presumably because the libdbus-1 package didn't install. I followed up with an apt-get update to see if the dependencies would pick up the package -- no luck. Any suggestions? Most appreciated putting together for Halloween this weekend.

3 replies

That's a very curious error. I actually just bought a pi zero w today, to do this on and didn't have any issues. I even came back here to get my pip command. What version of rasbian are you running? how did you install raspbian? When I installed raspbian tonight I used the noobs install, just to make my life easier. I can only assume something went wrong in either the install of the OS, or the sudo python3 -m pip install omxplayer-wrapper command. I'd reinstall raspbian. I think omxplayer-wrapper is importing dbus. but still weird. let me know how it goes.

I'm running version "Jessie" and I ran the update again today so it "should" be up to date... BTW: Which version are you running? I will admit I am new to the Raspberry Pi universe, so this is probably a basic issue that catches newcomers... but if I were to reinstall everything there is no guarantee that it will resolve the issue... and what would change to allow apt-get to find the "libdbus-1" package? Now I did find and install packages "libdbus-1-dev", "libdbus-1-3", and "dbus"... and when I run Python3 I see a trace back starting from my project where I have in my code: "from omxplayer.play import OMXPlayer" then traces to "usr/local/lib/python3.4/dist-packages/omxplayer/ __init__,py" where it traces to "usr/local/lib/python3.4/dist-packages/omxplayer/player.py" (line 18) in module to "from dbus import DBusException, Int64, string. Object path.... ImportError: No module named 'dbus'" of course I've googled this and tried the advice on Stack-Overflow... to no avail. Question: does it appears that the wrapper may not have had all the objects necessary when I issued the command? -- and would uninstalling the wrapper and rebuilding it help? I will try that; any other advice based on the information provided? Thanks.

I think part of the issue is you're running 'jessie' current raspbian is running stretch. That error isn't something I've encountered before. I don't think your wrapper installed wrong. I think the updated omxplayer and omxplayer-wrapper that is pushed with stretch is the issue. I still highly recommend a new install using the default instructions here https://www.raspberrypi.org/downloads/raspbian/. I wouldn't use 'lite' either as it is most likely missing something that is needed. I'm sorry I couldn't be of more help. If I run across this issue in my setup at anytime and find a way to fix it I'll let you know.

Thanks for taking the time to post this. I've been trying to do this projects for weeks and your instructions worked perfectly. One question, if I wanted this to run on boot, how would you go about doing that?

2 replies

theres many ways to do this but one is: make a file called run.sh, inside that file put the command you run manually. for example "python3 living_portrait.py myvideo.mp4" and save it. make the file executable by doing "chmod +x run.sh" then enter "sudo crontab -e" go to the bottom of that file and enter "@reboot /bin/sh /pi/home/run.sh &" then exit out of crontab and reboot and it should work. you can also run it directly from crontab but sometimes arguements trip up crontab. Here is a link that can help if you get lost https://www.raspberrypi-spy.co.uk/2013/07/running-a-python-script-at-boot-using-cron/