DeadEnded / MotionEyeAudio

Script to add Audio to MotionEye recordings
66 stars 26 forks source link

Stuck trying to get the script to work #6

Closed computersandstuff closed 3 years ago

computersandstuff commented 3 years ago

I am running motioneyeOS (not on docker) on a raspberry pi 3. Currently I am using a usb camera (for testing currently) and attempting to use the built in microphone in the camera.

I started with the instructions in the readme following for meyeos. I created the motioneye-audio.sh file with vim in the /data/etc folder. I set the permissions with chmod +x for the script as mentioned in the instructions. Then I set the camera's options in the ui as this: on_movie_start /data/etc/motioneye-audio.sh start %t %f '%$' in Extra Motion settings and /data/etc/motioneye-audio.sh stop %t %f '%$' for Run a Command in file storage. I did not change any text for any of these.

I didn't see any sign that the script was doing anything. I've restarted several times, manually entered the camera id (1) in the motioneye-audio.sh file, tried to run directly from ssh, and followed many of the issues in github and the home assistant forum.

Running the command alone with the camera id specified I get the /etc/motioneye not found. I am running on motioneyeos so im not sure why it's looking there. It's actually in /data/etc/

Should I install docker with motioneye? Does this work on motioneyeos? Thanks!

computersandstuff commented 3 years ago

Sorry for writing this on thanksgiving week, and I understand if you cannot answer immediately. I just wanted to add that I switched to docker running on raspbian. At least this eliminated the issue of finding the wrong config folder, plus you stated in one of the posts that you currently have a working docker setup. Thanks!

DeadEnded commented 3 years ago

Okay, so I haven't used MotionEyeOS, just MotionEye... I have talked to a few others who have used OS though and did find that it works differently.

If you look at the issues #3 and #4 they have similar issues... I believe the first thing to test is changing line 5 and commenting line 9 (check for details in the other issues... it is posted in both). The MotionEyeOS uses different code and so the script doesn't work the same. Also, the directory pathing is different - but I think you already figured out that part.

My guess is that the script is failing because of the import on line 9 - MotionEyeOS doesn't have that code, so it probably stops the script.

Let me know if that helps! Good Luck! DeadEnd

computersandstuff commented 3 years ago

I tried working around with some different scripts it seems to be a problem with my motioneye as it won't execute certain scripts. Right now I posted an issue in the motioneye github, but I'll get back if the script executing problem is resolved

DeadEnded commented 3 years ago

Simple thing to overlook... did you chmod +x to make the script executable?

computersandstuff commented 3 years ago

I managed to get the script somewhat working. I had to install a different version on my raspi. I managed to modify the script and use arecord to get it working. Some of it would not want to execute unless I put sudo before the command to run the script in motioneye. (I didn't attempt that before as I assumed that motioneye wouldn't let you use sudo commands for security reasons) But thank you for the help, without this project I would have just assumed that it is impossible to add audio.

DeadEnded commented 3 years ago

Glad you got it working! Perhaps I will usher motioneyeOS users to use your modified version then... sounds like it took a bit of work!

computersandstuff commented 3 years ago

It's very basic and I need to improve quite a few parts of it, but once I got it to a very simple form it eliminated the problems that were occurring with my installation, but if you would like here is what I have so far: Record script:

!/bin/bash

recfolder=date '+%Y-%m-%d'; if pgrep -x 'arecord' > /dev/null then sudo pkill arecord sudo arecord --device=hw:1,0 --format S16_LE --rate 44100 -c1 /var/lib/motioneye/Camera1/$recfolder/recaudio.wav -V mono else sudo arecord --device=hw:1,0 --format S16_LE --rate 44100 -c1 /var/lib/motioneye/Camera1/$recfolder/recaudio.wav -V mono fi

And here is the finalizing script that stops the recording and merges the audio and video with ffmpeg:

!/bin/bash

timestamp=date '+%Y_%m_%d__%H_%M_%S'; recfolder=date '+%Y-%m-%d'; if pgrep -x 'arecord' > /dev/null then sudo pkill arecord; fi mv /var/lib/motioneye/Camera1/$recfolder/recaudio.wav /var/lib/motioneye/Camera1/$recfolder/readyaudio.wav sleep 5;

mp4path=$1 mp4filename=$(basename -- "$mp4path")

ffmpeg -i $mp4path -i /var/lib/motioneye/Camera1/$recfolder/readyaudio.wav -c copy /var/lib/motioneye/Camera1/$recfolder/$mp4filename.mkv

The commands are as follows: on_movie_start sudo /etc/motioneye/soundrec.sh in the extra motion options sudo /etc/motioneye/finishrec.sh %f in the file storage run a command

