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.targetnetwork-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 在卸载时停止服务,但在安装时不启动它

editText 背景设置但在应用程序启动时不显示

ISMServ.exe 在域控制器启动时不启动

命令在控制台中能正常执行但在shell脚本中却无法执行?

我的 Excel 2010 宏快捷方式在我第一次启动 Excel 时不起作用,但只有在我第一次从 VBE 中手动运行它时才起作用