Created
October 12, 2022 16:27
-
-
Save eabase/82cb97e4c8c82fe19f447dd5a1efb4a5 to your computer and use it in GitHub Desktop.
One button controls for multiple youtube videos in a 2x3 grid
This file contains 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
/* main.css */ | |
header, footer { | |
font: 14px Arial, sans-serif; | |
padding: 8px; | |
color: white; | |
background-color: black; | |
clear: left; | |
text-align: left; | |
} | |
footer { | |
font-size: 10px; | |
max-width: 1110px; /* width + header padding */ | |
} | |
body { | |
background-color: #404040; | |
color: lightgrey; | |
margin: 0; | |
padding: 1em; | |
/* height: 100vh; */ | |
box-sizing: border-box; | |
} | |
.container { | |
max-width: 1100px; | |
/* width: 100%;*/ | |
border: 1px solid black; | |
padding: 10px; | |
} | |
.mosaic { | |
display: grid; | |
/* Setup a 2x3 grid */ | |
/* Where "fr" is a fractional unit so that "1fr" is for 1 part of the available space. */ | |
grid-template-columns: 1fr 1fr; | |
grid-template-rows: 50% 50% 50%; | |
max-width: 1100px; | |
max-height: 100%; | |
/* margin: auto; */ | |
margin-bottom: 1em; | |
/*padding: 2em; */ | |
gap: 5px; | |
} | |
/*------------------------------------------------------------------------------- | |
# NOTE: YouTube ads don't display if the width of the iframe is less than | |
# 320 pixels, so the iframes are set to be 319px wide. | |
#-------------------------------------------------------------------------------*/ | |
.mosaic.iframe { | |
/* iframe width="560" height="315" */ | |
display: block; | |
width: 100%; | |
height: 100%; | |
aspect-ratio: 16/9; /* */ | |
background: gray; | |
border: 1px solid black; | |
margin: 0px; | |
} | |
/* For the <div id="player-xxxx"> based player */ | |
[id^="player"] { | |
/* iframe width="560" height="315" */ | |
display: block; | |
width: 100%; | |
height: 100%; | |
aspect-ratio: 16/9; | |
background: gray; | |
border: 1px solid black; | |
margin: 0px; | |
} |
This file contains 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> | |
<head> | |
<title>YT Mosaic</title> | |
<link href="main.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div id="container"> | |
<header>YouTube Mosaic</header> | |
<p> xxxx xxxx </p> | |
<button onclick="pause();"> ⏸ </button> | |
<button onclick="play();"> ▶ Play All</button> | |
<button onclick="stop();">⏹ Stop All</button> | |
<button onclick="mute();">🔇</button> | |
<div class="mosaic"> | |
<!-- iframe width="560" height="315" .. --> | |
<!-- iframe id="if1" src="https://www.youtube.com/embed/5mL-OkdM7Tc?cc_load_policy=3&autoplay=0&mute=1&enablejsapi=1" frameborder="0" allowfullscreen></iframe --> | |
<div id="player-5mL-OkdM7Tc"></div> <!-- TRT --> | |
<div id="player-9Auq9mYxFEE"></div> <!-- SKY --> | |
<div id="player-VBTdNwm5CDY"></div> <!-- Global News --> | |
<div id="player-ntmPIzlkcJk"></div> <!-- Euronews --> | |
<div id="player-GE_SfNVNyqk"></div> <!-- DW --> | |
<div id="player-h3MuIUNCCzI"></div> <!-- F24 --> | |
<!-- div id="player-vOTiJkg1voo"></div> --> <!-- ABC News [AU] --> | |
</div> | |
<!-- The Emojis: ▶️ ⏯️ ▶ ⏸ ⏹ 🔇 --> | |
<button onclick="pause();"> ⏸ </button> | |
<button onclick="play();"> ▶ Play All</button> | |
<button onclick="stop();">⏹ Stop All</button> | |
<button onclick="mute();">🔇</button> | |
</div> | |
<script defer> | |
//------------------------------------------------------------------------ | |
// defer = We wait to run script, until entire HTML DOM has been rendered. | |
//------------------------------------------------------------------------ | |
var tag = document.createElement('script'); | |
tag.src = "https://www.youtube.com/iframe_api"; | |
var firstScriptTag = document.getElementsByTagName('script')[0]; | |
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
let playersObjs = []; | |
window.onYouTubeIframeAPIReady = () => { | |
// <div id="player-9Auq9mYxFEE"></div> <!-- SKY --> | |
const playerContainers = document.querySelectorAll('div[id^="player"]'); | |
playerContainers.forEach((container) => { | |
const videoId = container.id.slice(7); | |
// We want the following parameters: | |
// <!-- iframe width="560" height="315" .. --> | |
// <iframe id="if4" src="https://www.youtube.com/embed/ntmPIzlkcJk?cc_load_policy=3&autoplay=0&mute=1&enablejsapi=1" frameborder="0" allowfullscreen></iframe> | |
playersObjs.push(new YT.Player(container.id, { | |
events: { | |
'onReady': onPlayerReady, | |
'onStateChange': onPlayerStateChange, | |
'onError': catchError | |
}, | |
height: '560', | |
width: '315', | |
videoId, | |
playerVars: { | |
'cc_load_policy': 3, | |
'autoplay': 0, | |
'mute': 1, | |
'enablejsapi': 1, | |
//'origin': 'https://www.youtube.com', // should be used when using API (enablejsapi=1) | |
'playsinline': 1, | |
'rel': 0 | |
} | |
})) | |
}) | |
} | |
//--------------------------------------------------------------- | |
// Event Functions | |
//--------------------------------------------------------------- | |
function onPlayerReady(event) { | |
event.target.setVolume(30); // Set Volume | |
//event.target.unMute(); | |
//event.target.mute(); | |
event.target.playVideo(); | |
} | |
var done = false; | |
function onPlayerStateChange(event) { | |
if (event.data == YT.PlayerState.PLAYING && !done) { | |
//setTimeout(stop, 3000); // wait 6 s. before stopping player | |
setTimeout(pause, 3000); // wait 6 s. before stopping player | |
done = true; | |
} | |
} | |
function catchError(event) { | |
if (event.data == 2) console.log("[LOG] Error: The request contains an invalid parameter value."); | |
if (event.data == 100) console.log("[LOG] Error: Video doesn't exists (or has been removed)!"); | |
if (event.data == 101) console.log("[LOG] Error: Not allowed to be played in an embedded player."); | |
if (event.data == 150) console.log("[LOG] Error: Not allowed to be played in an embedded player."); | |
if (event.data == 5) console.log("[LOG] Error: content cannot be played in an HTML5 player."); | |
// This should never happen! | |
console.log("Error:\n", event); | |
//event.target.stopVideo(); | |
} | |
function show_video_url() { | |
var vurl; | |
vurl = player.getVideoUrl(); | |
console.log("Playing YT URL:\n", vurl); | |
// ToDo: Add YT video id to textbox on page | |
} | |
//--------------------------------------------------------------- | |
// Be careful with other variables/functions with these names | |
//--------------------------------------------------------------- | |
const play = () => { | |
playersObjs.forEach((player) => { | |
//show_video_url(); | |
player.playVideo(); | |
//player.setVolume(30); | |
player.mute(); | |
}) | |
} | |
const stop = () => { | |
playersObjs.forEach((player) => { | |
player.stopVideo(); | |
}) | |
} | |
const mute = () => { | |
playersObjs.forEach((player) => { | |
//if (player.isMuted()) { player.unMute(); } else { player.mute(); } | |
player.mute(); | |
}) | |
} | |
var DEBUG = 0; | |
const pause = () => { | |
playersObjs.forEach((player) => { | |
var ps = player.getPlayerState(); | |
var cid = player.g.id; //container.id for the <div id="XX"> | |
if (DEBUG) console.log("[LOG] Pausing cid : ", player.g.id); | |
if (ps == YT.PlayerState.PAUSED) { | |
player.playVideo(); // Resume playing at previous volume | |
document.getElementById(cid).style.opacity = "1"; | |
} | |
if (ps == YT.PlayerState.PLAYING) { | |
player.pauseVideo(); | |
document.getElementById(cid).style.opacity = "0.7"; | |
//player.setVolume(20); | |
//player.playVideo(); | |
} | |
}) | |
} | |
</script> | |
</body> | |
<footer>Copyleft © EABASE</footer> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment