<!DOCTYPE html> <html> <head> <title>Alt. youtube player</title> <style> /* Adapt to your needs, but it shouldn't be necessary to add much of css as the js-script will handle sizing. */ * {padding: 0;margin: 0;} /* Not necessary when using frameworks */ .player { width: 70vw; margin: 0 auto; } /* Note that the > restricts the img to be on the root level of .player */ .player > img.thumb { width: 100%; } .player > iframe { width: 100%; height: 100%; } .player.play { cursor: pointer; } .player.stop { cursor: not-allowed; } .player.loading { cursor: wait; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> </head> <body> <!-- A player MUST: - Have a class «player» - Have a child element of img - with the class «thumb» - Have a child of the iframe - that has the query-param «enablejsapi=1» --> <div class="player"> <img class="thumb" src="./thumb.png" alt="Thumbnail" /> <iframe src="https://www.youtube-nocookie.com/embed/dcsvMySGmS8?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe> </div> <!-- additional players --> <div class="player"> <img class="thumb" src="./thumb.png" alt="Thumbnail" /> <iframe src="https://www.youtube-nocookie.com/embed/pouODQkJQG0?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe> </div> <div class="player"> <img class="thumb" src="./thumb.png" alt="Thumbnail" /> <iframe src="https://www.youtube-nocookie.com/embed/Y-JQ-RCyPpQ?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe> </div> <div class="player"> <img class="thumb" src="./thumb.png" alt="Thumbnail" /> <iframe src="https://www.youtube-nocookie.com/embed/4-079YIasck?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe> </div> <!-- You need this before the </body>-tag (closing) --> <script> // Hack to load Youtube iframe_api jQuery.getScript("http://www.youtube.com/iframe_api") var ytd = $.Deferred(); window.onYouTubeIframeAPIReady = function () { ytd.resolve(window.YT); }; $(document).ready(function () { // Store all instances of «Youtube Players» var ytp = []; // When a player opens var playerOpen = function (i, player) { if (!ytp[i]) return; // Remove thumb and show iframe player.children('.thumb').slideUp(); player.children('iframe').slideDown({ complete: function () { // When fully opened, plat video and change cursor ytp[i].playVideo() player.removeClass('play loading').addClass('stop'); } }); // Close all the players that might be open. $('.player').each(function (idx) { if (i == idx) return; playerClose(i, $(this)); }) } // When a player is closing var playerClose = function (i, player) { if (!ytp[i]) return; // Stop the video ytp[i].stopVideo(); // Hide iframe and show thumg player.children('iframe').slideUp() player.children('.thumb').slideDown(function() { player.removeClass('stop loading').addClass('play'); }); } // Make sure Iframe has the same size as the thumb-img var adoptThumbSizeToIframe = function (player) { var ytvid = player.children('iframe'); var thumb = player.children('.thumb'); var hidden = thumb.is(':hidden'); // Hack to read size if (hidden) thumb.show(); // Adopt the size of the thumbnail to the iframe ytvid.css({ height: thumb.height(), width: thumb.width(), }); if (hidden) thumb.hide(); } // On scroll, check that we are withing bounding. Close if not. window.addEventListener('scroll', function (e) { var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); var d = $(document).scrollTop(); $('.player').each(function (i) { if ($(this).children('iframe:visible').length == 0) return; // player not open (already showing thumb) var x = $(this).offset()['top']; var xoff = $(this).height() / 15; if ((x + $(this).height() - xoff) < d || (x + xoff) > (d + h)) playerClose(i, $(this)); /* No horizontal test... but... var y = $(this).offset()['left']; var yoff = ($(this).width() / 15); */ }) }) window.addEventListener('resize', function () { $('.player').each(function() { console.log("Resize"); adoptThumbSizeToIframe($(this)); }) }) // Youtube API is reacy ytd.done(function (YT) { /* Initialize player on all of them. Could be optimized and wait with init until the player should start, and destroy it when it's closed. */ $(".player").each(function (i) { var player = $(this).addClass('loading'); var ytvid = player.children('iframe').hide(); adoptThumbSizeToIframe(player); // Generate and add id to the iframe ytvid.attr('id', 'player-' + (i+1)); ytp.push(new YT.Player(ytvid.attr('id'), { events: { 'onReady': function (e) { player.removeClass('loading').addClass('play'); player.bind('click', function () { playerOpen(i, player); }) }, 'onStateChange': function (e) { // Add event specific data here switch (e.data) { case YT.PlayerState.ENDED: playerClose(i, player) break; case YT.PlayerState.PLAYING: // console.log("PLAYING"); break; case YT.PlayerState.PAUSED: player.removeClass('stop loading').addClass('play'); break; case YT.PlayerState.BUFFERING: player.removeClass('stop play').addClass('loading'); break; case YT.PlayerState.CUED: //console.log("CUED"); break; } }, } })); }) }) }); </script> </body> </html>