51

我正在构建具有自定义界面的 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;

然后它工作正常(减去弹出的烦人警报)。任何想法这里发生了什么或我如何解决它?

更新:好的,虽然我还没有完全解决这个问题,但我确实想出了一个解决我最大问题的解决方法......用户体验。

首先,视频直到观众点击播放按钮后才开始加载,所以我假设持续时间信息无法被拉取(我不知道如何解决这个特定问题......虽然我假设它只涉及将视频元数据与视频分开加载,但我什至不知道这是否可能)。

因此,为了解决没有持续时间数据的事实,我决定完全隐藏持续时间信息(实际上是整个控件),直到您点击播放。

也就是说,如果有人知道如何将视频元数据与视频文件分开加载,请分享。我认为应该彻底解决这个问题。

4

6 回答 6

166

去做:

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);
});
于 2010-04-08T18:47:39.180 回答
32

问题出在 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上有更多关于媒体元素属性的信息。

于 2010-04-08T18:49:11.777 回答
5

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

于 2015-03-26T05:02:39.587 回答
2

这是对您的代码的修改

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方法来检索视频对象呢?

于 2010-02-08T11:36:55.613 回答
2

既不听“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;
};
于 2019-03-12T09:21:55.327 回答
0

我遇到了同样的问题:无法读取视频的持续时间,$('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);

该代码非常简单并且确实有效,因此我发布此答案并希望它可以帮助更多人。

于 2016-07-07T09:07:14.860 回答