book/scripts-greasemonkey/youtube_to_invidious.user.js

170 lines
6.4 KiB
JavaScript

// ==UserScript==
// @name YouTube to Invidious
// @author OdinBrood, Jesús E.
// @namespace Krul & Brood
// @description Scan page for Youtube embeds and urls and replace with Invidious.
// @include *
// @exclude /^http(s|)://(www[.]|)invidio[.]us/.*$/
// @exclude /^http(s|)://(www[.]|)invidious[.]snopyta[.]org/.*$/
// @exclude /^http(s|)://(www[.]|)vid.wxzm[.]sx/.*$/
// @exclude /^http(s|)://(www[.]|)invidious[.]kabi[.]tk/.*$/
// @exclude /^http(s|)://(www[.]|)invidiou[.]sh/.*$/
// @exclude /^http(s|)://(www[.]|)invidious[.]enkirton[.]net/.*$/
// @exclude /^http(s|)://(www[.]|)tube[.]poal[.]co/.*$/
// @exclude /^http(s|)://(www[.]|)invidious[.]13ad[.]de/.*$/
// @grant GM_xmlhttpRequest
// @version 8.4.2
// ==/UserScript==
/* jshint esversion: 6 */
var instance='proxy.invidious.snopyta.org'; //set you favorite Invidious instance! (https://github.com/omarroth/invidious/wiki/Invidious-Instances)
//change script options, default values recommended
var a=1; //set to 0 to force autoplay off, set to 1 to keep embed's value [default 1]
var b=1; //set to 0 to not replace all youtube links to Invidious [default 1]
var c=1; //set to 0 to disable DASH playback (beta feature) [default 1]
var d=1; //set to 0 to disable Invidious proxy [default 1]
var e=1; //set to 0 to disable bypass of url shorteners [default 1]
var ytdomains=new RegExp(/http(s|)\:\/\/(m[.]|i[.]|www[.]|img[.]|)(youtu(|be|be-nocookie)|.*ytimg)[.](com|be)\/.*/);
var shorteners=new RegExp(/^http(s|):\/\/(bit.ly|goo.gl|tinyurl.com|t.co|ow.ly|is.gd|buff.ly|deck.ly|su.pr|lnk.co|fur.ly|moourl.com|)\/.*/);
var params=new RegExp(/^(autoplay|channel|v|playlist|list)$/);
var current=window.location.href.match(ytdomains)===null;
var frames,thumbs,links,skip;
if(current){
frames=Array.prototype.slice.call(document.getElementsByTagName('iframe')).filter(ytel);
thumbs=Array.prototype.slice.call(document.getElementsByTagName('img')).filter(ytel);
if(b==1)links=Array.prototype.slice.call(document.getElementsByTagName('a')).filter(ythref);
if(frames.length>0)embed();
if(thumbs.length>0)thumb();
if(links.length>0)link();
}else{
var title=Array.prototype.slice.call(document.getElementsByTagName('h1'));
addbtn();
}
var observer=new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(current){
frames=Array.prototype.slice.call(mutation.target.getElementsByTagName('iframe')).filter(ytel);
thumbs=Array.prototype.slice.call(mutation.target.getElementsByTagName('img')).filter(ytel);
if(frames.length>0)embed();
if(thumbs.length>0)thumb();
if(b==1){
links=Array.prototype.slice.call(mutation.target.getElementsByTagName('a')).filter(ythref);
if(links.length>0)link();
}
}else{
skip=Array.prototype.slice.call(mutation.target.getElementsByClassName('skipinv'));
if(skip<1){
title=Array.prototype.slice.call(mutation.target.getElementsByTagName('h1'));
addbtn();
}
}
});
});
observer.observe(document.body,{childList:true,subtree:true});
function embed(){
for(var i=0;i<frames.length;i++){
frames[i].style.backgroundColor='rgba(35,35,35,1)';
frames[i].style.backgroundRepeat='no-repeat';
frames[i].style.backgroundPosition='center center';
frames[i].style.backgroundSize='auto';
for(var j=0;j<frames[i].attributes.length;j++) {
if(frames[i].attributes[j].value.match(ytdomains)){
var url=new URL(frames[i].attributes[j].value);
if(!url.hostname.match(/youtube/)){
url=new URL(decodeURIComponent(url.href).match(ytdomains)[0]);
url.searchParams.set('autoplay',0);
}
for(var key of url.searchParams.keys()){
if(!(key.match(params)))url.searchParams.delete(key);
}
url.hostname=instance;
if(a==1){
if(!url.searchParams.has('autoplay')||url.searchParams.get('autoplay')==='')url.searchParams.set('autoplay',0);
}else{
url.searchParams.set('autoplay',0);
}
if(c==1)url.searchParams.set('quality','dash');
if(d==1)url.searchParams.set('local',true);
frames[i].setAttribute(frames[i].attributes[j].name,url);
}
}
}
}
function thumb(){
for(var i=0;i<thumbs.length;i++){
var url=new URL(thumbs[i].src.match(ytdomains)[0]);
url.hostname=instance;
thumbs[i].src=url;
}
}
function link(){
for(var i=0;i<links.length;i++){
var url=new URL(links[i].href.match(ytdomains)[0]);
url.hostname=instance;
links[i].href=url;
}
}
function addbtn(){
for(var i=0;i<title.length;i++){
var btn=document.createElement('a');
btn.innerHTML='<h2>Watch on '+instance+'</h2>';
btn.href='javascript:void(0)';
btn.onclick=function(){redir();};
btn.className='skipinv';
title[i].parentNode.appendChild(btn);
}
}
function redir(){
var url=new URL(window.location.href);
url.hostname=instance;
location.href=url;
}
function unshorten(long,short){
frames=Array.prototype.slice.call(document.getElementsByTagName('iframe'));
for(var k=0;k<frames.length;k++){
for(var l=0;l<frames[k].attributes.length;l++) {
if(frames[k].attributes[l].value==long){
frames[k].attributes[l].value=short;
frames=[frames[k]];
embed();
return;
}
}
}
}
function ytel(el){
for(var i=0;i<el.attributes.length;i++){
var val=el.attributes[i].value;
if(val.substring(0,2)=='//')val='https:'+val;
try{val=decodeURIComponent(val);}catch(e){}
if(val.match(shorteners)&&e==1){
var long=el.attributes[i].value=val;
GM_xmlhttpRequest({
method:'GET',url:long,onload:function(response){
var short=response.finalUrl;
if(short.match(ytdomains))unshorten(long,short);
}
});
}
if(val.match(ytdomains)){
el.attributes[i].value=val;
return true;
}
}
}
function ythref(el){
return(decodeURIComponent(el.href).match(ytdomains));
}