Ubuntu 22.04下FFmpeg同时转码RTSP、RTMP至UDP并实现后台运行与开机自启的技术咨询
Ubuntu 22.04下FFmpeg同时转码RTSP、RTMP至UDP并实现后台运行与开机自启的技术咨询
嗨,我来帮你一步步搞定这个需求!这其实是几个常见场景的组合,咱们拆解开来逐个解决:
1. 编写FFmpeg转码命令
你需要针对RTSP和RTMP源分别生成UDP输出,这里有两种实现思路,你可以根据自己的需求选择:
方式一:单FFmpeg进程同时处理两个输入输出
这种方式能节省系统资源,一条命令就能搞定两个流的转码:
ffmpeg \ -i rtsp://your-rtsp-source-url \ -c:v copy -c:a copy -f mpegts udp://your-udp-dest-1:port \ -i rtmp://your-rtmp-source-url \ -c:v copy -c:a copy -f mpegts udp://your-udp-dest-2:port
- 小提示:
-c:v copy -c:a copy是直接复制音视频编码,效率最高;如果源编码不兼容UDP传输(比如某些特殊编码),可以换成-c:v h264 -c:a aac重新编码。-f mpegts是指定输出为MPEG-TS格式,这是UDP传输最稳定的封装格式,能避免丢包导致的播放中断。
方式二:分开两个独立FFmpeg进程(更稳定,便于单独管理)
如果担心一个进程出问题影响另一个流,建议分开启动两个命令,这样可以单独启停或排查每个流的问题:
# 处理RTSP转UDP ffmpeg -i rtsp://your-rtsp-source-url -c:v copy -c:a copy -f mpegts udp://your-udp-dest-1:port # 处理RTMP转UDP ffmpeg -i rtmp://your-rtmp-source-url -c:v copy -c:a copy -f mpegts udp://your-udp-dest-2:port
2. 让进程在后台持续运行
要让FFmpeg不受终端关闭影响,一直在后台跑,推荐用nohup结合&命令,同时把日志写到指定文件,方便后续排查问题:
针对单进程命令:
nohup ffmpeg \ -i rtsp://your-rtsp-source-url \ -c:v copy -c:a copy -f mpegts udp://your-udp-dest-1:port \ -i rtmp://your-rtmp-source-url \ -c:v copy -c:a copy -f mpegts udp://your-udp-dest-2:port > /var/log/ffmpeg-stream.log 2>&1 &
- 解释:
nohup会忽略终端挂起信号,就算你关掉SSH连接进程也不会停;> /var/log/ffmpeg-stream.log 2>&1是把正常输出和错误输出都写到日志文件里;&是让进程直接在后台运行。
针对两个独立进程:
# 后台运行RTSP转UDP,日志单独存放 nohup ffmpeg -i rtsp://your-rtsp-source-url -c:v copy -c:a copy -f mpegts udp://your-udp-dest-1:port > /var/log/ffmpeg-rtsp.log 2>&1 & # 后台运行RTMP转UDP,日志单独存放 nohup ffmpeg -i rtmp://your-rtmp-source-url -c:v copy -c:a copy -f mpegts udp://your-udp-dest-2:port > /var/log/ffmpeg-rtmp.log 2>&1 &
如果需要停止后台进程,先执行ps aux | grep ffmpeg找到对应的进程ID,再用kill <进程ID>就能终止了。
3. 配置开机自动启动(用Systemd服务)
Ubuntu 22.04默认用systemd管理系统服务,咱们可以创建自定义服务,让FFmpeg转码进程开机自动启动:
步骤1:创建systemd服务文件
先打开文本编辑器创建服务文件,比如单进程版本的:
sudo nano /etc/systemd/system/ffmpeg-stream.service
然后粘贴以下配置内容(记得把里面的URL和端口换成你自己的):
[Unit] Description=FFmpeg RTSP/RTMP to UDP Transcoding After=network.target [Service] Type=simple User=root # 也可以换成你常用的非root用户,只要该用户有网络权限和日志写入权限就行 ExecStart=/usr/bin/ffmpeg \ -i rtsp://your-rtsp-source-url \ -c:v copy -c:a copy -f mpegts udp://your-udp-dest-1:port \ -i rtmp://your-rtmp-source-url \ -c:v copy -c:a copy -f mpegts udp://your-udp-dest-2:port StandardOutput=append:/var/log/ffmpeg-stream.log StandardError=append:/var/log/ffmpeg-stream.log Restart=always # 进程意外退出时自动重启 RestartSec=5 # 重启间隔5秒 [Install] WantedBy=multi-user.target
如果你选的是双进程方式,建议创建两个独立服务,比如ffmpeg-rtsp.service和ffmpeg-rtmp.service,以ffmpeg-rtsp.service为例:
[Unit] Description=FFmpeg RTSP to UDP Transcoding After=network.target [Service] Type=simple User=root ExecStart=/usr/bin/ffmpeg -i rtsp://your-rtsp-source-url -c:v copy -c:a copy -f mpegts udp://your-udp-dest-1:port StandardOutput=append:/var/log/ffmpeg-rtsp.log StandardError=append:/var/log/ffmpeg-rtsp.log Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
另一个ffmpeg-rtmp.service只要修改Description、ExecStart和日志路径就行。
步骤2:启用并启动服务
配置好后,先重新加载systemd的配置:
sudo systemctl daemon-reload
然后启用服务(让它开机自启):
# 单进程版本 sudo systemctl enable ffmpeg-stream.service # 双进程版本 sudo systemctl enable ffmpeg-rtsp.service sudo systemctl enable ffmpeg-rtmp.service
最后启动服务,测试一下是否正常运行:
# 单进程版本 sudo systemctl start ffmpeg-stream.service # 双进程版本 sudo systemctl start ffmpeg-rtsp.service sudo systemctl start ffmpeg-rtmp.service
检查服务状态
执行以下命令就能查看服务是否正常运行:
# 单进程版本 sudo systemctl status ffmpeg-stream.service # 双进程版本 sudo systemctl status ffmpeg-rtsp.service sudo systemctl status ffmpeg-rtmp.service
一些实用小提示
- 要是你的服务器还没装FFmpeg,先执行
sudo apt update && sudo apt install ffmpeg安装一下。 - 确保UDP目标端已经监听对应端口,而且服务器和目标端之间的网络没有防火墙阻挡UDP流量。
- 如果转码时出现卡顿或丢包,可以试试给RTSP源加
-rtsp_transport tcp参数(让RTSP用TCP传输,比默认的UDP更稳定),或者增加缓冲区大小-bufsize 10M。
备注:内容来源于stack exchange,提问作者Mohammed Fawaz M
相关产品推荐
相关产品推荐

