tdashmike
(Mike Lin)
March 10, 2021, 3:54am
1
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?
nickrout
(Nick Rout)
March 10, 2021, 7:56am
3
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
tdashmike
(Mike Lin)
March 10, 2021, 4:06pm
4
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
tdashmike
(Mike Lin)
March 10, 2021, 4:11pm
5
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.
tdashmike
(Mike Lin)
March 11, 2021, 12:30am
8
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