FFmpeg 手动启动,但在启动时不使用 Systemd
Posted
技术标签:
【中文标题】FFmpeg 手动启动,但在启动时不使用 Systemd【英文标题】:FFmpeg starting manually but not with Systemd on boot 【发布时间】:2020-11-02 21:26:07 【问题描述】:在带有官方 Debian 10 映像的 Raspberry Pi 4 B 4GB 上,我有 /home/pi/run.sh 脚本,其中包含以下内容:
#!/bin/bash
ffmpeg -nostdin -framerate 15 -video_size 1280x720 -input_format yuyv422 -i /dev/video0 -f alsa -i hw:Device \
-af acompressor=threshold=-14dB:ratio=9:attack=10:release=1000 -c:a aac -ac 2 -ar 48000 -ab 160k \
-c:v libx264 -pix_fmt yuv420p -b:v 3M -bf 1 -g 20 -flags +ilme+ildct -preset ultrafast \
-streamid 0:0x101 -streamid 1:0x100 -mpegts_pmt_start_pid 4096 -mpegts_start_pid 0x259 -metadata:s:a:0 language="" -mpegts_service_id 131 -mpegts_transport_stream_id 9217 -metadata provider_name="Doesnt matter" -metadata service_name="Doesnt matter" \
-minrate 3500 -maxrate 3500k -bufsize 4500k -muxrate 4000k -f mpegts "udp://@239.1.67.13:1234?pkt_size=1316&bitrate=4000000&dscp=34" -loglevel debug < /dev/null > /tmp/ff3.log 2>&1
脚本从控制台启动没有问题。它从 USB 声卡获取音频,从 USB 摄像头获取视频,并创建 UDP 流到 IPTV。然后我创建了 Systemd 服务:
[Unit]
Description=Streamer
After=multi-user.target sound.target network.target
[Service]
ExecStart=/home/pi/run.sh
KillMode=control-group
Restart=on-failure
TimeoutSec=1
[Install]
WantedBy=multi-user.target
Alias=streaming.service
重启树莓后,脚本已经启动,但是FFmpeg在日志中出现错误失败挂起:
cur_dts is invalid st:0 (257) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:1 (256) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (257) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:1 (256) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (257) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:1 (256) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (257) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:1 (256) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
并且不会开始流式传输到 UDP 目标。但是,如果我手动登录 SSH 并发出 systemctl stop streaming 然后 systemctl start streaming Ffmpeg 启动成功。启动时服务自动启动有什么不同?
在脚本请求时设置“睡眠超时”将无济于事。但是,从 FFmpeg 配置中删除音频流似乎可以解决开机自动启动问题。
【问题讨论】:
当你在脚本中将sleep 30
放在 ffmpeg 之前,你是否得到了同样的错误?
是的,我提到过这个问题。没有区别。
【参考方案1】:
TLDR
使用
After=network-online.target
一步一步找出真正的问题。
1。这个错误告诉我们什么。
github ffmpeg 显示错误出现在选择输出时。
choose_output
函数为流选择输出。
2。为什么输出没有准备好?
当您尝试通过网络进行流式传输时,您需要在启动 ffmpeg 之前完全配置网络。
您的 systemd 脚本存在小问题。
network.target
和 network-online.target
之间有区别
关注systemd manual for network targets
network.target 在启动过程中意义不大。
network-online.target 是一个主动等待网络“up”的目标
现在您知道为什么您的脚本在启动时无法在 systemd 中运行,但在服务重新启动后它开始运行了吗?
如果需要更多说明,请发表评论。
【讨论】:
不,它没有帮助。我认为更改为 network-online.target 应该有类似的效果,就像在开始时设置睡眠一样。它也不起作用。我什至尝试记录到不等待网络启动的文件(.mp4),我在日志中看到相同的错误。现在唯一的解决方法是从配置中删除音频 ALSA 音频流,然后它会成功启动。 检查你的 sound.target 是否包含对 USB 声卡的依赖。可以为设备添加日志aplay --list-devices
吗?【参考方案2】:
对于那些后来提出这个问题的人,我在使用 systemd 启动时运行 FFmpeg 流代码时遇到了同样的问题。
我为解决这个问题所做的是编写另一个 python 代码(导入了子进程)来停止并在启动完成后再次启动流式 systemd 服务并出现一些睡眠延迟。并将此代码添加为 systemd 的另一个服务,该服务在前一个服务之后运行(在 [Unit]
下使用 After=streaming.service
)。
【讨论】:
以上是关于FFmpeg 手动启动,但在启动时不使用 Systemd的主要内容,如果未能解决你的问题,请参考以下文章
ContentControl 在应用程序通过 UI 自动化测试启动时不可见,但在用户启动应用程序时可见
WiX ServiceControl 在卸载时停止服务,但在安装时不启动它
我的 Excel 2010 宏快捷方式在我第一次启动 Excel 时不起作用,但只有在我第一次从 VBE 中手动运行它时才起作用