Skip to content

Commit

Permalink
added video streaming and streaming documentation
Browse files Browse the repository at this point in the history
the elusive VLC plus RPi.GPIO working together for button-controlled
streaming
  • Loading branch information
Alex Eames committed Aug 2, 2013
1 parent e8e6d4f commit 86fad39
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 15 deletions.
75 changes: 60 additions & 15 deletions ReadMe.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
This Readme will contain some basic info about the RasPiCamcorder 2
This Readme contains basic info about the RasPiCamcorder 2
by Alex Eames of RasPi.TV

But I haven't written it all yet, so, for the time being, you can pop over
to the http://RasPi.TV blog or YouTube and see some info about the project
there...
Basically there are three major parts...

Video recording [sudo python picamcorder2.py]
Stills capture (plus DropBox upload) [sudo python picamstills-db.py]
Video streaming [python picamstreamer.py]

These are currently three separate programs. See below for details.

Photos and further info on the http://RasPi.TV blog or YouTube...

http://raspi.tv/?p=3424
and
Expand Down Expand Up @@ -36,7 +43,10 @@ disable_camera_led=1

Usage
=====
To run the program manually, you can type

Video
-----
To run the video program manually, you can type

sudo python picamcorder2.py

Expand All @@ -45,6 +55,37 @@ Add a 0 (zero) if you want to disable the front LED

sudo python picamcorder2.py 0

Stills
------
To run the stills program manually, you can type

sudo python picamstills-db.py
or
sudo python picamstills-db.py 0 (if you want to disable the front LED)

Video Streaming
---------------
This uses two scripts to separate the GPIO and non-GPIO parts since
VLC can't run as root, but RPi.GPIO has to run as root.

To start the video streaming program (it works just as the recording program
except it streams to port 8090 rather than recording) just type...

python picamstreamer.py
or
python picamstreamer.py 0 (if you want to disable the front LED)

This program handles the streaming part, but the GPIO part is handled by
picamstream-sudo.py (which is called by picamstreamer.py).

Then, on your receiving device, you need to have VLC running and looking at
a network stream from...

http://ip_address_of_your_pi:8090

Further instructions about VLC streaming here
http://raspi.tv/?p=3099


Setting up your Pi
==================
Expand All @@ -66,8 +107,11 @@ The bash script picamcorder.sh just contains this...
sleep 10
sudo python /home/pi/picamcorder2.py &

...which slows things down enough to make it work and puts the process in the
background.
...which slows things down at startup, just enough to make it work and puts
the process in the background.

If you prefer to auto-start-up the stills or streaming programs instead of
video, just edit picamcorder.sh to call the program you want to run.


Setting up for small screen use
Expand All @@ -78,16 +122,16 @@ sudo dpkg-reconfigure console-setup
lets you increase console font size for small screens


Setting Up Dropbox upload for Stills mode
Setting Up Dropbox Upload for Stills mode
-----------------------------------------
Not written instructions yet, but you can find it all here if you want to
go through it yourself.
Blog article here http://raspi.tv/?p=3572 shows full instructions on how to
set up DropBox Uploader on your Pi and basic usage.

Full documentation at the author's GitHub
https://github.com/andreafabrizi/Dropbox-Uploader

It's not that hard. Only took me about 2 hours to
do the dropbox integration (including coding). To set up as a user, should
only take an hour or so.
To set up as a user, should only take an hour or so. A lot less if you already
have a DropBox account.


########################Possible Future Development#############
Expand All @@ -105,12 +149,13 @@ only take an hour or so.
# possibly a rotating base for all-round work - either stepper or highly geared

######### it would be nice to have a third button for stills too
######### getting errors after adding port 25 for stills
######### but getting errors after adding port 25 for stills

## All parts referring to GPIO25 are commented out for now

# it seems that raspivid and raspistill don't play nicely together in the
# same script, so had to remove the stills option for now
# same script, so had to remove the stills option from the video script
# and implement it separately

#def take_photo():
# call (["raspistill -t 3000 -o test-pic.jpg"], shell=True)
Expand Down
118 changes: 118 additions & 0 deletions picamstream-sudo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env python2.7
# script by Alex Eames http://RasPi.tv
import RPi.GPIO as GPIO
import sys
import time
from time import sleep

front_led_status = sys.argv[-1]
if front_led_status == "0":
print "front LED off"
front_led_status = 0

streaming_on = 0
streaming_file = "/home/pi/streaming.txt"
time_off = 0

GPIO.setmode(GPIO.BCM)

# GPIO 23 set up as input, pulled up to avoid false detection.
# wired to connect to GND on button press.
# So we'll be setting up falling edge detection
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# GPIO 24 set up as an input, pulled down, connected to 3V3 on button press
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# Set up GPIO 5 for camera LED control and rear LED control
GPIO.setup(5, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)

