// ==UserScript==
// @name Lazy Embedded Video
// @namespace [email protected]
// @description Lazy load embedded videos from Youtube/Dailymotion/Vimeo/Rutube/Twitch/Ustream
// @version 1.3
// @grant none
// ==/UserScript==
(function() {
if(!document.getElementById("zeusCSP")) {
var script = document.createElement('SCRIPT');
script.id = "zeusCSP";
script.text = "CSP_AllowInlineScript = true;";
document.head.appendChild(script);
}
if(!CSP_AllowInlineScript) return;
var createHtml = function(url, iframe, api, background_img) {
/(https?:\/\/w*\.?([^.]+)[^\/]+)/.test(url);
var provider_url = RegExp.$1, provider_name = RegExp.$2, data_convert = "", button_hsb = [];
if(api.includes("yahooapis"))
data_convert += "data = data.query.results.json;";
if(provider_name == "twitch") {
if(background_img) // channel live
data_convert += "data.title = data.status || 'Untitled Broadcast';"+
"data.author_url = '"+provider_url+"/'+data.name+'/profile';"+
"data.author_name = data.display_name;"+
"data.duration = data.game && 'playing <a target=_blank href=\""+provider_url+"/directory/game/'+data.game+'\">'+data.game+'</b>';"+
"window.jsonpCallback2 = function(data2) {"+
"if(data2.streams.length != 0) return;"+
"document.body.style.backgroundImage = 'url('+data.video_banner+')';"+
"document.getElementById('duration').textContent = 'offline';"+
"};"+
"var script = document.createElement('SCRIPT');"+
"script.src = 'https://api.twitch.tv/kraken/streams?channel='+data.name+'&callback=jsonpCallback2';"+
"script.defer = true;"+
"document.head.appendChild(script);";
else // video recorded
data_convert += "data.thumbnail_url = data.preview;"+
"data.author_url = '"+provider_url+"/'+data.channel.name+'/profile';"+
"data.author_name = data.channel.display_name;"+
"data.duration = data.length;";
}
if(background_img) // prevent downloading a second image
data_convert += "delete data.thumbnail_url;";
switch(provider_name) {
case "youtube" : button_hsb.push( 0, 100, 100); break;
case "dailymotion": button_hsb.push( 60, 30, 300); break;
case "vimeo" : button_hsb.push(220, 50, 220); break;
case "rutube" : button_hsb.push( 0, 0, 250); break;
case "twitch" : button_hsb.push(270, 50, 100); break;
case "ustream" : button_hsb.push( 40, 50, 230); break;
}
if(!this.html) this.html = [
"<!doctype html>"+
"<html>"+
"<head>"+
"<title>Lazy Embedded Video</title>"+
"<script defer src='", api, "&callback=jsonpCallback'></script>"+
"<script>"+
"function jsonpCallback(data){",
data_convert,
"if(data.thumbnail_url) document.body.style.backgroundImage = 'url('+data.thumbnail_url+')';"+
"if(data.url) document.getElementById('title').href = data.url;"+
"if(data.title) document.getElementById('title').textContent = data.title;"+
"if(data.author_url) document.getElementById('author').href = data.author_url;"+
"if(data.author_name) document.getElementById('author').textContent = data.author_name;"+
"if(data.duration) {"+
"if(Number(data.duration))"+
"document.getElementById('duration').textContent = new Date(data.duration*1000).toISOString().substr(11,8);"+
"else document.getElementById('duration').innerHTML = data.duration;"+
"}"+
"}"+
"</script>"+
"<style>"+
"html { height: 100%; }"+
"body {"+
"margin: 0;"+
"height: 100%;"+
"background: black ", background_img, " center/100% no-repeat;"+
"color: white;"+
"font: 14px sans-serif;"+
"}"+
"a {"+
"color: inherit;"+
"font-weight: bold;"+
"text-decoration: none;"+
"}"+
"a:hover { text-decoration: underline; }"+
"ul {"+
"margin: 0;"+
"padding: 0;"+
"list-style: none;"+
"}"+
"#infobar {"+
"position: absolute;"+
"top: 0px;"+
"width: 100%;"+
"padding: 8px 16px;"+
"box-sizing: border-box;"+
"background: rgba(0,0,0,0.5);"+
"word-wrap: break-word;"+
"}"+
"#infobar_right {"+
"float: right;"+
"margin-left: 16px;"+
"text-align: right;"+
"text-transform: capitalize;"+
"}"+
"#button {"+
"height: 100%;"+
"cursor: pointer;"+
"background-position: 0px 50%;"+
"}"+
"#button:hover {"+
"background-position: -70px 50%;"+
"filter: hue-rotate(", button_hsb[0], "deg) saturate(", button_hsb[1], "%) brightness(", button_hsb[2], "%);"+
"-webkit-filter: hue-rotate(", button_hsb[0], "deg) saturate(", button_hsb[1], "%) brightness(", button_hsb[2], "%);"+
"}"+
"#button > div {"+
"width: 70px;"+
"height: 100%;"+
"margin: auto;"+
"background: url(https://i.imgur.com/1aybyWN.png) no-repeat;"+
"background-position: inherit;"+
"}"+
"</style>"+
"</head>"+
"<body>"+
"<div id=button onclick='window.location.replace(\"", iframe, "\");'><div></div></div>"+
"<div id=infobar>"+
"<ul id=infobar_right>"+
"<li><a id=author target=_blank></a></li>"+
"<li><a id=provider target=_blank href='", provider_url, "'>", provider_name, "</a></li>"+
"</ul>"+
"<ul>"+
"<li><a id=title target=_blank href='", url, "'>", url, "</a></li>"+
"<li id=duration></li>"+
"</ul>"+
"</div>"+
"</body>"+
"</html>"
];
html[ 1] = api;
html[ 3] = data_convert;
html[ 5] = background_img;
html[ 7] = button_hsb[0];
html[ 9] = button_hsb[1];
html[11] = button_hsb[2];
html[13] = button_hsb[0];
html[15] = button_hsb[1];
html[17] = button_hsb[2];
html[19] = iframe;
html[21] = provider_url;
html[23] = provider_name;
html[25] = url;
html[27] = url;
return html.join("");
};
var createOembed = function(api, url) { return api+encodeURIComponent(url); };
var createNOembed = function(api, url) { return createOembed("https://noembed.com/embed?url=", url); };
var createYOembed = function(api, url) { return createOembed("https://query.yahooapis.com/v1/public/yql?format=json&q=",
'SELECT * FROM json WHERE url="'+createOembed(api,url)+'"'); };
var createLazyVideo = function(elem) {
if(elem.tagName == "IFRAME" && elem.srcdoc) return;
var src = decodeURIComponent(elem.src || elem.data || elem.dataset.src);
if(/youtube\.com\/(?:v|embed)\/([a-z\d_-]+)(?=.*[?&](list=[a-z\d_-]+)|)(?:.*[?&](start=\d+))?/i.test(src)) {
src = createHtml(src =
"https://www.youtube.com/watch?v="+RegExp.$1+(RegExp.$2 && "&"+RegExp.$2)+(RegExp.$3 && "&"+RegExp.$3),
"https://www.youtube.com/embed/"+RegExp.$1+"?autoplay=1"+(RegExp.$2 && "&"+RegExp.$2)+(RegExp.$3 && "&"+RegExp.$3),
createNOembed("https://www.youtube.com/oembed?format=json&url=", src),
"url(https://i.ytimg.com/vi/"+RegExp.$1+"/hqdefault.jpg)"
);
} else if(/dailymotion\.com\/(?:swf|embed)\/video\/([a-z\d]+)(?=.*[?&](mute=[^&#]+)|)(?:.*[?&](start=\d+))?/i.test(src)) {
src = createHtml(src =
"https://www.dailymotion.com/video/"+RegExp.$1+"?"+(RegExp.$2 && "&"+RegExp.$2)+(RegExp.$3 && "&"+RegExp.$3),
"https://www.dailymotion.com/embed/video/"+RegExp.$1+"?autoplay=1"+(RegExp.$2 && "&"+RegExp.$2)+(RegExp.$3 && "&"+RegExp.$3),
createOembed("https://www.dailymotion.com/services/oembed?format=json&url=", src),
"url(https://www.dailymotion.com/thumbnail/video/"+RegExp.$1+")"
);
} else if(/vimeo\.com\/(?:moogaloop\.swf.*[?&]clip_id=|video\/)(\d+)(?=.*[?&](loop=[^&#]+)|)(?:.*(\#t=[\dhms]+))?/i.test(src)) {
src = createHtml(src =
"https://vimeo.com/"+RegExp.$1+(RegExp.$2 && "?"+RegExp.$2)+RegExp.$3,
"https://player.vimeo.com/video/"+RegExp.$1+"?autoplay=1"+(RegExp.$2 && "&"+RegExp.$2)+RegExp.$3,
createOembed("https://vimeo.com/api/oembed.json?url=", src)
);
} else if(/rutube\.ru\/play\/embed\/(\d+)(?:.*[?&](bmstart=\d+))?/i.test(src)) {
src = createHtml(src =
"https://rutube.ru/tracks/"+RegExp.$1+".html/"+(RegExp.$2 && "?"+RegExp.$2),
"https://rutube.ru/play/embed/"+RegExp.$1+"?autoStart=1"+(RegExp.$2 && "&"+RegExp.$2),
createOembed("https://rutube.ru/api/oembed/?format=jsonp&url=", src)
);
} else if(/twitch\.tv\/.*[?&](channel|video)=([a-z\d_]+)/i.test(src)) {
src = createHtml(src =
"https://www.twitch.tv/"+(RegExp.$1=="video" ? RegExp.$2.replace("v","c/v/") : RegExp.$2),
"https://player.twitch.tv/?"+RegExp.$1+"="+RegExp.$2+"&autoplay=true",
"https://api.twitch.tv/kraken/"+RegExp.$1+"s/"+RegExp.$2+"?",
RegExp.$1=="channel" ? "url(https://static-cdn.jtvnw.net/previews-ttv/live_user_"+RegExp.$2+"-0x0.jpg)" : null
);
} else if(/ustream\.tv\/embed\/(recorded\/)?(\d+)/i.test(src)) {
src = createHtml(src =
"https://www.ustream.tv/"+(RegExp.$1||"channel/")+RegExp.$2,
"https://www.ustream.tv/embed/"+RegExp.$1+RegExp.$2+"?html5ui=1&autoplay=1",
createYOembed("https://www.ustream.tv/oembed?format=json&url=", src)
);
} else {
return;
}
if(elem.tagName != "IFRAME") {
var iframe = document.createElement("IFRAME");
iframe.id = elem.id;
iframe.className = elem.className;
iframe.style.cssText = elem.style.cssText;
if(!iframe.style.width && elem.width ) iframe.style.width = elem.width+"px";
if(!iframe.style.height && elem.height) iframe.style.height = elem.height+"px";
if(!iframe.style.border) iframe.style.border = "0px";
if(elem.parentNode.tagName == "OBJECT") elem = elem.parentNode;
elem.parentNode.replaceChild(iframe, elem);
elem = iframe;
}
elem.allowFullscreen = true;
elem.srcdoc = src;
};
if(frameElement) createLazyVideo(frameElement);
for(var i = 0, nodes = document.getElementsByTagName("IFRAME"); i < nodes.length; i++) { createLazyVideo(nodes[i]); }
for(var i = 0, nodes = document.getElementsByTagName("EMBED" ); i < nodes.length; i++) { createLazyVideo(nodes[i]); }
for(var i = 0, nodes = document.getElementsByTagName("OBJECT"); i < nodes.length; i++) { createLazyVideo(nodes[i]); }
})();