为啥在 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 206
和 Content-Range
和 Content-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 会重置时间?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?
为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?