php实现边播边下载
边播边下载的实现原理
边播边下载(也称为流式下载或渐进式下载)的核心是将媒体文件分块传输,客户端在下载部分内容后即可开始播放,同时后台继续下载剩余部分。PHP可通过控制HTTP响应头和数据输出实现这一功能。
设置必要的HTTP头
正确设置HTTP头是边播边下载的关键。需要确保服务器支持范围请求(Range Requests),并正确返回206 Partial Content状态码。

header("Accept-Ranges: bytes");
header("Content-Type: video/mp4"); // 根据实际文件类型调整
处理范围请求
客户端会发送Range头指示需要下载的字节范围。PHP需解析该头并返回对应数据块。
$filePath = 'path/to/video.mp4';
$fileSize = filesize($filePath);
$start = 0;
$end = $fileSize - 1;
if (isset($_SERVER['HTTP_RANGE'])) {
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$start = intval($matches[1]);
$end = isset($matches[2]) ? intval($matches[2]) : $fileSize - 1;
header("HTTP/1.1 206 Partial Content");
header("Content-Range: bytes $start-$end/$fileSize");
} else {
header("Content-Length: " . $fileSize);
}
分块输出文件内容
使用fopen和fseek读取文件的指定部分,避免内存耗尽。

$chunkSize = 1024 * 1024; // 每次读取1MB
$fp = fopen($filePath, 'rb');
fseek($fp, $start);
while (!feof($fp) && ($pos = ftell($fp)) <= $end) {
echo fread($fp, min($chunkSize, $end - $pos + 1));
ob_flush();
flush();
}
fclose($fp);
优化下载性能
对于大文件,可调整$chunkSize平衡内存使用和传输效率。启用Gzip压缩可能影响流式传输,建议禁用。
ini_set('zlib.output_compression', 'Off');
前端播放器配合
HTML5的<video>标签原生支持范围请求。确保视频格式(如MP4)已正确编码。
<video controls>
<source src="stream.php?file=video.mp4" type="video/mp4">
</video>
注意事项
- 文件路径需严格验证,防止目录遍历攻击
- 确保服务器配置允许大文件传输(如
upload_max_filesize和post_max_size) - 对于私有文件,需添加身份验证逻辑
- 考虑使用CDN或专用流媒体服务器处理大规模分发






