// ==UserScript==
// @name yahvt
// @description yet another html5 video tool
// @namespace gnblizz
// @version 1.16
// @include http://anilinkz.io/*
// @include http://www.animecenter.tv/*
// @include http://www.animedreaming.tv/*
// @include http://anime-exceed.com/*
// @include http://www.animefreak.tv/*
// @include http://www.animehere.com/*
// @include http://www.animenova.org/*
// @include http://www.animeplus.tv/*
// @include http://www.animeseason.com/*
// @include http://www.animesky.net/*
// @include http://as.animes-stream24.tv/*
// @include http://www.anime-sub.co/*
// @include http://www.animetoon.org/*
// @include http://www.animeultima.io/*
// @include http://www.animewow.org/*
// @include http://bestanimes.tv/*
// @include http://www.chia-anime.tv/*
// @include http://www.clipfish.de/*
// @include http://dramago.com/*
// @include http://www.dramago.com/*
// @include http://www.dramagalaxy.tv/*
// @include http://dubbedanime.net/*
// @include http://www.dubzonline.ca/*
// @include http://freeanime.com/*
// @include http://www.gogoanime.to/*
// @include http://www.goodanime.co/*
// @include http://www.gooddrama.to/*
// @include http://www.lovemyanime.net/*
// @include http://www.videozoo.me/*
// @include about:blank?video=*
// @include h*embed*
// @include h*gogo/*
// @include h*widget/*
// @match http://*.mangaotaku.org/*
// @include http://player.arkvid.tv/*
// @include http://www.dramastream.org/*
// @exclude https://openload.co/embed/*
// @exclude https://apis.google.com/*
// @run-at document-start
// @grant GM_xmlhttpRequest
// @icon data:image/gif;base64,R0lGODlhMAAwAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAwADAAAALQnI+py+0Po5y02ouz3rz7D4biBJTmiabqyrbuC8fyHAf2jedpzuOvAAwKh6mhUfg7Hks3gHLpehptwIBTioxig0zrdStIgrslMFA8pCKp1oAZjXW6w/Mt/Nl2t8HeFl7o5QZgBagEYyawNxhUl7h4dlelFlZG+QVY6aglmIjjuKd50xla9RKI0mSCqaPJSMM0aEK4mhfbpSnTabM4WXrShtpHI6gqKvmKnCwns0tm2lOsLP3aUy08aK0zvc3d7b09Ei4+Tl5ufo6err7O3n5QAAA7
// @compatible firefox
// @compatible chrome
// ==/UserScript==
"use strict";
var doc=document, isTop=window.self==window.top, domain = (document.domain||'unknown.').split('.').reverse(), insertionPoint, isFF = /Firefox/i.test(navigator.userAgent), maxmsg=99;
document.addEventListener('DOMContentLoaded', yahvt);
!function earlyHacks(){
switch(domain[1]) {
case 'clipfish'://.de
if(isFF) nn('SCRIPT', doc.body).innerHTML = 'checkMobile=function(){isMobile=true;}';
else Object.defineProperty(navigator, "userAgent", {value: 'fake Android'});
break;
}
}();
function sites(){
var a,i,o,e,b;
//console.log('yahvt: domain =', domain);
switch(domain[1]) {
case 'anilinkz'://.tv => io
SetStyle('#waifu,body>div:empty[style*="z-index: 2147483647;"]{display:none;}');
//SetStyle('div[style*="position"]{background-color:green;opacity:0.6;}');
allowFullscreen('#player');
setTimeout(function () {
var i = setInterval(function () {}, 999);
do { clearInterval(i); } while(--i);
i = setTimeout(function () {}, 999);
do { clearTimeout(i); } while(--i);
}, 45000);
break;
case 'animecenter'://.tv
allowFullscreen('#video');
break;
case 'animedreaming'://.tv
allowFullscreen('.videoholder');
break;
case 'anime-exceed'://.com
allowFullscreen('#player', (/^\/cool\//.test(location.pathname)?'':'body'),0,999);
break;
case 'animefreak'://.tv
a=na('.multi'); for(o of a) {
e = o.getAttribute('onclick');
if(e && /loadParts\('http/.test(e))
o.onclick = function(event) {
var vid_file = decodeURIComponent(this.getAttribute('onclick').match(/loadParts\('([^']+)'/)[1]);
doc.getElementById("player").innerHTML = '<video controls width="100%" height="412" src="' + vid_file + '" allowfullscreen="true" autoplay></video>';
};
}
break;
case 'animehere'://.com => error!
allowFullscreen('#playbox');
break;
case 'animenova'://.tv => org
case 'animeplus'://.tv
case 'animesky'://.net => error!
case 'animetoon'://.tv => org
case 'animewow'://.eu => org
case 'dramagalaxy'://.eu,com => tv
case 'dramago'://.com
case 'gooddrama'://.net => to
allowFullscreen('#streams');
break;
case 'animeseason'://.com
if(fn('#series_info'))
SetStyle('table a:visited{color:gray;}table a:hover{color:#FC0;}');
allowFullscreen('#video_source', 0, '#player_list A');
break;
case 'dramastream'://.org => error!
allowFullscreen('div[align]', 'center');
break;
case 'anime-sub'://.com => co
allowFullscreen('#movie-content');
break;
case 'animeultima'://.tv => io
allowFullscreen('#pembed');
break;
case 'bestanimes'://.tv
allowFullscreen('.post');
break;
case 'freeanime'://.com
nn('SCRIPT', doc.body).innerHTML = '$(window).unbind();\n$("#header").css("background-attachment","scroll")';
allowFullscreen('.z-video', 0, 'ul.z-tabs-nav LI', 999);
break;
case 'goodanime'://.net => co
case 'videozoo'://.me
allowFullscreen('#content');
case 'dubzonline'://.com => ca
return(location.pathname == '/embed.php');
case 'lovemyanime'://.net
//allowFullscreen('.player-area');
break;
case 'animes-stream24'://.net => .tv
allowFullscreen('#main');
break;
case 'gogoanime'://.com => .to
return location.pathname=='/flowplayer/' || allowFullscreen('#content');
case 'arkvid'://.tv
return domain[2]=='player';
case 'mangaotaku': // => error! // animeboy,dramastream
return 1;// return(location.pathname == '/dr_video_player.php');
case 'unknown'://about:blank?video="..."
if(/^about:blank\?video=/.test(location.href))
return nn('SCRIPT', doc.body).textContent = '("'+location.href.slice(18)+'")';
break;
default:
return(/(embed\b|\/gogo\/|\/widget\/)/.test(doc.URL));
}
function allowFullscreen(selTop, selFrame, mirrors, delay) {
if(delay)
window.setTimeout( function() { allowFullscreen(selTop, selFrame, mirrors); }, delay);
else {
var a,i;
if(isTop) {
if(mirrors) {
a = doc.querySelectorAll(mirrors);
for(i of a) {
i.addEventListener('click', function() {
window.setTimeout( function() { doc.querySelector(selTop+' IFRAME').setAttribute('allowfullscreen', 'true'); }, 99);
});
}
}
a = doc.querySelectorAll(selTop+' IFRAME');
if(!a.length) console.log('yahvt: couldn\'t apply fullscreen attribute because '+selTop+' IFRAME not found in '+doc.URL);
for(i of a) { i.setAttribute('allowfullscreen', 'true'); }
} else if(selFrame) {
a = doc.querySelectorAll(selFrame+' IFRAME');
for(i of a) { i.setAttribute('allowfullscreen', 'true'); }
}
}
}}
// FULL SCREEN API
//requires about:config full-screen-api.allow-trusted-requests-only=false
function SetFullScreenMode(v) {
(v.requestFullscreen||v.mozRequestFullScreen||v.webkitRequestFullscreen||v.webkitEnterFullscreen).call(v);
//console.info('To allow full screen mode, you may want to set full-screen-api.allow-trusted-requests-only to false in about:config.');
}
function FullScreenElement() {
if(doc.exitFullscreen) return doc.fullscreenElement;
if(doc.mozCancelFullScreen) return doc.mozFullScreenElement;
if(doc.webkitExitFullscreen) return doc.webkitFullscreenElement;
}
function EndFullScreenMode() {
if(!FullScreenElement()) return false;
(doc.exitFullscreen||doc.mozCancelFullScreen||doc.webkitExitFullscreen).call(doc);
return true;
}
function OnFullScreenChange(fn) {
if(doc.exitFullscreen) doc.addEventListener("fullscreenchange", fn);
if(doc.mozCancelFullScreen) doc.addEventListener("mozfullscreenchange", fn);
if(doc.webkitExitFullscreen) doc.addEventListener("webkitfullscreenchange", fn);
}
function SetFocus(v) {
if(!v) v = fn('VIDEO');
v.focus();
if(!isFF) setTimeout(function(){ v.focus(); }, 0); // same old chrome bug
}
// new node
function nn(name, parent) {
var a = name.split(/,(?! )/); name = a.shift();
var node = doc.createElement(name.match(/^\w+/)[0]),
m = name.match(/#\w+/); if(m) node.id = m[0].slice(1);
m = name.match(/\.\w+/); if(m) node.className = m[0].slice(1);
while(a.length) {
var t = a.shift(), l = t.indexOf('=');
switch(l) {
case -1:
node.setAttribute(t, t);
break;
case 0:
node.textContent = t.slice(1);
break;
case 1:
if(t.charAt(0) == '?') {
node.innerHTML = t.slice(2);
break;
}
default:
node.setAttribute(t.slice(0, l), t.slice(l+1));
}
};
if(parent) parent.appendChild(node);
return node;
}
// find node
function fn(name, parent) {
if(!parent) parent = doc;
switch(name.charAt(0)) {
case '#':
return parent.getElementById(name.slice(1));
case '.':
return parent.getElementsByClassName(name.slice(1))[0];
}
return parent.getElementsByTagName(name)[0];
}
// find nodes array
function na(name, parent) {
if(!parent) parent = doc;
return (name.charAt(0)=='.') ? parent.getElementsByClassName(name.slice(1)) : parent.getElementsByTagName(name);
}
// remove node
function rn(node) {
if(typeof(node)=='string') node = fn(node);
if(node) return node.parentNode.removeChild(node);
}
function domainName(href) {
if(!href) href = location.href;
var m = href.match(/\:\/\/(?:www\.|embed\.)?([^\/]+)/);
if(m) return m[1];
return 'unknown';
}
function Remember(name, value) {
try {
if(sessionStorage) switch(value) {
case '':
sessionStorage.removeItem(name);
break;
case undefined:
value = 'yes';
default:
sessionStorage.setItem(name, value);
}
}catch(e){}
}
function remembered(name, forget) {
try {
var x = sessionStorage.getItem(name);
if(forget) sessionStorage.removeItem(name);
return x;
} catch(e) {
if(name=='autoplay' && (domain[1]=='unknown' || /\bnoflash\b/.test(location.search) || /(part|clip)_?0?[2-9]/.test(location.pathname))) return 'yes';
}
}
// style
function SetStyle(style) {
var st = nn('STYLE', doc.head);
st.innerHTML = style;
return st;
}
function MakeCSSString(name, def) {
var names = Object.getOwnPropertyNames(def), style = (names.indexOf('top') < 0 ? '' : 'position:absolute;' ), x, value;
for(x of names) {
value = def[x];
if(typeof(value) == 'number' && x != 'z_index') value += 'px';
style += x.replace(/_/g,'-') + ': ' + value + '; ';
}
return name + '{' + style + '}\n';
}
//*/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////*/
function findVideoFiles() {
function getScript(o) {
s = o.innerHTML;
if(s.length) {
var m = s.match(/^eval(\(function\(p(?:,[a-ek]){5}\).+\bsplit\b.+)$/m), timer;
if(m) {
try { s += eval(m[1]); console.log('yahvt: Packed script detected.'); } catch(e) { console.log('yahvt: Packed script parse error.'); }
}
s = unescape(s.replace(/\s\/\/.*$/gm,'').replace(/\s+/gm,' ').replace(/\/\*.*\*\//g,'').replace(/'/g,'"'));
if(domain[1]=='dailymotion') s = s.replace(/\\\//g, '/');
return s;
}
}
function add(m) { if(m && v.indexOf(m)<0) v.push(m); }
function addm1(m) { if(m && v.indexOf(m[1])<0) v.push(m[1]); }
function find(pattern) {
var g = /g/.test(pattern.flags);
do {
var m = pattern.exec(s);
if(!m) break;
try {
add(decodeURIComponent(unescape(m[1])));
} catch(e) {
add(m[1]);
}
} while(g);
}
//findVideoFiles() {
var v = [], s, m, a, i, p;
a = fn('VIDEO', doc.body);
if(a) {//usually doesn't exist yet
add(a.getAttribute('src'));
a = na('SOURCE', a);
for(i of a) {
add(i.getAttribute('src'));
}
}
a = na('SCRIPT', (domain[1]=='videozoo' ? doc.documentElement : doc.body)); for(i of a) {
if(getScript(i)) {
find(/"(https?:\/\/[^"]+\.(?:mp4|flv)\b[^"]*)"/gi);
find(/"(.+\.php\b.+\.(?:mp4|flv))"/gi);
find(/"([^"]+\bpicasa\.php\b[^"]+)"/gi);
find(/"(https\:\/\/[^"]*\.google(?:video\.com\/videoplayback|usercontent.com\/)[^"]+)"/gi);
}
}
switch(domain[1]) {
case 'trollvid'://.net// Is this of any use today? TODO obsolete?
for(i of a) {
s = i.innerHTML; m = s.match(/['"](http.+?data.*?file.*?)['"]/i); addm1(m);
}
a = na('SCRIPT', doc.head); for(i of a) {
m = i.innerHTML.match(/unescape\(atob\('(.+?)'/);
if(m) { m = unescape(atob(m[1])); if(/\.(mp4|flv)/i.test(m)) add(m); }
}
break;
case 'videobam'://.com// Is this of any use today?
for(i of a) {
s = i.innerHTML; m = s.match(/['"](http:\\\/\\\/[^'"]+\.(?:mp4|flv)\b[^'"]*)['"]/i); if(m) add(m[1].replace(/\\\//g,'/'));
}
case 'yourupload'://.com// experimental
try {
s = fn('#player').nextElementSibling.textContent;
m = s.match(/'(\/play\/\d+\.flv\?.+?)'/);if(m) add(m[1]);
}catch(e){ console.log(e); }
case 'test':
}
try {// even if it looks wierd...
m = doc.querySelector('#flowplayer+script').innerHTML.replace(/\s+/g, ' ').match(/\/\* playlist\: \[ \{ url\: '(.*)'/)[1];
if(!/\<|\>/.test(m)) {
console.log('yahvt: html5_path in comment found.');
add(m);
}
} catch(e){}
try {// animeboy
add(unescape(fn('NOSCRIPT').innerHTML.match(/<param\sname="movie"\svalue="\S+&fpath=([^&]+)&/i)[1]).replace(/\+/g,'%20'));
console.log('yahvt: movie param in noscript found.');
} catch(e){}
a = na('PARAM'); for(i of a) { p = i.getAttribute('value'); m = p.match(/video=(https?:\/\/[^'"]+\.mp4[^'"&]*)/i); addm1(m); }
a = na('EMBED'); for(i of a) { p = i.getAttribute('src'); m = p.match(/video=(https?:\/\/[^'"]+\.mp4[^'"&]*)/i); addm1(m); }
switch(domain[1]) {
case 'dailymotion':
return v.reverse();
case 'mp4upload':
i = v.length;
if(i) do {
a = v[--i];
if(a.match(/\.com\/[a-z]+\.mp4$/)) {
console.log('yahvt:', a, 'ignored.');
delete v[i];
}
} while(i);
}
return v;
}
function yahvt(loadevent) {
function insertVideo() {
function ShowSomeInfo(meta) {
var div = nn('DIV.info'), txt = domainName() + (nvp ? (' video part '+nvp.now) : ' video'), src = v.currentSrc, m, adr = ['mailto:gnblizz'];
if(meta) {
var t = v.duration + .5;
txt += '<br>pixel format: ' + v.videoWidth + 'x' + v.videoHeight
+ '<br>duration: ' + Math.floor(t/60) + ':' + ('0' + Math.floor(t%60)).slice(-2);
} else div.style.color = '#666';
m = src.match(/https?:\/\/([^:?/]+)/);
if(m) txt += '<br>video host name: ' + m[1];
m = src.match(/.*\/([^?/]*)/);
if(m) txt += '<br>video file name: ' + m[1];
txt += '<br><br>A - toggle stretch mode<br>F - toggle full screen mode<br>I - '+(meta ? 'this info<br>Q - quick viewing<br>S - slow motion' : 'some info')+'<br>Z - toggle zoom to 100%';
if(meta) {
adr.push('@web.de?subject=yahvt%20at%20', document.domain);
txt += '<br><br><small><a target="_newtab" href="https://greasyfork.org/en/scripts/14476-yahvt" title="info, code, feedback and stats of yahvt">yahvt</a> is public domain by <a href="' + adr.join('')
+ '" title="email the author directly">gnblizz</a>.</small>';
}
div.innerHTML = txt;
v.parentNode.appendChild(div);
window.setTimeout(StopInfo, 15000);
}
function StopInfo() {
if(!v.paused || v.currentTime < 5) return rn(p.querySelector('div.info,div.info2'));
var div = p.querySelector('div.info');
if(div) nn('SMALL,?=<br><br>If there are issues regarding yahvt, someone has to complain.<br>Therefore, the two links above.', div);
}
function NextPart(name) {
var m = name.match(/^(.*(?:part|clip)_?0?)(\d+)(.*)$/), i;
if(m)
return {now: i = parseInt(m[2]), next: ++i, URL: m[1]+i+m.pop()};
else {
m = name.match(/^(.*%26sp%3D)a(%26episode%3D\d+)A(%26.*)$/);//animeboy,mangaotaku
if(m)
return {now: 'A', next: 'B', URL: m[1]+'b'+m[2]+'B'+m.pop()};
}
}
function StartStop() {
if(v.paused) v.play();
else v.pause();
}
function TestResource(url, btn) {
var req = new XMLHttpRequest();
try {
if(req) {
req.open('HEAD', url, true);
req.onloadend = function () {
switch(req.status) {
case 200:
if(req.statusText != 'Not Found')
btn.click();
case 404:
rn(btn);
}
};
req.send();
}
}catch(e){ console.log('yahvt:', e, url, req); }
}
//insertVideo() {
var nvp = NextPart(doc.URL), txt = '<video controls ' + (autoplay ? 'autoplay ' : '') +
'width="100%" height="100%" tabindex="0', altClick, hTimer2, autoHide, smw, delay = 2;
av.push(av[0]+'&noflash');
av.push(av[0]+'&html5=true');
av.forEach(function(x){ txt += '"><source src="' + x.replace(/\?/g,'&').replace('&','?'); });
txt += '"></video>';
if(fn('#flowplayer')) txt += '<div id="flowplayer"></div>';
else if(fn('#player')) txt += '<div id="player"></div>';
if(insertionPoint);//TODO
else doc.body.innerHTML = txt;
console.log('yahvt: starting ' + domainName() + (nvp ? (' video part '+nvp.now) : ' video'));
var v = fn('VIDEO'), p = v.parentNode;
v.onloadedmetadata = function(event) {
//console.log('yahvt: now playing: '+v.currentSrc);
var format = [v.videoWidth, v.videoHeight].join('x');
StopInfo();
if(!isTop) window.top.postMessage('videoformat'+ format, '*'); // new code
//if(!isTop) window.top.postMessage('videoformat', '*', format); // new code
if(remembered('fullscreen', true)=='yes')
SetFullScreenMode(v);
nn('DIV.info2,=' + format, v.parentNode);
window.setTimeout(StopInfo, 3000);
SetFocus(v);
};
p.onmousemove = function(event) {
if(hTimer2) clearTimeout(hTimer2);
else p.style.cursor = '';
if(autoHide) {
hTimer2 = setTimeout(function() {
hTimer2 = 0;
p.style.cursor = 'none';
}, 3456);
} else hTimer2 = 0;
delay = 1;
};
v.onplaying = function(event) {
autoHide = 1;
StopInfo();
hTimer2 = setTimeout(function() {
hTimer2 = 0;
p.style.cursor = 'none';
}, delay * 3456);
};
v.onpause = function(event) {
if(hTimer2) clearTimeout(hTimer2);
else p.style.cursor = '';
autoHide = 0;
hTimer2 = 0;
delay = 0;
};
v.onkeypress = function(event) {
if(event.altKey || event.metaKey || event.ctrlKey) return;
switch(event.key.toUpperCase()) {
case ' ':
if(isFF) return;
case 'P':
StartStop();
break;
case 'A':// toggle stretch mode
v.style.objectFit = v.style.objectFit ? '' : 'fill';
p.style.height = '100%';
break;
case 'F':// toggle full screen
if(!EndFullScreenMode())
SetFullScreenMode(v);
break;
case 'H':// toggle LMB behavior
((altClick = !altClick) ? v.addEventListener : v.removeEventListener).call(v, 'click', StartStop, false);
break;
case 'I':// show some info
if(!rn(p.querySelector('div.info')))
ShowSomeInfo(true);
break;
case 'Q':// quick view
if(!smw) {
nn('DIV.info2,=press "Q" to end quick view mode', v.parentNode);
smw = window.setTimeout(StopInfo, 3000);
}
v.playbackRate = v.playbackRate != 1 ? 1 : 2;
break;
case 'S':// slow motion
if(!smw) {
nn('DIV.info2,=press "S" to end slow motion mode', v.parentNode);
smw = window.setTimeout(StopInfo, 3000);
}
v.playbackRate = v.playbackRate != 1 ? 1 : .05;
break;
case 'Y': case 'Z':// toggle zoom mode
if(p.style.width) {
p.style.width = '';
p.style.minHeight = p.parentNode.clientHeight+'px';
p.style.margin = '';
} else if(v.videoWidth) {
p.style.width = v.videoWidth+'px';
p.style.minHeight = v.videoHeight+'px';
p.style.margin = '0px auto';
}
break;
default:
return;
}
event.preventDefault();
event.stopPropagation();
};
v.onkeydown = function(event) {
if(event.altKey || event.metaKey || event.ctrlKey || event.shiftKey) return;
switch(event.key) {
case 'ArrowRight':
v.currentTime += v.paused ? .5 : 5;
break;
case 'ArrowLeft':
v.currentTime -= v.paused ? .5 : 5;
break;
case 'Escape':
v.playbackRate = 1;
default:
return;
}
event.preventDefault();
event.stopImmediatePropagation();
};
if(!isFF) {
v.onclick = function(event) {
if(document.hasFocus()) StartStop();
SetFocus(v);
//onmousedown event.preventDefault();?
};
}
v.lastChild.onerror = function(event) {
StopInfo();
if(!/\bnoflash\b/.test(location.search)) {
Remember('autoplay');
location.search = location.search ? location.search+'&noflash' : '?noflash';
throw 'redirecting to location + noflash';
}
console.log('yahvt: video load error');
if(nvp && nvp.now>1)
doc.body.innerHTML = '<center style="color:orange;"><br><br>No part '+nvp.now+' could be found, so this must be...<br><b style="font-size:333%;"><br>The End</b></center>';
remembered('fullscreen', true);// discard value
};
v.onended = function(event) {
var wasFullScreen = EndFullScreenMode();
autoHide = 0;
p.style.cursor = '';
if(!isTop) window.top.postMessage('videoended', '*'); // new code
if(!isTop && !fn('#VideoCloseButton')) {
nn('BUTTON#VideoCloseButton,type=button,=x,title=close', p).onclick = function(event){
location.replace('about:blank');
return false;
};
}
if(nvp) {
var btnNext = nn('BUTTON#NextPartButton,type=button,='+nvp.next+',title=on to part '+nvp.next, p);
btnNext.onclick = function(event) {
console.log('yahvt: redirecting to part '+nvp.next);
Remember('autoplay');
Remember('fullscreen', (wasFullScreen ? 'yes' : ''));
location.replace(nvp.URL);
return false;
};
btnNext.focus();
TestResource(nvp.URL, btnNext);
} else {//nfv
var vf = v.currentSrc, m = vf.match(/^(.*(?:part|clip)_?0?)(\d+)(.*)$/);
if(m) {
console.log('yahvt: using alternate next part algorithm (experimental)');
// This is when no part information was found in the page location, but in the video file name instead.
// I forgot long time ago where I saw such scenario and don't know how to test it anymore. TODO
var inp = parseInt(m[2])+1;
vf = m[1] + inp + m[3];
var btnNext2 = nn('BUTTON#NextPartButton,type=button,='+inp+',title=on to part '+inp, p);
btnNext2.onclick = function(event) {
Remember('fullscreen', (wasFullScreen ? 'yes' : ''));
av = [vf];
insertVideo();
};
console.log('yahvt: about to insert video part '+inp);
try {
var rv = GM_xmlhttpRequest({
url: vf,
method: "HEAD",
onload: function(response) {
if(/^Content-Type:\s*video\b/m.test(response.responseHeaders)) {
console.log('yahvt: video resource found');
btnNext2.click();
} else {
console.log('yahvt: invalid video resource');
}
rn(btnNext2);
},
onerror: function(response) {
console.log('yahvt: --onerror-response:\n'+response.responseHeaders);
rn(btnNext2);
}
});
} catch(e) {
TestResource(vf, btnNext2);
}
}//m
}//!nfv
};//v.onended
ShowSomeInfo(false);
OnFullScreenChange(function(event) { fn('VIDEO').focus(); });
}
function Block(event) {
event.preventDefault();
if(maxmsg>=0) {
console.warn("yahvt: blocking script element:", event.target.src, event.defaultPrevented);
if(!(--maxmsg)) {
//console.log('yahvt:', event);
throw('to many alien script requests.');
} //trollvid tries again and again, causing heavy CPU load, so we give up
}else document.defaultView.removeEventListener('beforescriptexecute', Block);
}
//yahvt() {
//console.log('yahvt:', loadevent);
try {
if(sites()) {
var av = findVideoFiles();
if(av && av.length) {
// we block things only after we are sure they aren't needed
if(!insertionPoint) {
document.defaultView.addEventListener('beforescriptexecute', Block);
var n = setTimeout(function(){},0); while(--n){clearTimeout(n);};
n = setInterval(function(){},999); while(n){clearInterval(n--);};
}
console.log('yahvt: Found '+av.length+' video source'+(av.length==1 ? '' : 's')+' at '+domainName()+'.');
if(/\/blank.mp4$/.test(av[0])) av.push(av.shift());
var v = fn('VIDEO');
if(v) { v.pause(); v.removeAttribute('src'); }
SetStyle(
MakeCSSString('body,html',{padding:0, margin:0, height:'100%', overflow:'hidden', background:'#000', color:'#fff', font_size:14}) +
MakeCSSString('video', {outline:0}) +
MakeCSSString('#player,#flowplayer', {display:'none'}) +
MakeCSSString('button#VideoCloseButton', {top:0, right:0, height:25, min_width:25}) +
MakeCSSString('button#NextPartButton', {top:0, right:30, height:25, min_width:25}) +
MakeCSSString('.info a', {color:'unset'}) +
MakeCSSString('.info', {top:50, left:50, text_shadow:'1px 1px black'}) +
MakeCSSString('.info2', {top:1, left:2, text_shadow:'1px 1px black', font_size:'large'})
);
var autoplay = remembered('autoplay', true) == 'yes';
if(!isTop && !autoplay) {
doc.body.innerHTML = '<center><p>Video '+((/(part|clip)_?\d/.test(av[0]+doc.URL)) ? 'part ' : '')+'found at ' + domainName(doc.URL) + '.</p><button type="button" style="padding:10px;width:98%">play</button></center><div id="flowplayer" style="display:none"></div>';
fn('BUTTON').onclick = function() { autoplay = true; insertVideo(); };
fn('BUTTON').focus();
} else {
insertVideo();
}
} else {
if(/^video(wing|zoo)$/.test(domain[1]) && !/\bnoflash\b/i.test(location.search)) {
console.log('yahvt: redirecting to location + noflash');
location.search = location.search ? location.search+'&noflash' : '?noflash';
}
var as = na('SCRIPT'), i;
for(i of as) {
if(/_url\s*=\s*\"video not found\"/i.test(i.innerHTML)) { doc.body.innerHTML = '<p>Video not found.</p>'; break; }
}
}
}
} catch(e) { console.log('yahvt:', e); }
}
function receiveMessage(event) {
function RestoreFormat() {
var frame = fn('#yahvt_currentview');
if(frame) frame.removeAttribute(id);
rn('#yahvt_fmtbtn');
rn('#yahvt_dimmer');
rn('#yahvt_topstyle');
}
function InsertButton() {
var spn, btn;
try {
switch(domain[1]) {
case 'animecenter':
case 'freeanime':
return nn('BUTTON#yahvt_fmtbtn,type=button,title=video width,style=float:left;,='+x, fn('.rating_div'));
case 'anilinkz':
spn = fn('#watchmode').parentNode;
btn = nn('BUTTON#yahvt_fmtbtn,type=button,title=video width,style=float:right;margin:12px 12px 0px 0px;,='+x);
spn.parentNode.insertBefore(btn, spn);
return btn;
case 'animeseason':
spn = fn('#video_views');
btn = nn('DIV#yahvt_fmtbtn,style=background:url(/images/video_icons.png) -171px 0 no-repeat;width:57px;height:55px;margin-right:55px;line-height:55px;cursor:pointer;,title=video width,?=<style>#yahvt_fmtbtn + div{display:none;}</style>'+x);
spn.parentNode.insertBefore(btn, spn);
return btn;
}
} catch(e) {
console.log(e);
}
spn = nn('SPAN,style=position:relative;');
btn = nn('BUTTON#yahvt_fmtbtn,type=button,title=video width,style=position:absolute;top:-21px;left:1px;,='+x, spn);
m.insertBefore(spn, frame.nextSibling);
return btn;
}
try {
//console.log('yahvt: received message', event);
if(typeof event.data != 'string') return;
switch(event.data.slice(0,11)) {
case 'videoformat':
var m = event.data.match(/(\d+)x(\d+)$/), x = parseInt(m[1]), y = parseInt(m[2])+(isFF ? 56 : 64), frame, frames = na('IFRAME'), txt, id, stl, zi=100000;
RestoreFormat();
for(m of frames) {
if(m.contentWindow === event.source) {
frame = m;
break;
}
}
//console.log('yahvt: detected frame:', frame);
if(!frame) switch(domain[1]) {
case 'anime-exceed':
frame = doc.querySelector('#player>iframe'); break;
default:
return;
}
m = frame.parentNode;
if(!m.id) m.id = 'yahvt_currentview';
id = '#' + m.id;
txt = MakeCSSString('html,body', { width: '100%', height: '100%', overflow: 'hidden'}) +
MakeCSSString(id, { width: frame.clientWidth, height: frame.clientHeight, min_height: frame.clientHeight}) +
MakeCSSString(id+(isFF ? '>iframe' : '>iframe:not(:-webkit-full-screen)'), { border: '0px !important', position: 'fixed', width: x+'px!important', height: y+'px!important', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', margin: '0 auto', max_width: '100%', max_height: '100%', z_index: zi});
txt += MakeCSSString('#yahvt_fmtbtn', {display: 'none' });
txt += MakeCSSString('#yahvt_dimmer>div', { background_color: 'black', opacity: '.85'}) +
MakeCSSString('#yahvt_dimmer>.topshade', { position: 'fixed', width: '100%', height: 'calc(50% - '+y/2+'px)', top: 0, left: 0, z_index: zi}) +
MakeCSSString('#yahvt_dimmer>.bottomshade', { position: 'fixed', width: '100%', height: 'calc(50% - '+y/2+'px)', bottom: 0, left: 0, z_index: zi}) +
MakeCSSString('#yahvt_dimmer>.leftshade', { position: 'fixed', width: 'calc(50% - '+x/2+'px)', height: y, top: 'calc(50% - '+y/2+'px)', left: 0, z_index: zi}) +
MakeCSSString('#yahvt_dimmer>.rightshade', { position: 'fixed', width: 'calc(50% - '+x/2+'px)', height: y, top: 'calc(50% - '+y/2+'px)', right: 0, z_index: zi});
InsertButton().onclick = function() { stl.disabled = false; };
stl = SetStyle(txt);
stl.id = 'yahvt_topstyle';
m = nn('DIV#yahvt_dimmer', m);
nn('div.topshade', m);
nn('div.bottomshade', m);
nn('div.leftshade', m);
nn('div.rightshade', m);
m.onclick = function() { stl.disabled = true; };
break;
case 'videoended':
RestoreFormat();
break;
}
} catch(e){ console.log(e); }
}
if(isTop && !/^(anime-exceed|animefreak|anime-sub|bestanimes|clipfish)$/.test(domain[1]))
window.addEventListener('message', receiveMessage, false);
// public domain by gnblizz
// contact me with my username + '@web.de'