为啥在 Chrome 中设置 HTML5 视频元素的 currentTime 会重置时间?

Posted

技术标签:

【中文标题】为啥在 Chrome 中设置 HTML5 视频元素的 currentTime 会重置时间?【英文标题】:Why does setting currentTime of HTML5 video element reset time in Chrome?为什么在 Chrome 中设置 HTML5 视频元素的 currentTime 会重置时间? 【发布时间】:2016-08-15 11:26:05 【问题描述】:

我想在 html5 中设置视频的时间位置。时间应该这样设置:

function settime()
    var video = document.getElementById("video1");
    console.log(video.currentTime); //----->output for example 15.3
    video.currentTime = 10.0;
    console.log(video.currentTime);//----->>output always 0

视频是这样嵌入的:

<button onclick="settime();">Set Time</button>
<div class="container">
<video id="video1" class="video-js vjs-default-skin" muted>
     <source src="video.m4v" type="video/mp4" />
     HTML5 Video is required for this example.
</video>

但由于某种原因,这总是在 Chrome 中将 currentTime 重置为 0。

为什么在设置 currentTime 时会重置时间?以及如何正确设置 currentTime?

【问题讨论】:

视频本身是否在视觉上也可以重新开始,还是只是 console.log 显示为 0? 是的,任何想法为什么以及我做错了什么? sn-p 对我来说似乎是正确的 - 设置 currentTime 也是异步的,但在这里应该无关紧要(因为视频会在视觉上重置)。该问题可能与此处未显示的其他部分有关。您是否有可能设置一个可以重现问题的小提琴/内联 sn-p? 我发现上面的代码在 Firefox 中有效。 Chrome 中有什么我可能需要做的不同的事情吗? 你能用其他文件重现这个吗? 【参考方案1】:

应该是

var video = document.getElementById("video1");

如你所愿

<video id="video1" class="video-js vjs-default-skin" muted>

【讨论】:

虽然你的回答确实指出了代码中的问题,但并没有回答问题的主要问题。 @IdrisDopicoPeña:不过,这是一个真正的错误,所以我认为否决这个答案是不公平的。只编辑问题会更有建设性。 @MichaelScheper - 我只给出了我的反馈,我没有否决这个答案:)。即便如此,他只提到了修复(阅读:刚刚给出了答案),而不是提供所需的反馈。【参考方案2】:

终于找到答案了! Chrome 要求您将 currentTime 设置为字符串,而不是数字。

function settime() 
    var video = document.getElementById("video1");
    console.log(video.currentTime); // output 0
    video.currentTime = 10.0;
    console.log(video.currentTime); // output 0 for some chrome users or 10 for firefox and others
    video.currentTime = "10.0";
    console.log(video.currentTime); // output 10


settime();
<audio id="video1" src="https://sample-videos.com/audio/mp3/crowd-cheering.mp3" controls></audio>
<div>Click play to start the audio at 10 s.</div>

【讨论】:

在我当前版本的 Chrome (73.0.3683.75) 中绝对不是这种情况 也许他们现在已经修复了它,但它在我的旧版 Chrome 中确实可以正常运行。我应该记下我当时使用的版本。 不幸的是,这并没有解决我在 Chrome 80.0.3987.162(Mint 下的 64 位)下的问题。不过,如果是这样的话,我会去最近的 Google 办公室向他们吹树莓派。 Version 90.0.4430.212 (Official Build) (64-bit) Win10 -- 在这里使用字符串仍然不起作用。 哈哈哈这很有趣..我的打字稿不允许我将字符串设置为数字属性:D ...【参考方案3】:

您似乎在使用video.js。如果有,通过VideoJsPlayer.currentTime()方法获取并设置currentTime。

例如:

const player = videojs(document.getElementById("video1"));

// read currentTime
console.log(player.currentTime());

//set currentTime
player.currentTime(10.0);

// read currentTime
console.log(player.currentTime());

【讨论】:

【参考方案4】:

这是 Chrome 中的 bug,显然只发生在“某些”视频中。类似的错误报告过去已经提交并关闭了很多次,所以我建议我们密切关注它,这样在问题真正解决之前它不会再次关闭。

