PHP 8 下解决 RTMP 断流的核心是稳健启动、监控并重启 FFmpeg 进程,关键路径有三:1. 用 while 循环 + exec() 实现进程级自动重启;2. 配齐 FFmpeg 原生重连参数(-reconnect 1、-reconnect_at_eof 1、-reconnect_streamed 1、-reconnect_delay_max 5);3. 用 pcntl_fork() 实现守护进程管理。

PHP 8 本身不直接处理 RTMP 流中断,它只是调用 FFmpeg 的“调度员”。真正解决断流问题的核心,在于 如何用 PHP 8 稳健地启动、监控并重启 FFmpeg 进程,同时配合正确的 FFmpeg 参数实现自动重连。关键不是 PHP 版本新旧,而是架构设计是否容错。
以下三点是 PHP 8 环境下最实用、生产可用的解决路径:
用 while 循环 + exec() 实现进程级自动重启
PHP 8 的 exec() 或 proc_open() 可以捕获 FFmpeg 退出状态。当 FFmpeg 因网络闪断退出(返回非 0 状态码),PHP 主动拉起新进程,比依赖 FFmpeg 内置重连更可靠(尤其对 RTSP 源或老旧服务器)。
$rtmpUrl = "rtmp://39.105.129.233/myapp/stream_key";
$source = "rtsp://camera-ip/stream";
while (true) {
echo "[INFO] Starting FFmpeg at " . date('Y-m-d H:i:s') . "\n";
$cmd = sprintf(
'ffmpeg -rtsp_transport tcp -stimeout 5000000 -i "%s" ' .
'-c:v libx264 -preset ultrafast -tune zerolatency -g 60 ' .
'-c:a aac -f flv -reconnect 1 -reconnect_at_eof 1 ' .
'-reconnect_streamed 1 -reconnect_delay_max 5 "%s" 2>&1',
escapeshellarg($source),
escapeshellarg($rtmpUrl)
);
exec($cmd, $output, $returnCode);
if ($returnCode !== 0) {
error_log("[ERROR] FFmpeg exited with code {$returnCode}: " . implode("\n", $output));
sleep(3); // 避免密集重启
} else {
break; // 正常退出才跳出
}
}✅ 优势:完全绕过 FFmpeg 对某些 RTSP 服务器重连失效的问题
⚠️ 注意:务必用 escapeshellarg() 防止路径含空格或特殊字符导致命令失败
启用 FFmpeg 原生重连参数(必须配齐)
仅靠 PHP 重启还不够,FFmpeg 层需先尽力自愈。RTMP 推流必须带上这组参数(适用于 librtmp 后端):
立即学习“PHP免费学习笔记(深入)”;
-
-reconnect 1:启用重连总开关 -
-reconnect_at_eof 1:流读到末尾(如摄像头临时断开)时重连 -
-reconnect_streamed 1:对已建立的流也允许重连(防服务器主动踢) -
-reconnect_delay_max 5:最大间隔 5 秒,指数退避,避免刷爆服务端
⚠️ 不要只加
-reconnect 1—— 单独使用在 RTSP 拉流+RTMP 推流链路中大概率无效,必须四者共存。
用 PHP 8 的 pcntl_fork() 或守护进程管理(进阶稳定方案)
若需多路流或长期运行,建议用 pcntl_fork() 派生子进程,主进程负责健康检查(如每 10 秒检测 .ts 文件更新时间或 ps aux | grep ffmpeg 是否存活):
if (pcntl_fork() === 0) {
// 子进程:专注推流
exec("ffmpeg -re ... > /dev/null 2>&1");
exit(0);
} else {
// 父进程:看门狗
while (true) {
$pid = pcntl_wait($status, WNOHANG);
if ($pid > 0) {
error_log("Child FFmpeg died, restarting...");
pcntl_fork(); // 立即补一个
}
sleep(5);
}
}✅ 适合无人值守监控、教育直播等场景
⚠️ 要求 PHP 编译时启用 pcntl 扩展(默认 CLI 模式可用,Web SAPI 如 FPM 不支持)
不复杂但容易忽略。



















