本教程是在ThinkPHP5.0中进行的,如用在其它程序中,作少量修改即可。
/**
* 以文件流输出音频文件
* @author Sindsun
* @date 2018年10月27日22:32:17
* @param $filePath 文件地址
* @param $param 其它参数
* @param $fun 执行一个闭包函数 第一个参数为外部参数
* @output filestream
* @return bool
* */
public function outputStream($filePath,$clientSectionInfo){
if(!file_exists($filePath)){
return false;
}
//返回的文件(流形式)
//对照的完整地址推荐:http://tool.oschina.net/commons/
//header("Content-type: application/octet-stream");
//header("Content-type: audio/mp3");
header("Content-type: audio/mpeg");
header("Age:0");
//按照字节大小返回
//header("Accept-Ranges: bytes");
$fileSize = filesize($filePath);
//$httpRange = $this->request->header('HTTP_RANGE');
$httpRange = $this->request->header('Range');
if(empty($httpRange)){
$httpRange = $this->request->header('HTTP_RANGE');
}
if(!empty($httpRange)){
header("HTTP/1.1 206 Partial Content");
list($name, $range) = explode("=", $httpRange);
list($begin, $end) =explode("-", $range);
if(empty($begin)){
$begin = 0;
}
if(empty($end) || $end == 0){
$end = $fileSize - 1;
}
}else{
$begin = 0;
$end = $fileSize - 1;
}
header("Content-Length: " . ($end - $begin + 1));
//header("Content-Disposition: filename=".basename($filePath));
//header("Content-Disposition: filename=".time().'.mp3');
header("Content-Range: bytes " . $begin . "-" . $end . "/" . $fileSize);
//header("Content-Range:bytes {$begin}-{$end}/{$fileSize}");
header("Vary:Accept-Encoding");
header("Cache-Control:max-age=315360000");
$fobj = fopen($filePath, 'rb');
ob_clean();
flush();
fseek($fobj, $begin);
//设置分流
$buffer = 1024 * 10;
//来个文件字节计数器
$count = 0;
while(!feof($fobj)){
$p = min($buffer,$end - $begin + 1);
$begin += $p;
$data = fread($fobj,$buffer);
//$count += $buffer;//本次请求流量统计
echo $data; //传数据给浏览器端
}
fclose($fobj);
//更新请求次数与
/*$this->dbConObj('tab_client_sections')->where('id',$clientSectionInfo['c_id'])->update([
'request_count' => $clientSectionInfo['request_count']+1,
'traffic_count' => $clientSectionInfo['traffic_count']+$count
]);*/
exit();
//return true;
}