PHP如何集成HLS协议视频播放_PHP集成HLS视频播放方案【指南】

PHP不播放HLS,仅负责生成/代理.m3u8和.ts文件,需严格设置Content-Type、禁用缓存、确保路径同源;代理.ts时用video/MP2T类型及流式输出;动态m3u8须实时更新序列号与时间戳。

PHP本身不处理HLS播放,只负责生成或代理.m3u8和.ts文件

PHP 是服务端脚本语言,无法直接“播放” HLS 视频。所谓“集成 HLS”,实际是指:让 PHP 后端能正确提供 .m3u8 清单文件、按需分发 .ts 片段(或代理转发),并规避常见路径、编码、CORS 问题。浏览器播放器(如 video.jsHls.js)才是真正的 HLS 解析与播放主体。

关键点在于:PHP 不参与解码、切片、加密,只做「路由控制」和「安全分发」。

用 PHP 输出合法 .m3u8 文件时的三个硬性要求

HLS 播放器对 .m3u8 格式极其敏感,PHP 输出稍有偏差就会静默失败(无报错但黑屏)。必须确保:

  • Content-Type 必须是 application/vnd.apple.mpegurl(不是 text/plainapplication/x-mpegURL
  • HTTP 响应头禁止缓存干扰:Cache-Control: no-cachemax-age=0(尤其对动态生成的 live 列表)
  • 所有 .ts 路径必须可被浏览器直接 GET 访问,且协议/域名/端口与 .m3u8 一致(避免跨域)
header('Content-Type: application/vnd.apple.mpegurl');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Origin: *'); // 开发阶段可加,生产建议精确限制
readfile('/path/to/stream.m3u8');

PHP 代理分发 .ts 文件时要绕过 Web 服务器缓存和 MIME 陷阱

如果 .ts 文件不在 Web 根目录下,或需鉴权(如会员视频),就得用 PHP 代理读取并输出。此时极易出错:

  • Web 服务器(Nginx/Apache)可能拦截 .ts 请求并返回 404,需配置规则放行 PHP 路由(如 /play.php?seg=123.ts
  • PHP 输出 .ts 时,Content-Type 必须为 video/MP2T,否则 Hls.js 拒绝加载
  • 大文件用 readfile() 易内存溢出,应配合 fpassthru() + fopen() 流式输出
header('Content-Type: video/MP2T');
header('Content-Length: ' . filesize($ts_path));
$fp = fopen($ts_path, 'rb');
fpassthru($fp);
fclose($fp);

用 PHP 动态生成 m3u8 列表时,时间戳和序列号不能写死

Live 流必须让每个新请求返回更新后的 #EXT-X-SEQUENCE 和最新片段列表,否则播放器认为流已结束。VOD 可静态生成,但 live 场景下 PHP 需实时扫描目录或查数据库:

  • glob('*.ts') 获取最新 N 个文件,按修改时间排序
  • #EXT-X-TARGETDURATION 应取所有 .ts 中最大时长(向上取整)
  • #EXT-X-SEQUENCE 必须严格递增,不可重复;可用 Redis 自增键或文件锁保证并发安全

注意:PHP 生成的 m3u8 若含中文路径或特殊字符,必须用 rawurlencode() 编码片段名,否则 Hls.js 解析失败。

真正卡住人的从来不是 PHP 写几行 echo,而是 m3u8 的换行符(LF)、BOM 头、响应头顺序、.ts 文件权限、CDN 缓存穿透这些细节。调不通时,先用 curl -I 看响应头,再用 VLC 直接打开 m3u8 URL 看是否能载入——别急着改 PHP 逻辑。