It works for my scenario where I'm making a raspberry pi video doorbell with only one camera, but for other projects that are more complicated there would need to be a more automated process that would not need a script for each camera. Also I should at least simply compile them into one script, but it is verified working on raspberry pi 3 b+ and raspberry pi zero. I have this installed on them: https://github.com/ccrisan/motioneye/wiki/Install-On-Raspbian

DeadEnded commented 3 years ago

That's actually very nearly where I started with this one... then I had some help combining into a single script, and using variables so that it doesn't have to have 1 script per camera. So I'd say you're doing well!

jamesbrindle commented 3 years ago

Hey,

I couldn't get your script to work on my setup (RPI4, MotionEyeOS). I had some success, but couldn't work out the commands to try and tweak them...

I had a crack at script that computersandstuff has put in here, since I've used arecord before, and I've managed to come up a script the basically combines both of your approaches, and that seems to be working nicely for me...

If anyone is having similar issues, perhaps this script will help someone out (it's not an exceptional script by any means. I struggle with bash, but here is it none-the-less... it aims at a few things:

  1. For use with motion detected - of course
  2. motionEyeOs doesn't seem to have 'pgreg' or 'pkill', so using legacy 'pidof' and 'kill' (also, I'm not just terminating with the kill command, since arecord traps the interrupt (i.e. the kill -2)
  3. I have some weird issues recording to mp4 with motionEye, but I want the video to output as mp4 (not avi - as it appears you can only stream a recorded video from the motionEye web interface if the file is .mp4), so I use ffmpeg to convert to mp4.
  4. Audio and video synchronisation appears to be an, for me the video is ahead exactly 2 seconds to the audio, so I use ffmpeg to delay 2 seconds to the audio:

Usage

  1. Place script in /data/etc (typical of motionEyeOs) or /etc/motionEye (installed motionEye application)
  2. Make file executable: chmod +x soundrec.sh
    1. Within the motionEye web interface:
      a) Set Video Device 'Extra Motion Options': on_movie_start /data/etc/soundrec.sh start
      b) Set file storage 'Command' to: sh /data/etc/soundrec.sh %f
# Variables
operation=$1                                # Bash script input argument
outputcamerafolder="/data/output/Camera2"   # Typical of motionEyeOS
tempaudiofolder="/tmp"                      # Needs to be writable folder
audiodelay=2200                             # milliseconds: Audio delay: used to sync audio and video
compress=true                               # true = Re-encode and compress video, false = Don't re-encode and compress
subfolder=$(date +'%Y-%m-%d')               # Sub-folder date format
outputfiletype=".mp4"

if pidof arecord > /dev/null
then
    # -2 = Interrupt (not 'terminate') arecord process, as arecord utilises traping STDINT()
    kill -2 `pidof arecord`
fi

nowfile="/tmp/now.tmp"

case ${operation} in
    start) # Start recording audio      
        now=`date '+%Y_%m_%d__%H_%M_%S'`.wav
        echo $now > $nowfile

        recaudio="recaudio_$now"            
        arecord --device=hw:1,0 --format S16_LE --rate 44100 -c1 $tempaudiofolder/$recaudio -V mono
    ;;

    *)
        now=`cat $nowfile`
        recaudio="recaudio_$now"
        processaudio="processaudio_$now"
        readyaudio="readyaudio_$now"

        mv $tempaudiofolder/$recaudio $tempaudiofolder/$processaudio

        videopath=$1
        videofilename=$(basename -- "$videopath")
        outputfilename=${videofilename/.avi/$outputfiletype}

        # To sync audio with video - In my case: add 2 seconds of silence before the audio stream
        ffmpeg -i $tempaudiofolder/$processaudio -af "adelay=$audiodelay|$audiodelay" $tempaudiofolder/$readyaudio      
        rm $tempaudiofolder/$processaudio || true   

        # Not highly tested. May issues in the long run, as this process takes a good few seconds to run
        case ${compress} in
            true)           
                ffmpeg -y -i $videopath -i $tempaudiofolder/$readyaudio -c:v libx264 -crf 24 -preset medium -c:a aac -b:a 128k -shortest $outputcamerafolder/$subfolder/temp_$videofilename
         ;;         

        *)
                ffmpeg -y -i $videopath -i $tempaudiofolder/$readyaudio -c:v copy -c:a aac -shortest $outputcamerafolder/$subfolder/temp_$videofilename     
        ;;
        esac    

        rm $tempaudiofolder/$readyaudio || true     
        rm $outputcamerafolder/$subfolder/$videofilename || true        
        mv $outputcamerafolder/$subfolder/temp_$videofilename $outputcamerafolder/$subfolder/$videofilename             
    ;;
esac

exit 0
andrefernando25 commented 1 year ago

Hi! I'm going through the same problem. I use Motioneye and it is not recording audio, I did exactly what was in the information and even added the script.

Mine is installed on Debian 11, even with the sudo command in "run a command" it does not record with audio. can you help me?