PHP触发ffprobe获取直播流元信息需调用已安装的ffprobe命令,加-v quiet -print_format json等参数输出结构化JSON,用shell_exec执行并解析,注意PATH、禁用函数及超时控制。

PHP 本身不直接拉流,它只负责调度、生成地址、调用工具或转发请求;真正拉流的是 FFmpeg、浏览器 video 标签或播放器 SDK。
PHP 怎么触发 ffprobe 获取直播流元信息
想确认 RTMP 或 HLS 流是否在线、码率多少、有没有音轨,得靠 ffprobe。PHP 只是调用它并解析返回的 JSON。
-
ffprobe必须已安装且在系统 PATH 中,否则shell_exec会返回空或报错 “command not found” - 命令要加
-v quiet -print_format json -show_entries等参数控制输出,否则默认文本格式难解析 - 示例命令:
ffprobe -v quiet -print_format json -show_entries format=duration,bit_rate,probe_score -show_entries stream=codec_type,width,height,r_frame_rate -of default=nw=1 http://example.com/live/stream.m3u8 -
shell_exec在 php.ini 中可能被禁用(disable_functions),需检查并临时放开,生产环境建议改用proc_open更安全 - 超时必须控制——直播流卡住时
ffprobe可能挂起几十秒,要用timeout 5s ffprobe ...包一层(Linux)或stream_set_timeout配合proc_open
PHP 如何拼出快手/斗鱼等平台的合法拉流 URL
第三方平台(如快手、斗鱼)的拉流地址不是固定字符串,而是带签名、时效、权限校验的动态 URL,PHP 要按规则生成,错一个字符就 403。
- 快手必须拼
access_token、timestamp(秒级)、nonce(唯一随机串)、所有 query 参数字典序排序后 +app_secret做hash_hmac('sha256', $str, $app_secret) - 斗鱼拉流地址形如
https://hls.douyucdn.cn/live/xxx.flv?expires=...&rt=...&sign=...,其中sign是对rt+流ID+密钥的 MD5,且rt是当前时间戳(单位秒)与过期时间(如 1800)之和 - 漏传
auth_key或sign导致返回空响应或 404,但错误信息不明确,只能靠抓包比对官方网页请求 - PHP 里别手写 URL 拼接,用
http_build_query处理参数,再用urlencode手动补全特殊字段(如快手要求live_id不编码,但其他参数要)
PHP 怎么让前端拿到可用的 HLS/HTTP-FLV 播放地址
Nginx-rtmp 模块开启 hls on 后,实际播放地址不是推流地址,而是 Nginx 生成的 .m3u8 或 .flv 路径,PHP 要把这层映射关系暴露给前端。
立即学习“PHP免费学习笔记(深入)”;
- Nginx 配置里
hls_path /tmp/hls;对应的文件是/tmp/hls/streamkey.m3u8,但不能直接返回这个本地路径,而要配location /hls { alias /tmp/hls; },让前端访问https://your-domain/hls/streamkey.m3u8 - HTTP-FLV 拉流地址是
http://your-domain:8080/live/streamkey.flv,前提是 Nginx-rtmp 开了http_flv on;并监听了 8080(非 80) - PHP 返回给前端的必须是完整可访问 URL,不能含
localhost或内网 IP;Nginx 的server_name和 PHP 的$_SERVER['HTTP_HOST']要一致,否则跨域或 404 - 若用 CDN,PHP 生成的 URL 必须走 CDN 域名,且 Nginx 的
hls_fragment(切片时长)建议设为 2–4 秒,太短易触发频繁 HTTP 请求,太长则首屏延迟高
PHP 为什么不能直接用 file_get_contents 拉 RTMP 流
file_get_contents 只支持 HTTP/HTTPS 协议,RTMP 是二进制 TCP 协议,PHP 原生不支持;强行传 rtmp:// 地址只会返回 false 或警告 “failed to open stream: No such file or directory”。
- 有人误以为加
stream_context_create就能拉 RTMP,其实不行——PHP 没内置 RTMP 协议处理器,allow_url_fopen对 RTMP 无效 - 真要“拉” RTMP,只能用
exec("ffmpeg -i rtmp://... -f flv -")把它转成 HTTP-FLV 再吐给前端,但这是中转,不是直拉 - 更常见做法是:PHP 只管返回地址,前端用
video.js+videojs-contrib-hls(HLS)或flv.js(HTTP-FLV)来拉,它们才是真正的流客户端 - 若硬要在服务端做协议转换,FFmpeg 命令中必须加
-re(模拟实时推流节奏),否则转封装会瞬间读完导致播放器卡住
最容易被忽略的是:Nginx-rtmp 的 hls_cleanup on 默认开启,会自动删旧切片,但如果 PHP 接口查状态时去读 .m3u8 文件内容,可能刚读完就被清掉——得用 stat 先判断文件是否存在,而不是直接 file_get_contents。



