【讨论】:

绝对典型的 Google 开发人员反应“[插入晦涩的原因],所以你们都应该做 [插入烦人的和特定案例的操作]”。几乎立即设置为 wontfix。【参考方案5】:

在我的情况下,我必须更新视频服务服务器以返回带有 Status Code 206Content-RangeContent-Length 标头的响应

【讨论】:

【参考方案6】:

我遇到了同样的问题。这是底线发生的事情。

    如果你是在集成开发环境中写代码,那么直接从IDE服务器以外的硬盘打开你的HTML文件——我遇到过这种情况,服务器没有让你在视频播放过程中设置任意时间。李> 您可以检查浏览器是否可以执行此操作 警报(“开始:”+ player.seekable.start(0)+“结束:”+ player.seekable.end(0)); player.seekable 返回一个 TimeRanges 对象: 定义和使用 seekable 属性返回一个 TimeRanges 对象。 TimeRanges 对象表示可供用户搜索的音频/视频范围。 可搜索范围是用户可以搜索(移动播放位置)到的音频/视频的时间范围。 对于非流式视频,甚至在视频被缓冲之前,通常都可以在视频中的任何位置寻找。 注意:此属性是只读的。 www.w3schools.com article

【讨论】:

【参考方案7】:

这在很多情况下是由服务器没有回复Accept-Ranges 标头引起的。出于一个模糊的、仅与 Google 开发人员相关的原因(FF 人员似乎并没有对没有 Accept-Ranges 标头的服务器回复感到如此冒犯),当没有提供这样的标头时,他们拒绝执行搜索。通过使用 nginx 代理并添加 proxy_force_ranges on;(服务器或位置都可以),您可以非常轻松地添加一个(至少用于测试)。

【讨论】:

谢谢。这解决了我的情况并且完全有意义。 为这个答案添加更多细节:响应视频时没有缺少 Accept-Ranges 标头,响应 HTML 文件时缺少它,因为那时客户端知道服务器支持范围请求 在发出视频请求之前。【参考方案8】:

我的解决方案是首先从我的服务器发送以下标头:

Accept-Ranges: none,
Content-Length: 123456,
Content-Type: audio/mpeg

然后使用MediaSource 对象:

const mediaSource = new MediaSource();
audio.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen,  once: true );

function sourceOpen() 
    URL.revokeObjectURL(audio.src);
    const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');

    fetch('https://example.com/audio.mp3')
    .then(response => response.arrayBuffer())
    .then(data => 
        sourceBuffer.appendBuffer(data);
    )
    .catch(error => 
        console.log(error);
    );

这将强制浏览器下载整个文件,根据您的使用情况,这可能是不可取的。

【讨论】:

【参考方案9】:

它可能已经得到解决,但这是一个 Chrome“错误”,他们可以像 FF 一样修复,但我猜是#wontfix。这是一个服务器端修复,因此您需要查看确保正确传递标头。

这太浪费了,但是通过将 Accept-Ranges 设置为 bytes(确保还包括内容长度和 mime 类型),每次从字节零放大时,它都会尝试重新下载文件去你着陆的地方——所以它可以让你四处跳跃,但代价是巨大的。

    header('Accept-Ranges: bytes');

我建议您通读这个问题的答案,并尝试一直正确地设置范围,以免浪费太多带宽:

Resumable downloads when using php to send the file?

另外,更多参考:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#range_requests

【讨论】:

【参考方案10】:

您可以添加preload="auto",浏览器会尽快尝试下载文件。

https://developer.mozilla.org/en-US/docs/Web/Guide/Audio_and_video_delivery/Cross-browser_audio_basics

为我工作。

【讨论】:

以上是关于为啥在 Chrome 中设置 HTML5 视频元素的 currentTime 会重置时间?的主要内容,如果未能解决你的问题,请参考以下文章

在 HTML5 中设置视频高度

在 HTML5 视频中设置 currentTime 问题

为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?

为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?

如何在 chrome 媒体控制菜单和 Windows 媒体控制对话框中设置 HTML 音频或视频缩略图和标题

无法在 Chrome 中设置 type="time" 的输入元素的初始值