2017-01-06 1 views
0

Проблема: у меня есть только один источник видео (mp4), поскольку я пытаюсь добавить пользовательские элементы управления к видео tumblr.Пользовательские элементы управления HTML5 не работают, когда mp4 является единственным источником

Если в качестве источника есть только mp4, возвращается video.duration как NaN.

В качестве теста при использовании 3-х источников (mp4/webm/ogg), то он работает, поэтому video.duration должен быть возвращен только из wemb или ogg.

JSFIDDLE 1 только с одним mp4 в качестве источника (поэтому не работает).

JSFIDDLE 2 с тремя исходными файлами, которые работают.

HTML

<div id="video-container"> 
    <!-- Video --> 
    <video id="video" width="640" height="365" poster="https://68.media.tumblr.com/tumblr_oj7dx3dAJL1vf3pu7_smart1.jpg"> 
     <source src="https://www.tumblr.com/video_file/t:kuWOGAOEWjotDIJeZpO4yw/155341819278/tumblr_oj7dx3dAJL1vf3pu7/480" type="video/mp4"> 
    </video> 
    <!-- Video Controls --> 
    <div id="video-controls"> 
     <button type="button" id="play-pause" class="play">Play</button> 
     <input type="range" id="seek-bar" value="0"> 
     <button type="button" id="mute">Mute</button> 
     <input type="range" id="volume-bar" min="0" max="1" step="0.1" value="1"> 
     <button type="button" id="full-screen">Full-Screen</button> 
    </div> 
</div> 
<span id="currentTime">0</span> 
<span id="duration">0</span> 

JS:

// Video 
    var video = document.getElementById("video"); 
    // Buttons 
    var playButton = document.getElementById("play-pause"); 
    var muteButton = document.getElementById("mute"); 
    var fullScreenButton = document.getElementById("full-screen"); 
    // Sliders 
    var seekBar = document.getElementById("seek-bar"); 
    var volumeBar = document.getElementById("volume-bar"); 

    // Event listener for the play/pause button 
    playButton.addEventListener("click", function() { 
     if (video.paused == true) { 
      // Play the video 
      video.play(); 
      // Update the button text to 'Pause' 
      playButton.innerHTML = "Pause"; 
     } else { 
      // Pause the video 
      video.pause(); 
      // Update the button text to 'Play' 
      playButton.innerHTML = "Play"; 
     } 
    }); 

    ... 

    // Update the seek bar as the video plays 
    video.addEventListener("timeupdate", function() { 
     // Calculate the slider value 
     var value = (100/video.duration) * video.currentTime; 
     // Update the slider value 
     seekBar.value = value; 
    }); 

    ... 

JS в основном взяты из здесь: http://blog.teamtreehouse.com/building-custom-controls-for-html5-videos

То, что я пробовал:

video.addEventListener('loadedmetadata',function(){ 
     console.log(video.duration); //returns NaN 
    }); 

Некоторые JQuery

$(document).ready(function(){ 
    $("#video").on("timeupdate", function(event){ 
     onTrackedVideoFrame(this.currentTime, this.duration); 
    }); 
}); 

function onTrackedVideoFrame(currentTime, duration){ 
    $("#current").text(currentTime); 
    $("#duration").text(duration); 
} 

Еще одна попытка:

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

Также

<video preload="metadata"> 

Ни одно из этих решений, казалось, работали.

Я также посмотрел на это question на SO. У кого есть голосовой ответ, который не проверен.

+0

вам нужно дождаться загрузки метаданных для загрузки видео, чтобы получить значение продолжительности. если ваш JS находится в очереди, он будет срабатывать, как только он будет достигнут.Если вы привяжете его к событию onloaded для видеоэлемента, тогда вы должны быть хорошим – Offbeatmammal

+0

Эта функция 'video.addEventListener ('loadedmetadata', function() {' содержится в 'onload function' (вы можете видеть это в jsfiddle). Это то, что вы имеете в виду? Не стесняйтесь обновлять/разворачивать скрипку, если это помогает. Я стараюсь избегать inline js, где это возможно. – lharby

ответ

1

Для получения продолжительности видео необходимо дождаться загрузки части метаданных видеоисточника (это может значительно различаться в зависимости от того, как было закодировано видеоизображение - в идеале это двухпроходный код, который перемещает атом MOOV к началу используется, чтобы можно было быстро извлечь).

Слушайте событие loadedmetadata на видеообъекте, который ваш код будет знать, когда это безопасно.

В приведенном ниже коде вы увидите, что я регистрирую обработчик событий с помощью встроенного javascript (или может быть в document.onload), который, в свою очередь, вызывает функцию для извлечения продолжительности, когда это значение доступно. Затем должен быть запущен любой код, который должен знать значение.

Я также добавил preload="auto" только для личных предпочтений, так как он помогает предварительно буферизовать содержимое в некоторых браузерах/устройствах, что не обязательно для того, чтобы событие работало в большинстве сценариев.

<video preload="auto" id="video" width="640" height="365" poster="https://68.media.tumblr.com/tumblr_oj7dx3dAJL1vf3pu7_smart1.jpg"> 
    <source src="https://www.tumblr.com/video_file/t:kuWOGAOEWjotDIJeZpO4yw/155341819278/tumblr_oj7dx3dAJL1vf3pu7/480" type="video/mp4"> 
</video> 

<script> 

var vid = document.getElementById("video" 
vid.addEventListener('loadedmetadata', getDuration, false); 

function getDuration() { 
    console.log(vid.duration) 
} 

</script> 
+0

Спасибо. Это работает, я обновил свою скрипку, и теперь нет ошибок. – lharby

Смежные вопросы