How to stop shell script

Hello, I have an automation that’s triggering a shell script to record with ffmpeg. It is working but how do I stop it? Thank you.

#!/bin/bash
rm /config/scripts/camera_1.log;
exec &>>/config/scripts/camera_1.log;
ffmpeg -i "rtsp://xxx.xxx.xxx.xxx/user=&password=&channel=1&stream=0.sdp" -c copy -map 0 -f segment -segment_time 300 -segment_format mp4 "/config/scripts/capture-%03d.mp4";

UPDATE: I just made the automation call another script that had the command "killall fmpeg;". If anyone knows a better way to stop the ffmpeg recording please let me know. Like being able to kill the exact instance or stopping the recording elegantly as right now it just corrupts the file.

A killall is a hard, immediate kill. Not a good idea, generally, to stop something that’s running fine. Rather try a soft kill, such as SIGTERM.

I have no idea what your automation does but why not create a camera entity and use the camera.record service with a duration?

The other way is to save the PID of the process as the first thing it does, then kill the PID rather than every ffmpeg process. This is a common linux technique.

1 Like

The ffmpeg options automatically split the files so it’s not one huge file. There seemed to be an issue using it in a loop as I want to continuously record the video so I have not tried it yet.

Update:
I just noticed that it says “Exiting normally, received signal 15.” when I use kill and signal 15 is SIGTERM. Although I would like to just stop that one process. Still working on that.

Issue tracker: https://github.com/home-assistant/core/issues/30025

I’m trying to find the PID of the process so I can kill just that process but I’m not having much success. I think it’s because HASS is adding a return or newline to the end of the ffmpeg command. In my script I have to add a “;” at the end of every line or else the commands don’t work. I tried adding “& echo $1” just to see if I can get it show first.

ffmpeg -i "rtsp://xxx.xxx.xxx.xxx/user=&password=&channel=1&stream=0.sdp" -c copy -map 0 -movflags +faststart -f segment -segment_time 30 -segment_format mp4 "/config/scripts/capture-%03d.mp4" & echo $1;

Log output:

ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.3.0 (Alpine 9.3.0)
  configuration: --prefix=/usr --enable-avresample --enable-avfilter --enable-gnutls --enable-gpl --enable-libass --enable-libmp3lame --enable-libvorbis --enable-libvpx --enable-libxvid --enable-libx264 --enable-libx265 --enable-libtheora --enable-libv4l2 --enable-libdav1d --enable-postproc --enable-pic --enable-pthreads --enable-shared --enable-libxcb --enable-libssh --disable-stripping --disable-static --disable-librtmp --enable-vaapi --enable-vdpau --enable-libopus --enable-libaom --disable-debug
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, rtsp, from 'rtsp://xxx.xxx.xxx.xxx/user=&password=&channel=1&stream=0.sdp':
  Metadata:
    title           : RTSP Session
  Duration: N/A, start: 0.189100, bitrate: N/A
    Stream #0:0: Video: h264 (Baseline), yuv420p(progressive), 1280x960, 11 fps, 11 tbr, 90k tbn, 22 tbc
[segment @ 0x7f7377e4ac00] Opening '/config/scripts/capture-000.mp4' for writing
Output #0, segment, to '/config/scripts/capture-%03d.mp4':
  Metadata:
    title           : RTSP Session
    encoder         : Lavf58.45.100
    Stream #0:0: Video: h264 (Baseline), yuv420p(progressive), 1280x960, q=2-31, 11 fps, 11 tbr, 11264 tbn, 11 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
[segment @ 0x7f7377e4ac00] Non-monotonous DTS in output stream 0:0; previous: 0, current: -1679; changing to 1. This may result in incorrect timestamps in the output file.
[segment @ 0x7f7377e4ac00] Non-monotonous DTS in output stream 0:0; previous: 1, current: -1229; changing to 2. This may result in incorrect timestamps in the output file.
[segment @ 0x7f7377e4ac00] Non-monotonous DTS in output stream 0:0; previous: 2, current: -778; changing to 3. This may result in incorrect timestamps in the output file.
[segment @ 0x7f7377e4ac00] Non-monotonous DTS in output stream 0:0; previous: 3, current: -328; changing to 4. This may result in incorrect timestamps in the output file.
frame=   37 fps=0.0 q=-1.0 size=N/A time=00:00:02.01 bitrate=N/A speed=3.57x    
frame=   44 fps= 41 q=-1.0 size=N/A time=00:00:02.65 bitrate=N/A speed=2.44x    
frame=   51 fps= 31 q=-1.0 size=N/A time=00:00:03.28 bitrate=N/A speed=2.01x    
frame=   57 fps= 26 q=-1.0 size=N/A time=00:00:03.83 bitrate=N/A speed=1.76x    
frame=   64 fps= 23 q=-1.0 size=N/A time=00:00:04.46 bitrate=N/A speed=1.62x    
frame=   71 fps= 21 q=-1.0 size=N/A time=00:00:05.10 bitrate=N/A speed=1.53x    
frame=   78 fps= 20 q=-1.0 size=N/A time=00:00:05.74 bitrate=N/A speed=1.46x    
frame=   85 fps= 19 q=-1.0 size=N/A time=00:00:06.37 bitrate=N/A speed=1.41x    
frame=   92 fps= 18 q=-1.0 size=N/A time=00:00:07.01 bitrate=N/A speed=1.38x    
frame=   99 fps= 18 q=-1.0 size=N/A time=00:00:07.65 bitrate=N/A speed=1.37x    
frame=  106 fps= 17 q=-1.0 size=N/A time=00:00:08.28 bitrate=N/A speed=1.36x    
frame=  106 fps= 17 q=-1.0 Lsize=N/A time=00:00:08.28 bitrate=N/A speed=1.34x    
video:4504kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Exiting normally, received signal 15.

Have a look at this post.

Basically, put the process in the background briefly (the single &), get the PID and resume (%1).

I’ve tested the idea by doing this:

echo 'hello world!' & echo $! > /tmp/my_pid

Output:

$ echo 'hello world!' & echo $! > /tmp/my_pid
[1] 73857
hello world!
[1]+  Done                    echo 'hello world!'
$ cat /tmp/my_pid
73857

Job [1] has (had) PID 73857.

I’ve seen the recording duration not being 100% accurate when the system running ffmpeg is under heavy load but not as bad as mentioned in that issue. In my own case, it might be off by a second or two.

Thanks for the help, below is what worked for me.


Note: The pid is stored at the very end of the ffmpeg command.


Record script:

#!/bin/bash
rm /config/scripts/camera_1.log;
exec &>>/config/scripts/camera_1.log;
ffmpeg -i "rtsp://xxx.xxx.xxx.xxx/user=&password=&channel=1&stream=0.sdp" -c copy -map 0 -movflags +faststart -f segment -segment_time 300 -segment_format matroska -strftime 1 -reset_timestamps 1 "/media/camera_1/%Y%m%d-%H%M%S.mkv" & echo $! > /config/scripts/ffmpeg_pid;

Stop script:

#!/bin/bash
rm /config/scripts/stop.log;
exec &>>/config/scripts/stop.log;
kill -HUP $(cat /config/scripts/ffmpeg_pid);
1 Like