更新:好的,虽然我没有完全解决这个问题,但我确实找到了解决这个问题的工作,处理了我最关心的问题......用户体验。
首先视频没有开始加载,直到观众点击播放按钮,所以我假设持续时间信息不可用(我不知道如何解决这个特定问题...虽然我假设它只涉及将视频元数据与视频分开加载,但我甚至不知道这是否可行)。
因此,为了解决没有持续时间数据的事实,我决定完全隐藏持续时间信息(实际上是整个控件),直到你点击播放。
我知道......它的作弊。但是现在它让我开心:)
那说...如果有人知道如何从视频文件中分别加载视频元数据...请分享。我认为应该彻底解决这个问题。
我正在开发一个带有自定义界面的HTML5视频播放器,但是我在显示视频持续时间信息方面遇到了一些问题。
我的HTML非常简单(见下文)
<video id="video" poster="image.jpg" controls>
<source src="video_path.mp4" type="video/mp4" />
<source src="video_path.ogv" type="video/ogg" />
</video>
<ul class="controls">
<li class="time"><p><span id="timer">0</span> of <span id="duration">0</span></p></li>
</ul>
我用来获取和插入持续时间的javascript是
var duration = $('#duration').get(0);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;
问题是没有任何反应。我知道视频文件有持续时间数据,因为如果我只使用默认控件,它显示正常。
但真正奇怪的是,如果我将警报(持续时间)放在我的代码中,就像这样
alert(duration);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;
然后工作正常(减去弹出的烦人警报)。任何想法在这里发生了什么或我如何解决它?
问题出在WebKit浏览器中;视频元数据在视频之后加载,因此在JS运行时不可用。您需要查询readyState属性;它有一系列从0到4的值,让你知道视频的状态;加载元数据后,您将获得值1。
所以你需要做类似的事情:
window.setInterval(function(t){
if (video.readyState > 0) {
var duration = $('#duration').get(0);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;
clearInterval(t);
}
},500);
我没有测试过那段代码,但它(或类似的东西)应该可以工作。
有关developer.mozilla.org上媒体元素属性的更多信息。
去做:
var myVideoPlayer = document.getElementById('video_player');
myVideoPlayer.addEventListener('loadedmetadata', function() {
console.log(myVideoPlayer.duration);
});
当浏览器从视频接收到所有元数据时触发。
[编辑]从那时起,更好的方法是收听'durationchange'而不是'loadedmetadata',这可能是不可靠的,因此:
myVideoPlayer.addEventListener('durationchange', function() {
console.log('Duration change', myVideoPlayer.duration);
});
这是对代码的修改
var duration = document.getElementById("duration");
var vid_duration = Math.round(document.getElementById("video").duration);
//alert(vid_duration);
duration.innerHTML = vid_duration;
//duration.firstChild.nodeValue = vid_duration;
希望这可以帮助。
看起来你正在使用IE,你为什么不使用document.getElementById
方法来检索视频对象?
HTML5规范只允许预加载元数据:
<video id="video" poster="image.jpg" controls preload="metadata">
<source src="video_path.mp4" type="video/mp4" />
<source src="video_path.ogv" type="video/ogg" />
</video>
http://www.w3.org/TR/html-markup/video.html#video.attrs.preload
我遇到了同样的问题:无法读取视频的持续时间,$('video')[0].duration
总是返回NaN
,我提到@stopsatgreen接受的答案并更改代码以适应常见情况,它确实有效。
var video = $('video')[0];
var t = setInterval(function () {
if(video.readyState > 0) {
var duration = video.duration;
console.log(duration);
clearInterval(t);
}
}, 500);
代码非常简单,真的有用,所以我发布这个答案,希望它可以帮助更多的人。
既不听“loadedmetadata”或“durationchange”,video.duration也不可靠。 尝试加载“https://media.w3.org/2018/10/w3c-particles.webm”
有一种聪明有效的方法。
//first, seek to a big number time
video.currentTime = 7*24*60*1000;
//then listen 'seeked' event. when this event occur, that means video duration can access normally
video.onseeked = ()=>{
alert("the duration is: "+video.duration);
video.onseeked = undefined;
};