Search code examples
linuxvideoffmpegservicesystemd

Record video stream with ffmpeg as a service


I would like to use ffmpeg to record the video stream of a surveillance camera. For this I have a script to start the recording and a service for systemd. The idea is that if ffmpeg is stopped in between because the stream is interrupted, the service will be restarted automatically.

Start recording (/media/HDD1/video/video-record.sh):

#!/bin/bash
ip=$1
codec=h264
res=1920x1080
out="/media/HDD1/video/$ip-$codec-$(date -u +"%Y%m%dT%H%M%S").mp4"
url="rtsp://192.168.4.$ip/axis-media/media.amp?camera=1&videocodec=$codec&fps=24&resolution=$res&compression=60&videozstrength=50&videoframeskipmode=drop"
ffmpeg -nostdin -i "$url" -acodec copy -vcodec copy $out

Service file:

[Unit]
Description=Record camera 101 to HDD

[Service]
Type=simple
ExecStart=/bin/bash /media/HDD1/video/video-record.sh 101
Restart=always
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

The script works fine when I start and stop it manually. Starting the service also works without problems, only when terminating there are problems. In the log it says:

Error closing file /media/HDD1/video/101-h264-20230719T094514.mp4: Immediate exit requested.

Also, I can't play the video file anymore. Any idea?


Solution

  • The log entry is indicating that FFmpeg was killed with SIGTERM, causing it to ungracefully exit. Your MP4 isn't playable because it is missing the moov atom which is written after the recording is successful.

    You can configure Systemd's kill procedure to allow FFmpeg to exit gracefully by using SIGINT instead. Try something like this:

    KillSignal=SIGINT
    

    See also: https://www.freedesktop.org/software/systemd/man/systemd.kill.html