为什么要这样搞 因为很多视频 不可能 一次传输 需要切片 不然会断流
用nginx 就不会有这个问题 这个是 原生方案
中间件实现
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
/**
* Class StaticFile
* @package app\middleware
*/
class StaticFile implements MiddlewareInterface
{
public function process(Request $request, callable $next): Response
{
$path = ltrim($request->path(), '/');
$file = config('app.public_path') . '/' . $path;
// 不存在文件 → 放行
if (!is_file($file)) {
return $next($request);
}
// 只处理 Range
$range = $request->header('Range');
if (!$range) {
return $next($request);
}
$size = filesize($file);
if (!preg_match('/bytes=(\d+)-(\d*)/', $range, $m)) {
return $next($request);
}
$start = (int)$m[1];
$end = $m[2] !== '' ? (int)$m[2] : $size - 1;
// 限制最大分片
$max = 5 * 1024 * 1024;
$end = min($end, $start + $max - 1, $size - 1);
$fp = fopen($file, 'rb');
fseek($fp, $start);
$body = fread($fp, $end - $start + 1);
fclose($fp);
return response($body, 206, [
'Content-Type' => mime_content_type($file) ?: 'application/octet-stream',
'Accept-Ranges' => 'bytes',
'Content-Range' => "bytes $start-$end/$size",
]);
}
}
配置文件 需要修改
config->static
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Static file settings
*/
return [
'enable' => true,
'middleware' => [// Static file Middleware
app\middleware\StaticFile::class,
],
];
点赞,很合适内部文件存储