iPhone环境下含PHP头的video标签无法正常工作问题排查
解决iOS(iPhone)上视频无法通过PHP脚本播放的问题
我之前也碰到过一模一样的坑!iOS上的浏览器(包括Safari和其他基于WebKit的浏览器)在播放视频时,会发送Range请求来分段加载媒体文件,而你当前的video_url.php脚本只处理了返回完整文件的情况,完全没适配这种分段请求逻辑,这就是导致iPhone无法播放的核心原因。
问题根源拆解
当iOS设备请求视频时,它不会直接要求整个文件,而是先发送带Range: bytes=0-的HTTP头,只请求文件的前一小段来获取视频的编码、时长等元信息,之后再分段请求后续内容。你的脚本直接返回整个文件和200 OK状态码,完全不符合iOS的播放预期,自然就加载失败了。
修复方案:修改video_url.php适配Range请求
把你当前的PHP代码替换成下面这段,它既能处理iOS的分段请求,也能兼容网页端/安卓的完整请求:
<?php $vfn = '/path/vodep.mp4'; // 先检查文件是否存在 if (!file_exists($vfn)) { header("HTTP/1.1 404 Not Found"); exit; } $file_size = filesize($vfn); $mime_type = "video/mp4"; // 处理Range分段请求 if (isset($_SERVER['HTTP_RANGE'])) { list($range_type, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); if ($range_type !== 'bytes') { header("HTTP/1.1 416 Requested Range Not Satisfiable"); header("Content-Range: bytes */$file_size"); exit; } list($start, $end) = explode('-', $range, 2); // 处理起始和结束位置的边界值 $start = (int)$start; $end = $end ? (int)$end : $file_size - 1; if ($start >= $file_size) { header("HTTP/1.1 416 Requested Range Not Satisfiable"); header("Content-Range: bytes */$file_size"); exit; } $end = min($end, $file_size - 1); $length = $end - $start + 1; // 返回206 Partial Content状态码(分段响应) header("HTTP/1.1 206 Partial Content"); header("Content-Type: $mime_type"); header("Content-Length: $length"); header("Content-Range: bytes $start-$end/$file_size"); // 输出对应分段的文件内容 $fp = fopen($vfn, 'rb'); fseek($fp, $start); echo fread($fp, $length); fclose($fp); } else { // 处理普通请求,返回完整文件 header("HTTP/1.1 200 OK"); header("Content-Type: $mime_type"); header("Content-Length: $file_size"); readfile($vfn); } exit; ?>
额外必查项
- 确保你的视频文件是H.264编码+AAC音频的MP4格式,这是iOS原生支持的标准编码组合,如果编码不对,哪怕处理了Range请求也可能无法播放。
- 确认
/path/vodep.mp4的文件路径绝对正确,并且PHP脚本拥有读取该文件的权限。
这样修改后,你的视频应该就能在iPhone上正常播放了!
内容的提问来源于stack exchange,提问作者Waqas
相关产品推荐
相关产品推荐