def write_streaming_status(streaming_on):
vrnw = open(streaming_file, 'w')
vrnw.write(str(streaming_on))
vrnw.close()

def check_streaming_status():
# read file streaming_file, make into int() set streaming_on equal to it
vrn = open(streaming_file, 'r')
streaming_on = int(vrn.readline())
#print "streaming_on is %d" % streaming_on
vrn.close()
return streaming_on

# threaded callback function runs in another thread when event is detected
# this increments variable rec_num for filename and starts recording
def stream_button(channel):
global time_off
time_now = time.time()
if (time_now - time_off) >= 0.3:
streaming_status = check_streaming_status()
if streaming_status == 0:
write_streaming_status(1)
print "stream button pressed"
if front_led_status != 0:
GPIO.output(5, 1)
GPIO.output(22, 1)
time_off = time.time()

def flash(interval,reps):
for i in range(reps):
GPIO.output(5, 1)
GPIO.output(22, 1)
sleep(interval)
GPIO.output(5, 0)
GPIO.output(22, 0)
sleep(interval)

try:
write_streaming_status(0)
except:
print "couldn't write streaming status"
sys.exit()

# when a falling edge is detected on blue stream button port 23 stream_button() will be run
GPIO.add_event_detect(23, GPIO.FALLING, callback=stream_button)

try:
while True:
# this will run until black button attached to 24 is pressed, then
# if pressed long, shut program, if pressed very long shutdown Pi
# stop recording and shutdown gracefully
print "Waiting for button press" # rising edge on port 24"
GPIO.wait_for_edge(24, GPIO.RISING)
#print "Stop button pressed"

time_now = time.time()
if (time_now - time_off) >= 0.3:
streaming_status = check_streaming_status()
if streaming_status == 1:
write_streaming_status(0)
print "Stop button pressed"
GPIO.output(5, 0)
GPIO.output(22, 0)
time_off = time.time()

# poll GPIO 24 button at 20 Hz continuously for 2 seconds
# if at the end of that time button is still pressed, shut down
# if it's released at all, break
for i in range(60):
if not GPIO.input(24):
break
sleep(0.05)

if 25 <= i < 58:
print "Closing program"
flash(0.02,50) # interval,reps
write_streaming_status(2) # 2 will close the host program
GPIO.cleanup()
sys.exit()

if GPIO.input(24):
if i >= 59:
shutdown()

except KeyboardInterrupt:
stop_recording()
GPIO.cleanup() # clean up GPIO on CTRL+C exit
GPIO.cleanup() # clean up GPIO on normal exit
77 changes: 77 additions & 0 deletions picamstreamer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env python2.7
# script by Alex Eames http://RasPi.tv

from subprocess import call
import sys
import time

front_led_status = sys.argv[-1]
if front_led_status == "0":
print "front LED off"
front_led_status = 0

streaming_on = 0
streaming_file = "/home/pi/streaming.txt"
if front_led_status == 0:
sudo_file = "sudo python /home/pi/picamstream-sudo.py 0 &"
else:
sudo_file = "sudo python /home/pi/picamstream-sudo.py &"

stream = "raspivid -o - -t 9999999 -w 640 -h 360 -fps 25|cvlc stream:///dev/stdin --sout '#standard{access=http,mux=ts,dst=:8090}' :demux=h264 &"

# you can change -w and -h numbers for whatever suits your network.
# Depending on what I'm streaming to, mine can cope with 720p,
# which is -w 1280 -h 720

def stream_video():
print "starting streaming\n%s" % stream
call ([stream], shell=True)

def stop_stream():
print "stopping streaming"
call (["pkill raspivid"], shell=True)
call (["pkill cvlc"], shell=True)

def check_streaming_status():
# read file streaming_file, make into int() set streaming_on equal to it
vrn = open(streaming_file, 'r')
streaming_on = int(vrn.readline())
#print "streaming_on is %d" % streaming_on
vrn.close()
return streaming_on

def write_streaming_status(streaming_on):
vrnw = open(streaming_file, 'w')
vrnw.write(str(streaming_on))
vrnw.close()

try:
write_streaming_status(0)
except:
print "couldn't write streaming status"
sys.exit()

call ([sudo_file], shell=True)

previous_streaming_on = 0
counter = 0

#have a file containing the streaming_on variable value
while True:
streaming_on = check_streaming_status()
#print "streaming status = %d" % streaming_on

if streaming_on != previous_streaming_on:
if streaming_on == 1:
stream_video()
elif streaming_on == 0:
stop_stream()
else:
stop_stream()
print "Closing picamstreamer.py"
sys.exit()
if counter % 50 == 0:
print "streaming status = %d" % streaming_on
previous_streaming_on = streaming_on
counter += 1
time.sleep(0.1)

0 comments on commit 86fad39

Please sign in to comment.