PHP加载外部视频链接至HTML播放器问题求助
解决方案
替换原有PHP代码为以下版本,适配Google Drive这类远程视频流的代理需求:
<?php if($_GET['p']!='123'){ die('Not Found'); } $remoteUrl = "https://drive.google.com/uc?export=preview&id=1ym-pJX8yCMs6Sz1z-bwHuD4MIBwlOmAT"; // 初始化cURL会话 $ch = curl_init($remoteUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自动处理Google Drive的重定向 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 按需关闭SSL验证,部分环境可能需要 $range = ''; $start = 0; $end = 0; $fileSize = 0; $contentType = 'video/mp4'; // 处理HTTP范围请求 if (isset($_SERVER['HTTP_RANGE'])) { list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); if (strpos($range, ',') !== false) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); exit; } list($start, $end) = explode('-', $range); $start = (int)$start; // 若未指定结束位置,先获取文件总大小 if ($end === '') { curl_setopt($ch, CURLOPT_NOBODY, true); curl_exec($ch); $fileSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); $end = $fileSize - 1; } else { $end = (int)$end; } curl_setopt($ch, CURLOPT_RANGE, "bytes=$start-$end"); } else { // 获取远程文件总大小 curl_setopt($ch, CURLOPT_NOBODY, true); curl_exec($ch); $fileSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); $end = $fileSize - 1; } // 重置cURL参数,准备获取内容 curl_setopt($ch, CURLOPT_NOBODY, false); curl_setopt($ch, CURLOPT_HEADER, false); // 捕获远程响应的Content-Type curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($ch, $header) use (&$contentType) { $len = strlen($header); $header = trim($header); if (strpos($header, 'Content-Type:') === 0) { $contentType = trim(substr($header, 13)); } return $len; }); // 执行请求并获取结果 $content = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 输出响应头 header("Content-Type: $contentType"); header("Accept-Ranges: bytes"); if ($httpCode === 206) { header('HTTP/1.1 206 Partial Content'); header("Content-Range: bytes $start-$end/$fileSize"); header("Content-Length: " . ($end - $start + 1)); } else { header("Content-Length: $fileSize"); } // 输出视频内容 echo $content; exit(); ?>
问题根源分析
- 本地文件函数不支持远程URL:原代码中
file_exists()、filesize()仅能处理本地文件,对HTTP/HTTPS链接完全无效,导致代码提前退出,无法执行后续代理逻辑。 fopen()远程流能力有限:即使开启allow_url_fopen,fopen()也无法处理Google Drive的多层重定向,且无法将客户端的Range请求头传递给远程服务器,导致视频拖拽播放功能失效。- 范围请求逻辑不匹配:原代码针对本地文件做
fseek截取,但远程视频需要将Range请求直接转发给源服务器,由源服务器返回指定区间的内容。
额外注意事项
- 确保PHP环境已启用
curl扩展(绝大多数主机默认支持)。 - Google Drive文件需设置为「Anyone with the link can view」权限,否则需要在cURL中添加认证参数。
- 可根据需求添加
CURLOPT_TIMEOUT等参数,避免长视频加载超时。
内容的提问来源于stack exchange,提问作者Sukrat
相关产品推荐
相关产品推荐

