I have a webcam connected to my server, and I want to use it to offer a stream I can access using my phone, and also to perform some time-lapse capturing as well as motion detection when I’m not at home with email notification.
Previously I had tried zoneminder, but I didn’t really like the approach. This time I’m using a great package just called “motion.” I didn’t think it would be full-featured, but it is great. Installation is simple:
sudo apt-get install motion
Then I edited the /etc/default/motion, setting start_motion_daemon=yes.
The last setup file to edit is /etc/motion/motion.conf. It is very well documented and has so many options. Here are some of the tweaks I made:
v4l2_palette 2 #mjpeg palette width 1280 #capture resolution height 720 #capture resolution text_double on #easier to read time/date snapshot interval 4 target_dir /tmp/motion #stores snapshots/motion videos in RAM using tmp dir snapshot_filename timelapse/%Y%m%d_%H%M%S #subdirectory for snapshots webcam_port 39820 #changed to random port
This gave a webcam stream visible using a web browser, and captures a snapshot every 4 seconds for time-lapse. This is all stored in the tmp RAM disk in order to not be constantly writing to the hard drives more than needed. So that I don’t lose the snapshots upon reboot, I use the following file in /etc/init.d/transientmotion based on my /var/log RAM disk script of /etc/init.d/transientlog.
#!/bin/sh
### BEGIN INIT INFO
# Provides: transientmotion
# X-Start-Before: motion
# X-Stop-After: motion
# X-Interactive: yes
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Keeps RAM timelapse photos between reboots
# Description: Moves the contents of /tmp/motion/ to disk upon
# shutdown/reboot, and restores upon startup.
### END INIT INFO
# Version 1.0
#
# Inspired by transientlog.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=transientmotion
DESC="Transient motion directory"
LOCKFILE=/var/lock/$NAME.lock
VARLOG=/tmp/motion/timelapse
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
if [ -z "$VARLOGPERM" ]; then
var=/var
log=`basename $VARLOG`
VARLOGPERM="$var/permanent$log"
unset var log
fi
do_start()
{
# Return
# 0 if transient motion has been started
# 1 if transient motion was already running
# 2 if transient motion could not be started
[ -f $LOCKFILE ] && return 1
# Check if I'm root
[ `id -u` -eq 0 ] || return 2
# If VARLOG does not exist?
[ -d $VARLOG ] || return 2
# VARLOGPERM either does not exist (first invocation)
# or is empty (left from previous invocation).
#
[ -d $VARLOGPERM ] || mkdir -p $VARLOGPERM || return 2
[ -d $VARLOG ] || mkdir -p $VARLOG || return 2
# Mount a tmpfs over VARLOG.
# The mount will shadow the current contents of VARLOG.
# So, before, make a bind mount so that looking into VARLOGPERM
# we'll see the current contents of VARLOG, which
# will not be available anymore as soon as we mount
# a tmpfs over it.
#
if [ $? -eq 0 ]; then
# Populate the tmpfs
if cp -rfp $VARLOGPERM -T $VARLOG; then
# Success!
rm $VARLOGPERM/*
touch $LOCKFILE
return 0
fi
# Something went wrong...
# Rollback the mount
fi
# Rollback the directory mangling
return 2
}
do_stop() {
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
#[ -f $LOCKFILE ] || return 1
# Check if I am root
[ `id -u` -eq 0 ] || return 2
# Merge back to permanent storage
cp -rfup $VARLOG -T $VARLOGPERM
# The following cannot fail... or can it?
rm -f $LOCKFILE
return 0
}
do_reload() {
# Return
# 0 if transient log has been reloaded
# 1 if transient log was not running
# 2 if transient log could not be reloaded
#[ -f $LOCKFILE ] || return 1
# Check if I am root
[ `id -u` -eq 0 ] || return 2
# Merge back to permanent storage
cp -rfup $VARLOG -T $VARLOGPERM
touch $LOCKFILE
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
if [ -f $LOCKFILE ]; then
echo "$DESC is running"
else
echo "$DESC is stopped"
exit 1
fi
;;
reload)
log_daemon_msg "Reloading $DESC" "$NAME"
do_reload
log_end_msg $?
;;
*)
echo "Usage: $0 {start|stop|status|reload}" >&2
exit 3
;;
esac
Then I checked the start up priority of motion
sudo find /etc/rc*.d -iname ???motion /etc/rc0.d/K60motion /etc/rc1.d/K60motion /etc/rc2.d/S60motion /etc/rc3.d/S60motion /etc/rc4.d/S60motion /etc/rc5.d/S60motion /etc/rc6.d/K60motion
I set my new script to 1 lower (using a higher number) than it, so that it will start and stop after.
sudo update-rc.d transientmotion defaults 61
Additionally, I want to transcode my snapshots into x264 mp4 video on a schedule. The following script does that, making the video and then deleting the snapshots upon finishing. I set this to cron at 11pm and 6am (the hours between 11pm and 6am are usually just darkness).
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
DATER=`date +%Y-%m-%d_%H%M%S`
FOLDERIN="/tmp/motion/timelapse"
FOLDERTMP="/tmp/motiontmp"
FOLDEROUT="/datapool/Videos/timelapse"
mkdir $FOLDERTMP
mv $FOLDERIN/*.jpg $FOLDERTMP/
mencoder "mf://$FOLDERTMP/*.jpg" -fps 60 -ofps 60 -of lavf -ovc x264 -x264encopts preset=veryslow:crf=24:threads=auto -o $FOLDEROUT/$DATER.mp4
RC=$?
if [ "${RC}" -ne "0" ]; then
# Handle the error.
echo "error"
else
# Everything was ok.
echo "no error"
rm -r $FOLDERTMP
fi
This stores the resulting file outside of the /tmp, archiving it.
I’ll add information about turning on/off motion detection and emailing images/movies at some point, but not now.
Leave a Reply