I want to set up a daemon that starts recording video with sound when it detects noise or movement. There are tools that do that separately but can they be done at the same time? Can I set up motion in a way that when it detects motion it executes a script? Can I do the same with SOX?
-
1The motion config options `on-event-start
`, `on-motion-detected – ridgy Mar 26 '17 at 17:02`etc. can be configured to call a script. You may use conversion specifiers to pass information to the command (see `man motion`). -
I basically want to use motion as an event generator. That tells me when there is motion and when there is not and nothing else. Is it possible to do that? – tst Mar 26 '17 at 21:58
1 Answers
I know this is a very old question but I may be able to help someone (like me, few years ago) who stumble across this in a search... I found the above answer from ridgy when I was looking to record and stream audio from Motion and it sent me off to develop a successful solution, for me at least. My use case is recording the sounds from a nestbox. I've got an MS LifeCam webcam on a pan/tilt mount connected to a Pi 3B+ running motion. The solution was indeed to run script when motion was triggered to start recording a movie but I also have a continuously-running script which streams the audio from the webcam. I then use VLC to view the network video stream and play the audio stream alongside it. Details are as follows:
I have three directories set up for handling the audio and video files:
/home/pi/motion/videos, /home/pi/motion/videosB and /home/pi/videos/pre-mergevideos
motion.conf is configured so .mkv videos are saved to /home/pi/motion/videos
On movie start, motion runs a scripts called record_s.sh This records a 60 sec audio file with the same name as the .mkv video and saves it in /home/pi/motion/videos
On movie close, motion runs a script called merge_sv.sh This merges the .mkv and .mp3 files in /home/pi/motion/videos and saves the merged file to /home/pi/motion/pre-mergevideos. The .mkv & .mp3 source files are then deleted, the permissions of the merged file changed to 777 and its owner changed from root to motion and finally, the merged file moved to /home/pi/motion/videosB
crontab runs rsync every 2 minutes to move contents of 'videosB' to NAS share (/home/pi/motion/media)
The latter is to prevent 'motion' crashing if the NAS share becomes unavailable for any reason - 'motion' writes its files to local directories, whilst crontab takes care of the output to the NAS share.
#!/bin/bash
# record_s.sh
# 15/4/18: Created
# 25/11/20: libav-tools no longer available in 'Buster', 'avconv' replaced by 'ffmpeg'
filename="$1"
echo "$1" &> /home/pi/motion/filename.txt # filename.txt will contain /home/pi/motion/videos/xxxxxxxxxxxxxx.mkv
#remove ".mkv" file extension - "${filename%.*} (parameter expansion)
#Use of 'sudo' is only possible if user motion is in the sudoers file and in the sudo group
sudo ffmpeg -y -f alsa -ac 1 -i default -acodec mp3 -b:a 64k -t 60 "${filename%.*}".mp3 &> /home/pi/motion/record_s.txt
#!/bin/bash
# merge_sv.sh
# 19/04/18: Created
# Call arguments: %f %Y%H%d%T where %f is filename with full path (eg) /home/pi/motion/videos/9403-20180511053500.mkv
# Allow record_s.sh to finish writing the .mp3 sound file (which will have the same name & path as above except .mp3)
sleep 10
filename="$1"
# The 'if' statement below will reject timelapse files '*.avi'
if [[ ${filename##*\.} != avi ]] # See answer 5 in https://stackoverflow.com/questions/407184/how-to-check-the-extension-of-a-filename-in-a-bash-script
then
#Change output file address from /home/pi/motion/videos to /home/pi/motion/pre-mergevideos (/home/pi/motion/pre-mergevideos is a directory for temporarily holding the unmerged files)
tempfolder="pre-mergevideos"
outputfolder="videosB" # This is the folder containing the merged mkv & mp3 video and the jpg files from 'motion'. This folder is rsync'd to network share 'media'.
# Replaces 'videos' in $filename with the text in $tempfolder (ie) 'pre-mergevideos' so $output becomes (eg) /home/pi/motion/pre-mergevideos/9403-20180511053500.mkv, whilst
# $filename remains (eg) /home/pi/motion/videos/9403-20180511053500.mkv
temp_locn="${filename/videos/$tempfolder}"
final_locn="${filename/videos/$outputfolder}"
#
#
# Merge video and audio into one file. Note the mp3 file has to be converted to aac for an mkv container. Error and stdout messages are redirected to merge_sv.txt. For
# 'sudo' to work user 'motion' has to be added to the sudoers file and to the sudo group.
# The expression "${filename%.*} removes ".mkv" file extension (parameter expansion)
# -itsoffset option offsets the timestamps of all streams by (in this case) 0.8 seconds in the input file following the option (without it the audio leads the video by about 0.8s).
sudo ffmpeg -y -i $filename -itsoffset 0.80 -i "${filename%.*}".mp3 -c:v copy -c:a aac $temp_locn &> /home/pi/motion/merge_sv.txt
#Delete the source files
sudo rm $filename
sudo rm "${filename%.*}".mp3
# change the file permissions on the merged file (otherwise it's root 644 rw.r..r..)
sudo chmod 777 $temp_locn
# change the owner to 'motion'
sudo chown motion:motion $temp_locn
#move the recently merged file into the 'videosB' folder. Remember both $temp_locn and $final_locn contain path and filename
sudo mv $temp_locn $final_locn
fi
tldr version:
record_s.sh records the audio from the webcam whilst motion is recording the video.
When the video recording has finished, merge_sv.sh merges the audio and video files together and deletes the source files. The script applies an offset to the audio (determined by trial and error) to get the files synched together.
There's also some jiggery pokery to stop motion crashing if the network share becomes unavailable.
Audio streaming:
I run a simple script called sound_on.sh on bootup via crontab -e to generate an rtp stream:
#!/bin/bash
# sound_on.sh
# 13/1/18
#
# killall -9 avconv
#Pre Buster version:
#avconv -f alsa -ac 1 -re -i default -acodec mp3 -ac 1 -f rtp rtp://234.5.5.5:5004 2> /tmp/mylog.log
# default was hw:1,0
#Buster version onwards:
ffmpeg -f alsa -channels 1 -i hw:1,0 -acodec mp3 -f rtp rtp://234.5.5.5:5004 2> /home/pi/motion/sound_on.log
This can be played using VLC with the following settings:
Media/Open Network Stream: network URL: http://192.168.1.122:8081 (the address of the Raspberry Pi running motion)
Show more options/Play another media synchronously: 'Extra media' rtp://234.5.5.5:5004
Then press 'Play'
Please note this only (at the time of writing) works with the Ubuntu version of VLC - the Windows 10 version crashes every time I've tried this.
- 1,283
- 5
- 22