SGNLS

^

KnowledgeBase

Raspberry Pi as Webcam Server

11:53:32am, 15th Nov 2014

Note: Much of this is clunky, old and going through improvements. That said, it works, and works 'well'!

Create two files called capture.sh and upload.sh, remembering to mark both as executable;

pi@chloe ~/rdm/picam $ touch capture.sh
pi@chloe ~/rdm/picam $ chmod +x capture.sh

capture.sh
#!/bin/bash

# print hostname
echo $(hostname) > node.pi | \
echo $(date +%H:%M:%S) \/ $(date +%d.%m.%y) > last.pi | \

# disable autofocus 
# uvcdynctrl -d video0 --set='Focus, Auto' 0 | \

# capture image
fswebcam -v -r 640x480 --skip 5 \
--title "$(hostname)" --timestamp "%H:%M:%S (%d-%m-%Y)" \
--jpeg 100 --palette MJPEG \
--top-banner --banner-colour "#121212" --line-colour "#ffffff" \
--font "/usr/share/fonts/truetype/freefont/FreeMono.ttf:9" \
--save $PWD/img/picam.jpg \
--save $PWD/img/arc/picam_$(date +%F_%H:%M:%S).jpg | \
# --scale 320x240 $PWD/img/picam_scale.jpg \

# upload capture
ncftpput -u user -p password ftp.sgnls.net \
/picam.sgnls.net/html/img $PWD/img/picam.jpg | \

# upload node
ncftpput -u user -p password ftp.sgnls.net \
/picam.sgnls.net/html $PWD/node.pi | \

# upload last
ncftpput -u user -p password ftp.sgnls.net \
/picam.sgnls.net/html $PWD/last.pi

--##--

pi@chloe ~/rdm/picam $ touch upload.sh
pi@chloe ~/rdm/picam $ chmod +x upload.sh

upload.sh
#!/bin/bash

# upload captures (differential)
HOST="ftp.sgnls.net"
USER="user"
PASS="password"
FURL="ftp://$USER:$PASS@$HOST"
LCD="/home/pi/rdm/picam"
# LCD="$PWD"
RCD="/picam.sgnls.net/html"
#DELETE="--delete"

lftp -c "set ftp:list-options -a;
open '$FURL';
lcd $LCD;
cd $RCD;
mirror -R \
       $DELETE \
       --verbose \
       --exclude-glob *.sh" 

Run the simple script without uploading all the archived images; this is much quicker and will result in a more seamless stream (i.e. ./picam.sh). Additionally, for better flexibility with the uploads, run a third script (i.e. ./picam_full.sh);

picam.sh
#!/bin/bash

while true
do
	sh /home/pi/rdm/picam/capture.sh
	sleep 5
done

picam_full.sh
#!/bin/bash

while true
do
	sh /home/pi/rdm/picam/capture.sh
	sleep 5
	sh /home/pi/rdm/picam/upload.sh
	sleep 10
done

Call it all with PHP;

‹!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"›

‹html xmlns="http://www.w3.org/1999/xhtml"›
‹head›

	‹title›piCam - Live Capture‹/title›
	‹link rel="stylesheet" type="text/css" href="css/screen.css" media="screen" /›
	‹meta http-equiv="refresh" content="15" /›

‹/head›

‹body›

‹div id="mf"›
	‹div id="wf"›
	‹?php

	if(!isset($_GET)){$_GET = &$HTTP_GET_VARS;}
	if(!isset($_POST)){$_POST = &$HTTP_POST_VARS;}
	if(isset($_GET)){extract($_GET);}
	if(isset($_POST)){extract($_POST);}

	# get contents of node / last files
		$file_node = file_get_contents('node.pi', true);
		$file_last = file_get_contents('last.pi', true);


	# get updated time / date (hour:min / day.month), stripping year
		$comp_exp = explode(" / ",$file_last,2);
		$comp_time = $comp_exp[0];
			$comp_time_exp = explode(":",$comp_time,3);
				$comp_time_hour = $comp_time_exp[0];
				$comp_time_min = $comp_time_exp[1];

		$comp_date = $comp_exp[1];
			$comp_date_exp = explode(".",$comp_date,3);
				$comp_date_day = $comp_date_exp[0];
				$comp_date_mon = $comp_date_exp[1];


	# get actual time / date (hour:min / day.month)
		$time = date('H:i:s');
			$time_exp = explode(":",$time,3);
				$time_hour = $time_exp[0];
					# cater for GMT source vs BST server time
					# needs further adjustment for when BST = 23
					$time_hour_uk = $time_hour + 8;

					# 24 hour
					if($time_hour › 23){
						$time_hour_uk = "00";
					}
		
				$time_min = $time_exp[1];

				# allowance threshold (cater for upload)
					$time_min_l = $time_min - 2;
				# time shouldn't be 'ahead', but just in case...
					$time_min_g = $time_min + 2;

		$date = date('d.m.y');
			$date_exp = explode(".",$date,3);
				$date_day = $date_exp[0];
				$date_mon = $date_exp[1];

					$date_day_l = $date_day - 1;
					$date_day_g = $date_day + 1;

	## print basic debug
	if(isset($debug)){
	 echo "COMP_TIME_HOUR : $comp_time_hour ‹br /›";
	 echo "COMP_TIME_MIN : $comp_time_min ‹br /›";
	 echo "COMP_DATE_DAY : $comp_date_day ‹br /›";
	 echo "COMP_DATE_MON : $comp_date_mon ‹br /›‹br /›";
	 echo "TIME_HOUR : $time_hour_uk ‹br /›";
	 echo "TIME_MIN : $time_min ‹br /›";
	 echo "TIME_MIN_G : $time_min_g ‹br /›‹br /›";
	 echo "DATE_DAY : $date_day ‹br /›";
	 echo "DATE_MON : $date_mon ‹br /›";
	}

	# checking 'status'; considered using last file access time, but
	# this is not always true; the file may be modded for another reason
	# aim of the below is to compare the last updated hour, minute, day
	# and month (year is assumed to be correct) to the current date
	# (within defined 'allowances' either side for minutes). it is
	# ugly, but allows multiple (matched) if conditions using a 'voting'
	# system to create an expected 'sum'... (** MUST CHANGE THIS! **)

		if($comp_time_hour == $time_hour_uk){
			$vote_a = "1";
		}
		if($comp_time_min == $time_min || $comp_time_min == $time_min_g || $comp_time_min == $time_min_l){
			$vote_b = "1";
		}
		if($comp_date_day == $date_day || $comp_date_day == $date_day_g && $time_hour_uk == "00" || $comp_date_day == $date_day_l && $time_hour_uk == "00"){
			$vote_c = "1";
		}
		if($comp_date_mon == $date_mon){
			$vote_d = "1";
		}
		# if these conditions are NOT met, sum will be different
			else{
				$vote_a = "0";
				$vote_b = "0";
				$vote_c = "0";
				$vote_d = "0";
			}

		# count votes
		$vote = ($vote_a + $vote_b + $vote_c + $vote_d);


		# print status; NULL where file cannot be opened (i.e. uploading)
		if($vote == 4 || $file_last == NULL){
			echo "‹br /› \n‹font color=\"#38ab38\"›‹b›ONLINE‹/b›‹/font›";
		}
		else{
			echo "‹br /› \n‹font color=\"#dd3322\"›‹b›OFFLINE‹/b›‹/font›";
		}

	?›

	‹h3›piCam‹/h3›
	‹p›‹img src="img/picam.jpg"  class="f" /›‹/p›

	‹br /›

	‹h4›‹b›Node : ‹/b› ‹?php echo $file_node ?›‹/h4›
	‹p›‹i›Last Updated : ‹?php echo $file_last ?›‹/i›‹/p›


	‹/div›
‹/div›

‹/body›

‹/html›

Check out my own captures. Obviously, I am uploading this elsewhere but you could easily just run monkey or Apache locally and serve the image(s) without the need for shifting them elsewhere.

© Copyright SGNLS.net 2006-2017

v1.1313 | Material and content adheres to the Creative Commons (NC-SA 4.0) license.