Skip to content

Instantly share code, notes, and snippets.

@eabase
Created October 12, 2022 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eabase/82cb97e4c8c82fe19f447dd5a1efb4a5 to your computer and use it in GitHub Desktop.
Save eabase/82cb97e4c8c82fe19f447dd5a1efb4a5 to your computer and use it in GitHub Desktop.
One button controls for multiple youtube videos in a 2x3 grid
/* 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;
}
<!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 &copy; EABASE</footer>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment