Javascript 从文件中单独检索 HTML5 视频时长

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2221029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:18:02  来源:igfitidea点击:

Retrieving HTML5 video duration separately from the file

javascripthtmlvideohtml5-video

提问by drebabels

I am working on building a HTML5 video player with a custom interface, but I am having some problems getting the video duration information to display.

我正在构建一个带有自定义界面的 HTML5 视频播放器,但在显示视频时长信息时遇到了一些问题。

My HTML is simple:

我的 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>

And the javascript I am using to get and insert the duration is

我用来获取和插入持续时间的 javascript 是

var duration = $('#duration').get(0);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;

The problem is nothing happens. I know the video file has the duration data because if I just use the default controls, it displays fine.

问题是什么都没有发生。我知道视频文件有持续时间数据,因为如果我只使用默认控件,它显示正常。

But the real strange thing is if I put alert(duration) in my code like so

但真正奇怪的是,如果我像这样在代码中放入 alert(duration)

alert(duration);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;

then it works fine (minus the annoying alert that pops up). Any ideas what is happening here or how I can fix it?

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

UPDATE: Ok so although I haven't solved this problem exactly, but I did figure out a work around that handles my biggest concern... the user experience.

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

First the video doesn't begin loading until after the viewer hits the play button, so I am assuming that the duration information wasn't available to be pulled (I don't know how to fix this particular issue... although I assume that it would involve just loading the video metadata separately from the video, but I don't even know if that is possible).

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

So to get around the fact that there is no duration data, I decided to hide the duration info (and actually the entire control) completely until you hit play.

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

That said, if anyone knows how to load the video metadata separately from the video file, please share. I think that should completely solve this problem.

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

采纳答案by stopsatgreen

The issue is in WebKit browsers; the video metadata is loaded after the video so is not available when the JS runs. You need to query the readyState attribute; this has a series of values from 0 to 4, letting you know what state the video is in; when the metadata has loaded you'll get a value of 1.

问题出在 WebKit 浏览器中;视频元数据在视频之后加载,因此在 JS 运行时不可用。需要查询readyState属性;这有一系列从 0 到 4 的值,让您知道视频处于什么状态;加载元数据后,您将获得值 1。

So you need to do something like:

因此,您需要执行以下操作:

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);

I haven't tested that code, but it (or something like it) should work.

我还没有测试过那个代码,但它(或类似的东西)应该可以工作。

There's more information about media element attributes on developer.mozilla.org.

developer.mozilla.org上有关于媒体元素属性的更多信息。

回答by Mikushi

Do that:

去做:

var myVideoPlayer = document.getElementById('video_player');
myVideoPlayer.addEventListener('loadedmetadata', function() {
    console.log(myVideoPlayer.duration);
});

Gets triggered when the browser received all the meta data from the video.

当浏览器从视频接收到所有元数据时触发。

[edit] Since then the better approach would be to listen to 'durationchange' instead of 'loadedmetadata' which can be unreliable, as such:

[编辑] 从那时起,更好的方法是收听 'durationchange' 而不是 'loadedmetadata',后者可能不可靠,例如:

myVideoPlayer.addEventListener('durationchange', function() {
    console.log('Duration change', myVideoPlayer.duration);
});

回答by Manifest Interactive

The HTML5 spec does allow for only preloading the metadata:

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

http://www.w3.org/TR/html-markup/video.html#video.attrs.preload

回答by Buhake Sindi

This is the modification to your code

这是对您的代码的修改

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;

Hope this helps.

希望这可以帮助。

It looks like you're using IE, why don't you use document.getElementByIdmethod to retrieve video object?

看起来你在使用IE,你为什么不使用document.getElementById方法来检索视频对象?

回答by Kent Wood

neither listen "loadedmetadata" or "durationchange", video.duration is unreliable.
try load "https://media.w3.org/2018/10/w3c-particles.webm"

既不听“loadedmetadata”或“durationchange”,video.duration 也不可靠。
尝试加载“ https://media.w3.org/2018/10/w3c-particles.webm

there is a smart and effective way.

有一个聪明有效的方法。

//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;
};

回答by Kevin Yan

I encountered the same problem: can not read video's duration , $('video')[0].durationalways return NaN, I referred the accepted answer of @stopsatgreen and change the code to fit in a common case, it really work.

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

The code is very simple and really work, so I post this answer and hope it can help more people.

代码很简单,也很实用,所以贴出这个答案,希望能帮到更多人。