Adding Audio to MotionEye Recordings

That might be it… change your motioneye-audio.sh permissions to this:
image
Do it from the host… it might not be executing from the container.

Sorry about delay - board said I had too many posts as a new user and had to wait 3 hours. :slight_smile:

I made the permissions change but no change in audio. See pic of my chmod results. Still no audio. After the permissions change I ran a ps -ef while the mp4 was recording and did not see a ffmpeg process running, nor did I see a .wav file being created.

Do you think it could be a camera-specific issue even though I was able to get a .wav created when I manually ran ffmpeg on the stream?

Okay, we need to dig… so lets try this.
Replace the text in your motioneye-audio.sh with this:

#!/usr/bin/env bash

# Set variables
operation=$1
camera_id=$2
file_path=$3
motion_config_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
motion_camera_conf="${motion_config_dir}/camera-${camera_id}.conf"
netcam="$(if grep -q 'netcam_highres' ${motion_camera_conf};then echo 'netcam_highres'; else echo 'netcam_url'; fi)"
extension="$(echo ${file_path} | sed 's/^/./' | rev | cut -d. -f1  | rev)"

case ${operation} in
    start)
        credentials="$(grep netcam_userpass ${motion_camera_conf} | sed -e 's/netcam_userpass.//')"
		echo "credentials = " $credentials > /tmp/script-verification
        stream="$(grep ${netcam} ${motion_camera_conf} | sed -e "s/${netcam}.//")"
		echo "stream = " $stream >> /tmp/script-verification
        full_stream="$(echo ${stream} | sed -e "s/\/\//\/\/${credentials}@/")"
		echo "full_stream = " $full_stream >> /tmp/script-verification
        ffmpeg -y -i "${full_stream}" -c:a aac ${file_path}.aac | tee /tmp/script-verification 2>&1 1>/dev/null &
        ffmpeg_pid=$!
        echo ${ffmpeg_pid} > /tmp/motion-audio-ffmpeg-camera-${camera_id}
        ;;

    stop)
        # Kill the ffmpeg audio recording for the clip
        kill $(cat /tmp/motion-audio-ffmpeg-camera-${camera_id})
        rm -rf $(cat /tmp/motion-audio-ffmpeg-camera-${camera_id})

        # Merge the video and audio to a single file, and replace the original video file
        ffmpeg -y -i ${file_path} -i ${file_path}.aac -c:v copy -c:a copy ${file_path}.temp.${extension};
        mv -f ${file_path}.temp.${extension} ${file_path};

        # Remove audio file after merging
        rm -f ${file_path}.aac;
        ;;

    *)
        echo "Usage ./motioneye-audio.sh start <camera-id> <full-path-to-moviefile>"
        exit 1
esac

If I did it correctly, it should output each command into a file called /tmp/script-verification. Once you get that (should have 4 lines when complete - the 4th I’m not positive I did correctly though…) clean personal info and paste it here. Lets see if we can find anything in it that points to the problem.

Thanks!

File was created but it is completely empty.

Oppsy… I missed a flag on the tee command.
change:

tee /tmp/script-verification

to:

tee -a /tmp/script-verification

and try it again.

Thanks!

OK. We got something. But it is odd. See attached output.

I say it is odd because the IP:PORT data is to another camera. The camera I am working with is called “Driveway” and is identified as Camera 3 in MotionEyeOS. The data in the script-verification file points to a IP:PORT address of a camera called “Front” and it is identified as Camera 1 in MotionEyeOS. In the MotionEyeOS setup I do not have the “on_movie_start” command loaded for camera 1. I do for camera 3. I also looked in the conf files for both cameras and they are correct with the correct IP:PORT data.

Any idea why the audio script would be looking to another camera?

Thanks!

I had this happen just last week! My 2 camera’s switch audio streams (that took a while to figure out!).

I thought I caused it somehow, but if you also had this happen, then I think it is a bug in MotionEye. It is caching somehow the cameraID and not using what is saved in the config file.

This is very interesting to see since it confirms what I had happen to me is not a fluke. Reproducing it will take some work - but should be doable. To fix it I disabled all camera’s and then turned them on one at a time to get the cameraID’s to straighten out.

If your other camera does not have audio, or audio was disabled, or has a different stream path, etc. that would explain why it never got the audio.

Try turning all camera’s off in MotionEye, and then turn on just the one for audio and see if the information straightens out. I will try to document how to recreate this so I can submit a bug to MotionEye.

Cheers!

Wholy crap… that was easy… recreated by starting up two cameras - then turning off the first camera. The second camera even though it is cameraID 2 is using cameraID 1.

The file path is pulled as an independent variable - not referenced by the cameraID. So everything is based on the CameraID EXCEPT the file path.

So for when my setup failed, it switched the file paths which explains why the merge put the audio files in the wrong place. For your setup, check the folder path for your other camera - you very well may have audio files sitting there :laughing:

Now, time to submit a bug!
Thanks
DeadEnd

So I disabled all my cams then ONLY turned on my Driveway cam and ran a test. The script-verification file still shows that it is trying to point to Front. Even though that cam is actually disabled right now. I’m going to reboot the Pi and try again…

Also, I did check my other output folders. No WAV files.

I have update the script and readme in to repo.
The change is to use the camera_name instead of camera_id.
The motioneye config files don’t specify the camera_id and so motion engine uses thread instead… which is what leads to the mismatch.

I have updated the script to use the camera_name but this requires you to change the %t to '%$' to use the name instead of ID (both the movie start and movie end need this change).

Try pulling the new script, and updating the start/stop commands and see if that fixes it for you.
I testing it quickly on my setup and it appears to be working.

Thanks,
DeadEnd

OK. Pulled the new script and put in place. Changed the on motion commands to use the %$ as readme instructed. Ran a test. No audio in the MP4 and no .WAV created. I attempted to re-introduce your troubleshooting code back into the new script to try and see if the correct IP:PORT was now in play. It is possible I hosed it up as you can see by the script-verification file output below. It now seems to be pulling data from cam 2 and cam 3? (remember, cam 3 is what we’re working with) Again, it could have been my poor attempt at piecing together the new script with your debug code. Was just trying to make it easier on you by not asking you to do it. Look at the output and see if you think it is valid.

One thing I did notice is a motion-audio-ffmpeg-camera-Driveway file in the tmp directory where there was none before. File contained the number 13392.

Share the script as you have it now?
Also copy and paste in what you have in your on_movie_start and on_movie_end to verify.

It looks like the new script that goes by name is seeing both of your config files as being valid… so that might screw it up a bit as it pulls in multiple values… just a guess though - hoping to get the camera_id fixed in MotionEye so I can go back to that method… it was much simpler!

Thanks!
DeadEnd

See current script below. I had to remove some line spaces to fit it all in one screen snip.

Here are my start and end statements in MotionEyeOS setup:
Video Device > Extra Motion Options:
on_movie_start /data/etc/motioneye-audio.sh start ‘%$’ %f

File Storage > Run a command:
/data/etc/motioneye-audio.sh stop ‘%$’ %f

Okay, holiday weekend, but I’m looking when I have time.
The recordings in verification are weird… pulling in the file path isn’t suppose to happen… try to figure out how/why that is happening… might be the source of the problem…

No worries. Enjoy your holiday weekend. I really appreciate your helping me with this. We can get back at it next week. If there is anything I can do just let me know.

Okay, I added a bunch of echo’s to see the different variables… should be similar to the one I sent you before, I have not clue why the directories are being added - but that might be part of the problem…

Try this as your script and see if the verification come out correct:

#!/usr/bin/env bash

# Set variables
operation=$1
# Changing to Camera Name
# camera_id=$2
camera_name=$2
        echo "camera_name = " $camera_name >> /tmp/script-verification
file_path=$3
        echo "file_path = " $file_path >> /tmp/script-verification
motion_config_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
        echo "motion_config_dir = " $motion_config_dir >> /tmp/script-verification
# Replacing with camera name due to cameraID/thread mismatch
# motion_camera_conf="${motion_config_dir}/camera-${camera_id}.conf"
motion_camera_conf="$( egrep -l \^camera_name.${camera_name} ${motion_config_dir}/*.conf)"
        echo "motion_camera_conf = " $motion_camera_conf >> /tmp/script-verification
netcam="$(if grep -q 'netcam_highres' ${motion_camera_conf};then echo 'netcam_highres'; else echo 'netcam_url'; fi)"
extension="$(echo ${file_path} | sed 's/^/./' | rev | cut -d. -f1  | rev)"

