Created
October 16, 2024 21:16
-
-
Save ilopez/775c8ade7746162e83636a8d779f5d7e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Custom YouTube Video Sync</title> | |
<script src="https://www.youtube.com/iframe_api"></script> | |
<style> | |
/* Styling the headings */ | |
h2, h3 { | |
text-align: center; | |
} | |
/* Container for keeping videos 16:9 aspect ratio */ | |
.video-container, .center-video { | |
position: relative; | |
width: 100%; | |
padding-bottom: 56.25%; /* 16:9 aspect ratio */ | |
height: 0; | |
margin-bottom: 30px; | |
} | |
/* Style for the YouTube iframe to cover 100% of its container */ | |
iframe { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
border: none; | |
} | |
/* Flexbox container for the two side-by-side videos */ | |
.video-pair-container { | |
display: flex; | |
justify-content: space-between; | |
gap: 20px; /* Space between two videos */ | |
} | |
/* Each video in the pair should take up half the container */ | |
.video-wrapper { | |
width: 50%; | |
height: 0; | |
padding-bottom: 28.125%; /* 16:9 aspect ratio */ | |
position: relative; | |
} | |
/* Center dropdowns and buttons */ | |
.dropdown-container { | |
text-align: center; | |
margin: 10px 0; | |
} | |
</style> | |
</head> | |
<body> | |
<!-- Birds Eye View Section --> | |
<h2>Birds Eye View</h2> | |
<div class="center-video"> | |
<iframe id="birdseye" src="https://www.youtube.com/embed/h-WLw713zfk?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe> | |
</div> | |
<!-- Northbound Section --> | |
<h2>Northbound</h2> | |
<div class="dropdown-container"> | |
<label for="northboundLeft">Select Left Video:</label> | |
<select id="northboundLeft"> | |
<option value="719kDFBQtY4,22">Single-level, Fixed-span Steel Girder Bridges, 1 Aux Lane and C St Ramps</option> | |
<option value="tl0YqG80Cls,22">Single-level, Fixed-span Extradosed Bridges, 1 Aux Lane and No C St Ramps</option> | |
<option value="kuvocyMCs-I,34">Double-deck, Fixed-span Truss Bridges, 2 Aux Lanes and C St Ramps</option> | |
</select> | |
<label for="northboundRight">Select Right Video:</label> | |
<select id="northboundRight"> | |
<option value="tl0YqG80Cls,22">Single-level, Fixed-span Extradosed Bridges, 1 Aux Lane and No C St Ramps</option> | |
<option value="719kDFBQtY4,22">Single-level, Fixed-span Steel Girder Bridges, 1 Aux Lane and C St Ramps</option> | |
<option value="kuvocyMCs-I,34">Double-deck, Fixed-span Truss Bridges, 2 Aux Lanes and C St Ramps</option> | |
</select> | |
<button id="northboundPlayButton">Start</button> | |
<button id="northboundPauseButton">Pause/Play</button> | |
<button id="northboundBackwardButton">Back 5s</button> | |
<button id="northboundForwardButton">Forward 5s</button> | |
</div> | |
<div class="video-pair-container"> | |
<div id="northbound-left" class="video-wrapper"> | |
<div id="northbound-left-player"></div> | |
</div> | |
<div id="northbound-right" class="video-wrapper"> | |
<div id="northbound-right-player"></div> | |
</div> | |
</div> | |
<!-- Southbound Section --> | |
<h2>Southbound</h2> | |
<div class="dropdown-container"> | |
<button id="southboundPlayButton">Start</button> | |
<button id="southboundPauseButton">Pause/Play</button> | |
<button id="southboundBackwardButton">Back 5s</button> | |
<button id="southboundForwardButton">Forward 5s</button> | |
</div> | |
<div class="video-pair-container"> | |
<div id="southbound-left" class="video-wrapper"> | |
<div id="southbound-left-player"></div> | |
</div> | |
<div id="southbound-right" class="video-wrapper"> | |
<div id="southbound-right-player"></div> | |
</div> | |
</div> | |
<script> | |
var birdseyePlayer, northboundLeftPlayer, northboundRightPlayer, southboundLeftPlayer, southboundRightPlayer; | |
var northboundLeftStartTime, northboundRightStartTime; | |
// Load YouTube IFrame Player API | |
function onYouTubeIframeAPIReady() { | |
birdseyePlayer = new YT.Player('birdseye', { | |
events: { | |
'onReady': onPlayerReady | |
} | |
}); | |
loadSouthboundVideos(); | |
document.getElementById('northboundPlayButton').addEventListener('click', playNorthboundVideos); | |
document.getElementById('northboundPauseButton').addEventListener('click', pauseNorthboundVideos); | |
document.getElementById('southboundPlayButton').addEventListener('click', playSouthboundVideos); | |
document.getElementById('southboundPauseButton').addEventListener('click', pauseSouthboundVideos); | |
} | |
// Load the Southbound videos and set them to the correct starting time | |
function loadSouthboundVideos() { | |
southboundLeftPlayer = new YT.Player('southbound-left-player', { | |
videoId: 'kydFQ1StQqo', | |
events: { | |
'onReady': function(event) { | |
// Do nothing until user clicks Play | |
} | |
} | |
}); | |
southboundRightPlayer = new YT.Player('southbound-right-player', { | |
videoId: 'gA2hkC5evhQ', | |
events: { | |
'onReady': function(event) { | |
// Do nothing until user clicks Play | |
} | |
} | |
}); | |
} | |
// Play Northbound Videos based on selected dropdown values | |
function playNorthboundVideos() { | |
var leftVideoInfo = document.getElementById('northboundLeft').value.split(','); | |
var rightVideoInfo = document.getElementById('northboundRight').value.split(','); | |
var leftVideoId = leftVideoInfo[0]; | |
var leftStartTime = parseInt(leftVideoInfo[1]); | |
var rightVideoId = rightVideoInfo[0]; | |
var rightStartTime = parseInt(rightVideoInfo[1]); | |
if (northboundLeftPlayer) northboundLeftPlayer.destroy(); | |
if (northboundRightPlayer) northboundRightPlayer.destroy(); | |
northboundLeftPlayer = new YT.Player('northbound-left-player', { | |
videoId: leftVideoId, | |
events: { | |
'onReady': function(event) { | |
event.target.seekTo(leftStartTime); | |
} | |
} | |
}); | |
northboundRightPlayer = new YT.Player('northbound-right-player', { | |
videoId: rightVideoId, | |
events: { | |
'onReady': function(event) { | |
event.target.seekTo(rightStartTime); | |
} | |
} | |
}); | |
setTimeout(function() { | |
northboundLeftPlayer.playVideo(); | |
northboundRightPlayer.playVideo(); | |
}, 500); // Slight delay to ensure both players are ready | |
} | |
var northboundPaused = true; | |
var southboundPaused = true; | |
// Toggle Pause/Resume for Northbound Videos | |
function pauseNorthboundVideos() { | |
if (northboundLeftPlayer && northboundRightPlayer) { | |
if (northboundPaused) { | |
northboundLeftPlayer.playVideo(); | |
northboundRightPlayer.playVideo(); | |
} else { | |
northboundLeftPlayer.pauseVideo(); | |
northboundRightPlayer.pauseVideo(); | |
} | |
northboundPaused = !northboundPaused; | |
} | |
} | |
// Play Southbound Videos | |
function playSouthboundVideos() { | |
if (southboundLeftPlayer) { | |
southboundLeftPlayer.seekTo(23); | |
southboundLeftPlayer.playVideo(); | |
} | |
if (southboundRightPlayer) { | |
southboundRightPlayer.seekTo(23); | |
southboundRightPlayer.playVideo(); | |
} | |
} | |
// Toggle Pause/Resume for Southbound Videos | |
function pauseSouthboundVideos() { | |
if (southboundLeftPlayer && southboundRightPlayer) { | |
if (southboundPaused) { | |
southboundLeftPlayer.playVideo(); | |
southboundRightPlayer.playVideo(); | |
} else { | |
southboundLeftPlayer.pauseVideo(); | |
southboundRightPlayer.pauseVideo(); | |
} | |
southboundPaused = !southboundPaused; | |
} | |
} | |
function onPlayerReady(event) { | |
// You can customize player readiness behavior here if needed | |
} | |
// Seek 5 seconds backward for Northbound Videos | |
document.getElementById('northboundBackwardButton').addEventListener('click', function () { | |
if (northboundLeftPlayer && northboundRightPlayer) { | |
northboundLeftPlayer.seekTo(Math.max(northboundLeftPlayer.getCurrentTime() - 5, 0), true); | |
northboundRightPlayer.seekTo(Math.max(northboundRightPlayer.getCurrentTime() - 5, 0), true); | |
} | |
}); | |
// Seek 5 seconds forward for Northbound Videos | |
document.getElementById('northboundForwardButton').addEventListener('click', function () { | |
if (northboundLeftPlayer && northboundRightPlayer) { | |
northboundLeftPlayer.seekTo(northboundLeftPlayer.getCurrentTime() + 5, true); | |
northboundRightPlayer.seekTo(northboundRightPlayer.getCurrentTime() + 5, true); | |
} | |
}); | |
// Seek 5 seconds backward for Southbound Videos | |
document.getElementById('southboundBackwardButton').addEventListener('click', function () { | |
if (southboundLeftPlayer && southboundRightPlayer) { | |
southboundLeftPlayer.seekTo(Math.max(southboundLeftPlayer.getCurrentTime() - 5, 0), true); | |
southboundRightPlayer.seekTo(Math.max(southboundRightPlayer.getCurrentTime() - 5, 0), true); | |
} | |
}); | |
// Seek 5 seconds forward for Southbound Videos | |
document.getElementById('southboundForwardButton').addEventListener('click', function () { | |
if (southboundLeftPlayer && southboundRightPlayer) { | |
southboundLeftPlayer.seekTo(southboundLeftPlayer.getCurrentTime() + 5, true); | |
southboundRightPlayer.seekTo(southboundRightPlayer.getCurrentTime() + 5, true); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment