无法中断基于PHP SDK的AWS S3视频流传输,求解决方案
私有AWS S3存储桶MP4视频流式传输问题及解决方案建议
已通过PHP实现从私有AWS S3存储桶流式传输MP4视频,参考了S3视频流传输及AWS PHP SDK流包装器相关文档。
实现代码
S3视频流传输PHP代码
$path = 's3://' . $bucket . '/' . $fullFileName; $this->s3Client->registerStreamWrapper(); if ($stream = fopen('s3://' . $bucket . '/' . $fullFileName, 'r')) { while (!feof($stream)) { echo fread($stream, 1024); } fclose($stream); }
支持视频跳转的响应头设置
header("Content-Type: video/mp4"); header('Accept-Ranges: bytes'); header("Content-Disposition: inline;"); header("Content-Transfer-Encoding: binary\n"); header('Connection: close');
遇到的问题
功能运行正常,但在Chrome浏览器中,启动视频播放后点击普通HTML超链接,视频仍会继续播放一段随机时长(新请求处于pending状态时视频持续播放)。
HTML5 video标签代码
<video width="100%" controls preload="metadata" controlsList="nodownload"> <source src="/view-resource/1234" type="video/mp4"> </video>
已尝试的方案
猜测PHP流函数会持续运行至文件结束,尝试在循环中加入connection_aborted()判断,并设置ignore_user_abort(false),但问题仍未解决。
解决方案建议
- 强制刷新输出缓冲区:每次输出数据后立即刷新缓冲区,让PHP更快检测连接中断。修改循环代码:
while (!feof($stream) && !connection_aborted()) { echo fread($stream, 1024); ob_flush(); flush(); }
完整实现HTTP范围请求:当前仅声明支持范围请求,未实际处理客户端发送的
Range头。HTML5播放器依赖范围请求加载片段内容,实现该功能后,播放器能更精准控制数据流,连接中断时可及时终止请求。需要解析$_SERVER['HTTP_RANGE'],从S3对应位置读取数据,返回206 Partial Content状态码及Content-Range头。替换为S3预签名URL:无需PHP代理,直接生成带过期时间的S3预签名URL给客户端。连接中断时S3会直接停止传输,避免PHP进程持续运行,同时保证资源私有性。
优化连接状态检测频率:减小每次读取的字节数(如512字节),或在循环中定期调用
connection_status(),更及时发现连接中断。合理设置PHP执行参数:脚本开头设置
set_time_limit(0)以适应长视频传输,但结合connection_aborted()检测,避免进程无限制运行。
内容的提问来源于stack exchange,提问作者Enigma Plus
相关产品推荐
相关产品推荐

