使用 Chrome 在 HTML5 视频中查找

Posted

技术标签:

【中文标题】使用 Chrome 在 HTML5 视频中查找【英文标题】:Seeking in HTML5 video with Chrome 【发布时间】:2016-06-15 13:44:21 【问题描述】:

我在使用 Chrome 搜索视频时遇到问题。

出于某种原因,无论我做什么,video.seekable.end(0) 始终为 0。

当我打电话给video.currentTime = 5,然后是console.log(video.currentTime),我看到它总是0,这似乎重置了视频。

我尝试过基于 MP4 和 VP9 的 webm 格式,但都给出了相同的结果。

更烦人的是 Firefox 可以完美运行一切。 Chrome 有什么特别之处需要我了解吗?

这是我的代码(仅适用于 Firefox):

      <div class="myvideo">
        <video   id="video1" preload="auto">
          <source src="data/video1.webm" type="video/webm"/>
          Your browser does not support videos.
        </video>
      </div>

这是javascript

var videoDiv = $(".myvideo").children().get(0)
videoDiv.load();
  videoDiv.addEventListener("loadeddata", function()
    console.log("loaded");
    console.log(videoDiv.seekable.end(0)); //Why is this always 0 in Chrome, but not Firefox?
    videoDiv.currentTime = 5;
    console.log(videoDiv.currentTime); //Why is this also always 0 in Chrome, but not Firefox?
  );

请注意,简单地调用 videoDiv.play() 实际上确实可以在两种浏览器中正确播放视频。

此外,在电影文件完全加载后,videoDiv.buffered.end(0) 在两个浏览器中也会给出正确的值。

【问题讨论】:

【参考方案1】:

我花了一段时间才弄明白...

问题出在服务器端。我正在使用一个版本的 Jetty 来提供我所有的视频文件。 Jetty的简单配置不支持byte serving。

Firefox 和 Chrome 的区别在于,Firefox 会下载整个视频文件,以便您可以通过它进行搜索,即使服务器不支持http code 206 (partial content)。另一方面,Chrome 拒绝下载整个文件(除非文件非常小,例如 2-3mb 左右)。

因此,要让 html5 视频的 currentTime 参数在 Chrome 中运行,您需要一个支持 http 代码 206 的服务器。

对于遇到此问题的其他人,您可以使用 curl 仔细检查您的服务器配置:

curl -H Range:bytes=16- -I http://localhost:8080/GOPR0001.mp4

这应该返回代码 206。如果它返回 code 200,Chrome 将无法搜索视频,但 Firefox 会,因为浏览器中有解决方法。

最后一个提示:您可以使用 npm http-server 为支持部分内容的本地文件夹获取简单的 http-server:

npm install http-server -g

并运行它以提供本地文件夹:

http-server -p 8000

【讨论】:

我有类似的问题,但仅限于 Mac。 Chrome 拒绝搜索,但 Firefox 可以。我在我的机器上运行一个 http 206 兼容服务器,我可以在网络日志中看到 206 请求。也许我应该为此提出一个关于 SO 的新问题。 您是说我们只需将返回码作为 206 发送,就可以在 Chrome 中使用搜索功能吗? 不,我是说 206 是一种检查是否可以从服务器检索部分内容的方法。如果您正在编写自己的服务器,则必须符合协议。 Chrome 使用此信息无需在流式传输之前下载整个视频。很有效率。 谢谢 Tovi7,请原谅我在这里提出的其他问题。我们有一个处理视频文件的 Jetty 服务器,目前在响应中提供完整的流。当然,就像您的情况一样,搜索功能不起作用。因此,如果我理解正确,即使我一次以部分字节发送流,它也不会根据运行的服务器类型工作?是否有支持字节服务的升级版 Jetty?我的经验很少,所以只想了解一下。 这可能与我在此处针对音频文件的Content-Range 问题有关 - ***.com/questions/53226595/…【参考方案2】:

如果您等待canplaythrough 而不是loadeddata,它会起作用。

见this codepen example。

【讨论】:

我试过这个,我什至不知道这个属性。很好的建议,但不幸的是它并没有解决我的问题。我确实设法解决了这个问题,但结果证明这是一个服务器端问题......我赞成你的答案,因为我学到了一些新东西:-) 您是否已经按照上述方式设置了码头配置,因为使用您的建议对我不起作用【参考方案3】:

如果修改服务器代码不可行,请解决此问题。为您的视频进行 API 调用,然后将 blob 加载到 URL.createObjectURL 并将其输入到视频 html 标记的 src 属性中。这将加载整个文件,然后 chrome 将知道文件的大小,从而允许搜索功能起作用。

 axios.get(`$url`, 
      responseType: "blob"
    )
      .then(function(response) 
        setVideo(URL.createObjectURL(response.data));
      )
      .catch(function(error) 
        // handle error
        console.log(error);
      );

【讨论】:

【参考方案4】:

Video 标签有 3 种可能性:MP4、OGG、WebM。

并非所有格式都适用于所有浏览器。

在这里,我认为 WebM 在 Firefox 中有效,但在 Chrome 中无效,因此您应该为 MP4 和 WebM 文件提供两种替代格式,方法是包含引用 MP4 文件的 2nd Source 标签。

例如src="data/video1.mp4" type="video/mp4"

浏览器会自动选择相关版本。

【讨论】:

正如问题中提到的,我实际上尝试在 chrome 中使用 mp4,它没有任何区别。此外,webm 无法在 Chrome 中运行让我感到惊讶,因为 Google 是整个格式背后的主要驱动力。 对不起 - 你在这两个方面都是对的 - 我应该先阅读这个问题 - 是的,Chrome 当然应该处理 WebM。看起来伊恩德夫林有正确的答案。顺便说一句,我遇到了不是 H264 格式的 MP4 文件的问题...【参考方案5】:

我遇到了类似的问题。我正在监听视频的结束事件并将 currentTime 设置为视频的中间以连续循环播放。它在 Safari 或 Chrome 中不起作用。

我认为 Safari/Chrome 中可能存在一个错误,即播放头位置属性不可用,除非当前正在播放媒体。

我的解决方法是在视频结束之前开始循环,而不是让它真正结束。

尝试通过先开始播放来测试您的功能,然后运行您的功能以查看它是否适用于 Safari Chrome。

【讨论】:

这是一个很好的建议,但不幸的是它对我的特定问题没有帮助。不过谢谢!

以上是关于使用 Chrome 在 HTML5 视频中查找的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 视频大小与海报大小在 Chrome 中是错误的

HTML5 视频自动播放在 chrome 中不起作用

HTML5 视频搜索

HTML5 视频搜索

Chrome浏览器 HTML5看视频卡顿

HTML5 视频标签在移动 Chrome 上的奇怪行为,但适用于 SAFARI