case ${operation} in
    start)
        credentials="$(grep netcam_userpass ${motion_camera_conf} | sed -e 's/netcam_userpass.//')"
                echo "credentials = " $credentials >> /tmp/script-verification
        stream="$(grep ${netcam} ${motion_camera_conf} | sed -e "s/${netcam}.//")"
                echo "stream = " $stream >> /tmp/script-verification
        full_stream="$(echo ${stream} | sed -e "s/\/\//\/\/${credentials}@/")"
                echo "full_stream = " $full_stream >> /tmp/script-verification
        ffmpeg -y -i "${full_stream}" -c:a aac ${file_path}.aac | tee -a /tmp/script-verification 2>&1 1>/dev/null &
        ffmpeg_pid=$!
        # echo ${ffmpeg_pid} > /tmp/motion-audio-ffmpeg-camera-${camera_id}
        echo ${ffmpeg_pid} > /tmp/motion-audio-ffmpeg-camera-${camera_name}
        ;;

    stop)
        # Kill the ffmpeg audio recording for the clip
        # kill $(cat /tmp/motion-audio-ffmpeg-camera-${camera_id})
        # rm -rf $(cat /tmp/motion-audio-ffmpeg-camera-${camera_id})
        kill $(cat /tmp/motion-audio-ffmpeg-camera-${camera_name})
        rm -rf $(cat /tmp/motion-audio-ffmpeg-camera-${camera_name})

        # Merge the video and audio to a single file, and replace the original video file
        ffmpeg -y -i ${file_path} -i ${file_path}.aac -c:v copy -c:a copy ${file_path}.temp.${extension};
        mv -f ${file_path}.temp.${extension} ${file_path};

        # Remove audio file after merging
        rm -f ${file_path}.aac;
        ;;

    *)
        # echo "Usage ./motioneye-audio.sh start <camera-id> <full-path-to-moviefile>"
        echo "Usage ./motioneye-audio.sh start <camera-name> <full-path-to-moviefile>"
        exit 1
esac

Still pulling in data for 2 cams it seems. See below.

credentials =  /data/etc/camera-2.conf:{correct credentials} /data/etc/camera-3.conf:{correct credentials}
stream =  /data/etc/camera-2.conf:rtsp://{IP:PORT to Driveway2 - incorrect}/cam/realmonitor?channel=1&subtype=1 /data/etc/camera-3.conf:rtsp://{IP:PORT to Driveway - correct}/cam/realmonitor?channel=1&subtype=1
full_stream = 
camera_name =  Driveway
file_path =  /data/media/sda1/data/output/Driveway/2020-07-04/23-02-05.mp4
motion_config_dir =  /data/etc
motion_camera_conf =  /data/etc/camera-2.conf {<--cam 2 is Driveway2} /data/etc/camera-3.conf {<--cam 3 is Driveway}
credentials =  /data/etc/camera-2.conf:{correct credentials} /data/etc/camera-3.conf:{correct credentials}
stream =  /data/etc/camera-2.conf:rtsp://{IP:PORT to Driveway2 - incorrect}/cam/realmonitor?channel=1&subtype=1 /data/etc/camera-3.conf:rtsp://{IP:PORT to Driveway - correct}/cam/realmonitor?channel=1&subtype=1
full_stream = 
camera_name =  Driveway
file_path =  /data/media/sda1/data/output/Driveway/2020-07-04/23-02-05.mp4
motion_config_dir =  /data/etc
motion_camera_conf =  /data/etc/camera-2.conf /data/etc/camera-3.conf

Yeah, the problem here is that because the ID isn’t working we have to parse for the camera name… so if you have two camera’s with Driveway in them, both are found. Like I said earlier… really need to get the cameraID fixed in motioneye configs so that we don’t have to do that… its always going to have a problem somewhere…

But I still don’t understand why your creds and stream are getting the file path.
That is what is breaking it… because when it goes to make the full stream it fails… because the /data/etc/camera-#.conf isn’t suppose to be there. Maybe change your second camera name so it doesn’t have Driveway in it… see if everything cleans up…

BTW you can see that the full stream is blank - so the ffmpeg commands are going to fail.

Cheers!
DeadEnd

That was it! I’m seeing the .aac file show up and the resulting .mp4 now has sound! Below is the verification data if you want to see it.

I feel dumb that I did not think of the similar camera names when you told me you were switching from ID to name! Sorry about that…

Now that I’ve renamed my cam 2 I can just revert my script back to your latest release to get rid of all the verification echo’s, correct?

Thanks again for all your help on this!

camera_name =  Driveway
file_path =  /data/media/sda1/data/output/Driveway/2020-07-04/23-46-51.mp4
motion_config_dir =  /data/etc
motion_camera_conf =  /data/etc/camera-3.conf
credentials =  {correct creds}
stream =  rtsp://{correct IP:PORT}/cam/realmonitor?channel=1&subtype=1
full_stream =  rtsp://{correct creds}@{correct IP:PORT}/cam/realmonitor?channel=1&subtype=1
camera_name =  Driveway
file_path =  /data/media/sda1/data/output/Driveway/2020-07-04/23-46-51.mp4
motion_config_dir =  /data/etc
motion_camera_conf =  /data/etc/camera-3.conf

Fantastic!
Very happy it is working for you now!

In the future I hope to get the camera_id working as it should, and then camera name won’t matter. This is a better solution, but requires MotionEye to put the camera_id in the config file.

Cheers and congrats!
DeadEnd