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

16,663

199

76

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

  • Paper Contest

    Paper Contest
  • Organization Contest

    Organization Contest
  • Warm and Fuzzy Contest

    Warm and Fuzzy Contest

76 Discussions

0
None
JuliusM32

4 weeks ago

This is great, but when you buy the videos, there's a buffer video meant to play on a continuous loop until the sensor is activated. Then it will switch to play one of the 2 videos that come with the download (eyes-on-you or scare/nightmare)... I seems like the script could perform this process, but I'm extremely new to coding and don't know how to do it.
Anyone here capable of writing something similar?

0
None
scifideity

Question 3 months ago

How would I trigger this from an Arduino running Octobanger (buttonbanger.com)? I've got it working fine with the PIR directly connected to the Pi but would like to insert the Arduino in the path so it can handle playing an ambient attract mp3. Then, when the PIR on the Arduino triggers it can let the Pi know to play the video while it handles signals to the relays to control the Monster in a Box lit solenoid, lights, and fog. I've tried hooking it up with the Arduino/Octobanger using Trigger Low out to the Pi on the same pin as the PIR but the video loads up and immediately starts to play and loops.

0
None
stagge99

Tip 3 months ago

If you use USB speakers use '-o', 'alsa:hw:1,0' arguments.
player = OMXPlayer(VIDEO_PATH, args=['-o', 'alsa:hw:1,0', '--no-osd', '--loop', '--win', '0 0 {0} {1}'.format(slength, swidth)])

0
None
DennisBiker48

4 months ago

My scare video takes 12 seconds. If the PIR sensor detects a
motion, sometimes the video don't start at 0. Instead it jumps to the
8th second. So it stucks.

Another thing: It would be great if the video plays just one time. Sometimes the video plays for 3 or 4 times and then stop.

Please can anyone help me?

2 replies
0
None
DennisBiker48DennisBiker48

Reply 4 months ago

Found the error. The PIR sensor HC-SR501 was buggy. With a new sensor everything is good. Thanks again for your great job

0
None
stagge99kommy72

Reply 6 months ago

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

0
None
scarethetotskommy72

Reply 1 year ago

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.

0
None
stagge99

6 months ago

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.

0
None
MartyP24

9 months ago

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
0
None
MartyP24MartyP24

Reply 9 months ago

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?

0
None
scarethetotsMartyP24

Reply 7 months ago

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

0
None
Widiver

7 months ago

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
0
None
scarethetotsWidiver

Reply 7 months ago

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

0
None
scarethetotsJayC147

Reply 1 year ago

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

0
None
raymitchell1

1 year ago

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
0
None
scarethetotsraymitchell1

Reply 1 year ago

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

0
None
raymitchell1

1 year ago

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.