Last active
February 14, 2022 17:50
-
-
Save iamrobert/0928d36d093fc441db15f707f18e497e to your computer and use it in GitHub Desktop.
FIX PLYR.JS | Play on IOS + Fast Loading
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
//FIX PLYR AUTOPLAY ON IOS & FAST LOADING: | |
var app = {}; | |
/* + GET JS | |
-------------------------------------------------------------------------- | |
https://gist.github.com/iamrobert/a8907c30a66961340d2dd4cd53493ba9 | |
==========================================================================*/ | |
var getJS = function getJS(url) { | |
return new Promise(function (resolve, reject) { | |
let http = new XMLHttpRequest(); | |
http.addEventListener("load", function (event) { | |
loadComplete(event, resolve); | |
}); | |
http.addEventListener("error", function (event) { | |
loadFailed(event, reject); | |
}); | |
http.addEventListener("abort", function (event) { | |
loadCanceled(event, reject); | |
}); | |
http.open('GET', url, true); | |
http.setRequestHeader("Cache-Control", "public"); | |
http.send(null); | |
function loadComplete(evt, resolve) { | |
let script = document.createElement("script"); | |
script.innerHTML = evt.target.response; | |
document.head.appendChild(script); | |
resolve(); | |
} | |
function loadFailed(evt, reject) { | |
reject(); | |
} | |
function loadCanceled(evt, reject) { | |
reject(); | |
} | |
}); | |
}; | |
/* + GET CSS | |
======================================================================*/ | |
function getCSS(path) { | |
// console.log('Requesting ' + path + '... in progress'); | |
if (document.createStyleSheet) { | |
try { | |
// console.log('Loading ' + path + '... in progress'); | |
document.createStyleSheet(path); | |
} catch (e) { | |
// console.error('Failed dynamically loading stylesheet.'); | |
} | |
} else { | |
var css; | |
css = document.createElement('link'); | |
css.rel = 'stylesheet'; | |
// css.type = 'text/css'; | |
css.media = 'all'; | |
css.href = path; | |
document.getElementsByTagName('head')[0].appendChild(css); | |
// console.log('Appending ' + path + ' to document head... success'); | |
} | |
} | |
/* | |
* ======================================================================= | |
+ NORMAL VIDEO PLAYER | |
* ======================================================================= | |
*/ | |
app.videoPlayer = { | |
init: function () { | |
if (!document.querySelector(".js-player")) { | |
// console.log('no-plyr'); | |
return; | |
} else { | |
// app.videoPlayer.deferVideos(); | |
app.videoPlayer.YTPreConnect(); | |
app.videoPlayer.startPlyr(); | |
} | |
}, | |
YTPreConnect: function () { | |
//PRECONNECT TO YOUTUBE IMAGES | |
var linkTag = document.createElement("link"); | |
linkTag.rel = "preconnect"; | |
linkTag.href = "https://img.youtube.com"; | |
//inject tag in the head of the document | |
document.head.appendChild(linkTag); | |
}, | |
loadJSCSS: function () { | |
getCSS('css/plyr/plyr.css'); | |
getJS('js/vendor/plyr.js'); | |
}, | |
startPlyr: function () { | |
var players = []; | |
var YouTubeContainers = document.querySelectorAll(".js-player"); | |
// Iterate over every YouTube container you may have | |
var loopYT = function loopYT() { | |
var container = YouTubeContainers[i]; | |
//GET YT Thumbnail Image + Video Title | |
var viewportWidth = window.innerWidth || document.documentElement.clientWidth; | |
// console.log(viewportWidth); | |
if (viewportWidth > 640) { | |
var imageSource = "https://img.youtube.com/vi_webp/" + container.dataset.plyrEmbedId + "/maxresdefault.webp"; | |
} else { | |
var imageSource = "https://img.youtube.com/vi_webp/" + container.dataset.plyrEmbedId + "/mqdefault.webp"; | |
} | |
var ytUrl = "https://www.youtube.com/watch?v=" + container.dataset.plyrEmbedId + ""; | |
// Load the Thumbnail Image asynchronously | |
var image = new Image(); | |
image.src = imageSource; | |
// alt image | |
fetch("https://noembed.com/embed?dataType=json&url=" + ytUrl) | |
.then(function (res) { | |
return res.json(); | |
}) | |
.then(function (data) { | |
return (image.alt = data.title); | |
}); | |
// image attributes | |
image.width = "480"; | |
image.height = "360"; | |
// image.loading = 'lazy' | |
image.addEventListener("load", function () { | |
container.appendChild(image); | |
}); | |
/* Edit by HH */ | |
//checking IOS Devices | |
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; | |
//if IOS | |
if (isIOS) { | |
getCSS('css/plyr/plyr.css'); | |
getJS('js/vendor/plyr.js') | |
.then(function () { | |
const imageObserver = new IntersectionObserver((entries, imgObserver) => { | |
entries.forEach((entry) => { | |
if (entry.isIntersecting) { | |
var plyr = container.getAttribute("data-plyr-embed-id"); // | |
plyr = ".js-player[data-plyr-embed-id=" + plyr + "]"; | |
var player = new Plyr(plyr, { | |
youtube: { | |
//SEE YOUTUBE API: https://developers.google.com/youtube/player_parameters#Parameters | |
origin: window.location.host + '/', | |
iv_load_policy: 3, | |
modestbranding: 1, | |
playsinline: 1, | |
showinfo: 0, | |
rel: 0, | |
enablejsapi: 1, | |
noCookie: true, | |
autoplay: 0 | |
} | |
}); | |
} | |
}) | |
}); | |
const arr = document.querySelectorAll('.js-player') | |
arr.forEach((v) => { | |
imageObserver.observe(v); | |
}) | |
console.log('This is a IOS device'); | |
}); | |
} else { //if not IOS | |
console.log('This is Not a IOS device'); | |
//LOAD PLYR ON CLICK | |
// When the user clicks on the container, load the embedded YouTube video | |
container.addEventListener("click", function () { | |
getCSS('css/plyr/plyr.css'); | |
getJS('js/vendor/plyr.js') | |
.then(function () { | |
var plyr = container.getAttribute("data-plyr-embed-id"); // | |
plyr = ".js-player[data-plyr-embed-id=" + plyr + "]"; | |
var player = new Plyr(plyr, { | |
youtube: { | |
//SEE YOUTUBE API: https://developers.google.com/youtube/player_parameters#Parameters | |
origin: window.location.host + '/', | |
iv_load_policy: 3, | |
modestbranding: 1, | |
playsinline: 1, | |
showinfo: 0, | |
rel: 0, | |
enablejsapi: 1, | |
noCookie: true | |
} | |
}); | |
player.on("ready", function () { | |
player.play(); | |
}); // Attach Play Event | |
player.on("play", function () { | |
players.forEach(function (playerElement) { | |
if (playerElement !== player && playerElement.playing) { | |
playerElement.pause(); | |
} | |
}); | |
}); | |
// Save Player Instance | |
players.push(player); | |
// STOP Other Players | |
players.forEach(function (player) { | |
player.on("play", function () { | |
player.elements.container.classList.add("player-expand"); | |
players.forEach(function (otherPlayer) { | |
if (otherPlayer !== player && otherPlayer.playing) { | |
otherPlayer.pause(); | |
} | |
}); | |
/** | |
* Pause when opening Lightbox | |
*/ | |
var lightboxLinks = document.querySelectorAll("[class^='glightbox']"); | |
for (var i = 0; i < lightboxLinks.length; i++) { | |
lightboxLinks[i].addEventListener("click", function () { | |
player.pause(); | |
}); | |
} // player.toggleControls('progress'); | |
}); | |
player.on("pause", function () { | |
if (!player.seeking) { | |
player.elements.container.classList.remove("player-expand"); | |
} | |
}); | |
}); | |
}); | |
}); | |
} | |
}; | |
for (var i = 0; i < YouTubeContainers.length; i++) { | |
var ytUrl; | |
loopYT(); | |
} | |
} | |
} | |
app.videoPlayer.init(); | |
/* | |
* ======================================================================= | |
+ LIGHTBOX VIDEO PLAYER | |
* ======================================================================= | |
*/ | |
var lightbox = null; | |
app.lightBox = { | |
init: function () { | |
if (!document.querySelectorAll("[class^='glightbox']")[0]) { | |
return; | |
} else { | |
app.lightBox.fireOnEachImageScroll(); | |
if (document.querySelector('.masonry__item')) { | |
BackgroundCheck.init({ | |
targets: '.masonry__item a', | |
threshold: 70, | |
}); | |
} | |
} | |
}, | |
start: function () { | |
getCSS('css/glightbox.css'); | |
getJS('js/vendor/glightbox-responsive-dist.js') | |
.then(function () { | |
//DEFAULT LIGHTBOX | |
var lightbox = GLightbox({ | |
touchNavigation: true, | |
loop: true, | |
autoplayVideos: true, | |
width: '90vw', | |
height: '90vh', | |
videosWidth: '100vw', | |
plyr: { | |
css: 'css/plyr/plyr.css', | |
js: 'js/vendor/plyr.js', | |
config: { | |
// muted: true, | |
fullscreen: { | |
enabled: true, | |
fallback: true, | |
iosNative: true | |
}, | |
youtube: { | |
//SEE YOUTUBE API: https://developers.google.com/youtube/player_parameters#Parameters | |
origin: window.location.host + '/', | |
iv_load_policy: 3, | |
modestbranding: 1, | |
playsinline: 1, | |
showinfo: 0, | |
rel: 0, | |
enablejsapi: 1, | |
noCookie: true, | |
}, | |
} | |
} | |
}); | |
//PRODUCT INLINE | |
var lightboxInlineIframe = GLightbox({ | |
selector: '.glightbox4' | |
}); | |
}); | |
}, | |
fireOnEachImageScroll: function () { | |
// 1. We have multiple targets - so fire glightbox script once with var fired | |
var images = Array.from(document.querySelectorAll("[class^='glightbox']")); | |
var fired = false; | |
if ("IntersectionObserver" in window) { | |
var imageObserver = new IntersectionObserver(function (entries, observer) { | |
entries.forEach(function (entry) { | |
if (entry.isIntersecting) { | |
var image = entry.target; | |
if (fired == false) { | |
app.lightBox.start(); | |
fired = true; | |
} | |
imageObserver.unobserve(image); | |
} | |
}); | |
}); | |
images.forEach(function (img) { | |
return imageObserver.observe(img); | |
}); | |
} | |
}, | |
} | |
app.lightBox.init(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment