php 实现边播边下载
实现边播边下载的PHP方案
在PHP中实现边播边下载功能,通常需要结合流媒体技术和文件分块处理。以下是实现该功能的几种方法:

使用HTTP范围请求(Range Requests)
通过处理HTTP Range头实现部分内容传输,浏览器或播放器可以请求文件的特定部分:

$filePath = '/path/to/video.mp4';
$fileSize = filesize($filePath);
$chunkSize = 1024 * 1024; // 1MB chunks
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]) : $start + $chunkSize;
$length = min($end - $start + 1, $fileSize - $start);
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$fileSize");
header("Content-Length: $length");
$file = fopen($filePath, 'rb');
fseek($file, $start);
echo fread($file, $length);
fclose($file);
} else {
header("Content-Length: $fileSize");
readfile($filePath);
}
分块传输编码
使用分块传输编码逐步发送文件内容:
$filePath = '/path/to/video.mp4';
$chunkSize = 8192; // 8KB chunks
header('Content-Type: video/mp4');
$file = fopen($filePath, 'rb');
while (!feof($file)) {
echo fread($file, $chunkSize);
ob_flush();
flush();
usleep(10000); // 微秒延迟控制速度
}
fclose($file);
结合数据库记录下载进度
对于需要记录下载进度的场景:
// 记录下载进度
$userId = $_SESSION['user_id'];
$fileId = 'video123';
$downloadedBytes = getDownloadProgress($userId, $fileId);
// 处理范围请求时从$downloadedBytes开始
if ($downloadedBytes > 0) {
header("Content-Range: bytes $downloadedBytes-");
// ...其余范围请求处理代码
}
// 下载完成后更新进度
updateDownloadProgress($userId, $fileId, $newBytes);
注意事项
- 确保服务器支持HTTP范围请求
- 大文件处理时注意内存使用,避免一次性读取整个文件
- 对于MP4等格式,需要确保文件元信息(moov atom)位于文件开头
- 考虑添加安全验证防止未授权访问
性能优化建议
- 使用X-Sendfile或X-Accel-Redirect让web服务器直接处理文件传输
- 对静态文件配置正确的缓存头减少服务器负载
- 考虑使用CDN分发大媒体文件
- 实现断点续传功能提升用户体验
以上方法可以根据具体需求组合使用,实现高效的边播边下载功能。






