PHP实现视频断点续播需手动处理HTTP Range请求:响应206状态码,设置Accept-Ranges、Content-Range、Content-Length和Content-Type等关键Header;避免Web服务器或CDN劫持Range响应。

PHP 本身不直接处理视频断点续播
断点续播不是靠 PHP 后端“播放”实现的,而是依赖 HTTP Range 请求 + 前端 标签的原生能力。PHP 的作用仅限于:正确响应字节范围请求(206 Partial Content),并确保文件可被分段读取。如果 PHP 脚本直接输出视频但没处理 Range 头,浏览器就无法拖动、无法续播。
必须用 readfile() 配合 header() 手动处理 Range
不能简单 echo file_get_contents($path) 或重定向到文件路径(比如 header("Location: /videos/xxx.mp4")),那样会丢失 Range 支持。需手动解析 HTTP_RANGE,计算起始/结束偏移,并设置对应 header:
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
if (preg_match('/bytes=(\d+)-(\d+)?/', $range, $matches)) {
$start = (int)$matches[1];
$end = isset($matches[2]) ? (int)$matches[2] : filesize($file) - 1;
$length = $end - $start + 1;
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $start . '-' . $end . '/' . filesize($file));
header('Accept-Ranges: bytes');
header('Content-Length: ' . $length);
header('Content-Type: video/mp4');
$fp = fopen($file, 'rb');
fseek($fp, $start);
fpassthru($fp);
fclose($fp);
exit;
}}
// 没有 Range 请求时,走完整响应
header('Content-Length: ' . filesize($file));
header('Content-Type: video/mp4');
readfile($file);
关键 Header 缺一不可,否则前端视为普通下载
以下 header 必须全部存在且值正确,否则 Chrome/Safari 会禁用进度条、拖动失效、续播失败:
-
Accept-Ranges: bytes— 告诉浏览器“我支持分段” -
Content-Range(仅 206 响应)— 格式必须是bytes 123-456/789,末尾总大小不能错 -
Content-Length— 对应本次响应的字节数(不是整个文件) -
Content-Type— 必须匹配视频实际格式(如video/mp4、video/webm)
漏掉 Accept-Ranges 是最常见错误,会导致前端完全忽略 Range 能力。
本文档主要讲述的是android rtsp流媒体播放介绍;实时流协议(RTSP)是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使实时数据,如音频与视频,的受控、点播成为可能。数据源包括现场数据与存储在剪辑中数据。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、组播UDP与TCP,提供途径,并为选择基于RTP上发送机制提供方法。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
立即学习“PHP免费学习笔记(深入)”;
注意 Nginx/Apache 可能劫持 PHP 的 Range 响应
如果 PHP 脚本返回了正确的 206 和 header,但浏览器仍收到 200 全量响应,大概率是 Web 服务器在中间做了覆盖。例如:
- Nginx 默认对 PHP-FPM 返回的 206 响应自动转为 200,需加
fastcgi_ignore_headers Range;并确认未启用fastcgi_buffering off; - Apache 的
mod_php在某些配置下会清空部分 header,建议用mod_proxy_fcgi替代 - CDN 或反向代理(如 Cloudflare)默认不透传 Range 请求,需显式开启 byte-range 支持
调试时务必用 curl -v -H "Range: bytes=0-999" http://yoursite.com/video.php 直接验证响应状态码和 header,别只看浏览器表现。










