I needed an encoder-service waiting to handle ffmpeg-workloads, and decided to use systemctl
and a fifo pipe, so jobs could be queued without the need of RabbitMQ/other.
I'm aware of DLQ and fancy scaling, however this does the trick and hasn't failed for years.
1) Create script for initiating the fifo pipe, save it at /opt/createWorkerPipe.sh
:
#!/bin/bash
# pipe location
pipe=/tmp/ffmpeg-pipe
trap "rm -f $pipe" EXIT
# Initiate pipe
[[ -p $pipe ]] || mkfifo $pipe
while true; do
exec 3<> $pipe
read line < $pipe
bash <<< "/opt/ffmpeg-worker.sh $line"
done
2) Create your ffmpeg-worker, with your ffmpeg args, at /opt/ffmpeg-worker.sh
:
#!/bin/bash
# Do ffmpeg stuff
/usr/bin/ffmpeg -y input.avi [yourargs] output.mp4
3) Create service file at /etc/systemd/system/ffmpeg-encoder.service
:
[Unit]
Description=ffmpeg encoder service
DefaultDependencies=no
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
ExecStart=/opt/createWorkerPipe.sh:
TimeoutStartSec=0
RemainAfterExit=yes
[Install]
WantedBy=default.target
3) Reload systemctl daemon: systemctl daemon-reload
4) Enable service: systemctl enable ffmpeg-encoder.service
Verify the service state with: systemctl status ffmpeg-encoder.service
Verifying service status programatially can be done by running:
systemctl is-active --quiet ffmpeg-encoder.service
where exitcode 0
is the active state of the service.
I also wrote a simple ffmpeg-log-parser for polling state via PHP, but that's for another post.