Получение длительности видео HTML5 отдельно от файла
Я работаю над созданием видеоплеера 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) следующим образом:
alert(duration);
var vid_duration = Math.round(video.duration);
duration.firstChild.nodeValue = vid_duration;
тогда все работает нормально (без всплывающего предупреждения) Есть идеи, что здесь происходит или как я могу это исправить?
ОБНОВЛЕНИЕ: Хорошо, поэтому, хотя я точно не решил эту проблему, но я нашел способ обойти это, решивший мою самую большую проблему... пользовательский опыт.
Сначала видео не начинает загружаться до тех пор, пока зритель не нажмет кнопку воспроизведения, поэтому я предполагаю, что информация о продолжительности была недоступна для извлечения (я не знаю, как исправить эту конкретную проблему... хотя я предполагаю, что для этого потребуется просто загрузить метаданные видео отдельно от видео, но я даже не знаю, возможно ли это).
Поэтому, чтобы обойти факт отсутствия данных о продолжительности, я решил полностью скрыть информацию о продолжительности (и фактически весь элемент управления) до тех пор, пока вы не нажмете на игру.
Тем не менее, если кто-то знает, как загрузить метаданные видео отдельно от видеофайла, пожалуйста, поделитесь. Я думаю, что это должно полностью решить эту проблему.
Ответы
Ответ 1
Проблема в браузерах 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.
Ответ 2
Сделайте это:
var myVideoPlayer = document.getElementById('video_player');
myVideoPlayer.addEventListener('loadedmetadata', function() {
console.log(myVideoPlayer.duration);
});
Возвращается, когда браузер получил все метаданные из видео.
[edit] С тех пор лучшим подходом будет прослушивание "longchange" вместо "загруженных метаданных", которое может быть ненадежным, как таковое:
myVideoPlayer.addEventListener('durationchange', function() {
console.log('Duration change', myVideoPlayer.duration);
});
Ответ 3
Спецификация 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
Ответ 4
Это модификация вашего кода
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
для извлечения видеообъекта?
Ответ 5
Я столкнулся с одной и той же проблемой: не могу прочитать продолжительность видео, $('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);
Код очень прост и действительно работает, поэтому я публикую этот ответ и надеюсь, что он может помочь большему количеству людей.
Ответ 6
не слушайте ни "загруженные метаданные", ни "длительность", 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;
};