使用PHP fpassthru()加载的Chrome HTML5视频(mp4 / webm),无法设置currentTime?

3

我遇到了一个奇怪的问题。我只在Mac上测试了Chrome和Safari两个浏览器,而在这些浏览器中,问题只会出现在Chrome浏览器中。

我有一个非常基本的HTML5视频元素,它从我的服务器加载视频,用户有几个屏幕按钮来跳转到视频中的特定时间点。

当视频文件被作为直接链接引用时,例如:

<video id="thevideo" width="720" height="480">
  <source type="video/webm" src="videos/vid102.webm" />
  <source type="video/mp4" src="videos/vid102.mp4" />
  <p>Your browser does not support this video.</p>
</video>

...它能够正常运作。

然而,我刚刚设置了视频可以通过PHP fpassthru加载,例如:

<video id="thevideo" width="720" height="480">
  <source type="video/webm" src="getvideo.php?t=webm&v=166" />
  <source type="video/mp4" src="getvideo.php?t=mp4&v=166" />
  <p>Your browser does not support this video.</p>
</video>

其中 getvideo.php 大致如下:

<?php
$videoID = $_REQUEST["v"];
$videoType = $_REQUEST["t"];
$vidPath = "videos/video$vidFile.$videoType";

$fp = fopen($vidPath, 'rb');
header("Content-Type: video/$videoType");
header("Content-Length: " . filesize($vidPath));
fpassthru($fp);

?>

奇怪的事情是:在两个浏览器上,视频都能够正确加载和播放。然而,在Chrome浏览器中,使用fpassthru PHP脚本的版本会破坏设置播放器“currentTime”属性并跳转到视频某个时间点的功能。如果我调用document.getElementById('thevideo').currentTime = 50,它不会跳转到50秒处,而是停留在当前位置。
您有任何想法是什么原因引起的吗?
更新: 我发现这可能与Chrome要求提供“Accept-Ranges”头有关。我已经将头文件“Accept-Ranges: bytes”添加到.php脚本的输出中,并确保Web服务器允许字节范围请求,但仍然不起作用。
1个回答

4
您关于需要“接受范围”标头作为HTTP字节服务的一部分是正确的。我建议阅读类似问题的答案:

Chrome中的Seekbar无法工作

添加响应标头是不够的。您还必须使用“206部分内容”状态代码进行响应,并仅返回请求的字节范围。听起来您仍在返回整个文件。fpassthru将一直读取文件到结尾,因此看起来您需要找到另一种读取文件的方法。

啊哈!这很有道理。如果我实际上没有返回所请求的字节范围,那么告诉客户端我可以返回所请求的字节范围就没有意义了,对吧? :) - DanM
顺便说一下,多亏了你的提示,我找到了以下这个看起来可以解决问题的链接:https://dev59.com/o3VC5IYBdhLWcg3w4VRz - DanM
很高兴它能正常工作。我怀疑使用PHP这样的方式提供文件会有点慢。为什么不使用CDN或专用的文件服务机器,而不是PHP,并在Javascript中动态计算URL呢? - brianchirls
主要是,我不想公开实际文件,并且希望使用相同的URL让不同的用户接收到不同版本的文件。 - DanM
有一些CDN会提供一个过期的密钥,你可以使用“Location”头来动态重定向到CDN的临时URL。 - brianchirls

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接