JavaScript YouTube external captions
by JM note
HTML
<style>
.subtitle:hover { background: orange }
.subtitle.current { background: skyblue }
</style>
<iframe id="player" src="https://www.youtube.com/embed/gdZLi9oWNZg?enablejsapi=1" frameborder="0"></iframe>
<div class="subtitle" data-start="41.000" data-end="42.000">0:41 Sing song when I’m walking home</div>
<div class="subtitle" data-start="42.000" data-end="45.000">0:42 Jump up to the top LeBron</div>
<div class="subtitle" data-start="45.000" data-end="47.000">0:45 Ding dong call me on my phone</div>
<div class="subtitle" data-start="47.000" data-end="49.000">0:47 Ice tea and a game of ping pong</div>
<div class="subtitle" data-start="49.000" data-end="50.000">0:49 This is getting heavy</div>
<div class="subtitle" data-start="50.000" data-end="53.000">0:50 Can you hear the bass boom, I’m ready</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
var player;
var timer;
const elements = document.querySelectorAll('.subtitle');
function onYouTubeIframeAPIReady() {
console.log('onYouTubeIframeAPIReady')
player = new YT.Player('player',{events: {'onStateChange': onPlayerStateChange}});
}
function onPlayerStateChange(event) {
console.log('onPlayerStateChange')
if (event.data == YT.PlayerState.PLAYING) timer = setInterval(updateMarkers, 100)
else clearInterval(timer);
}
function updateMarkers() {
const t = player.getCurrentTime();
elements.forEach(function(el, i) {
if (el.dataset.start <= t && t <= el.dataset.end) el.classList.add("current");
else el.classList.remove("current");
});
}
document.onreadystatechange = () => {
if (document.readyState === 'complete') {
elements.forEach(function(el, i) {
el.onclick = function() { player.seekTo(el.dataset.start); }
})
}
};
</script>