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