// ==UserScript== // @name yahvt // @description yet another html5 video tool // @namespace gnblizz // @include http://anilinkz.tv/* // @include http://www.animeboy.org/* // @include http://www.animeboy.tv/* // @include http://www.animecenter.tv/* // @include http://www.animedreaming.tv/* // @include http://anime-exceed.com/* // @include http://www.animefreak.tv/* // @include http://www.animefushigi.co/* // @include http://www.animefushigi.com/* // @include http://www.animehere.com/* // @include http://www.animenova.org/* // @include http://www.animenova.tv/* // @include http://www.animeplus.tv/* // @include http://www.animeseason.com/* // @include http://www.animesky.net/* // @include http://ww1.animes-stream24.net/* // @include http://www.anime-sub.com/* // @include http://www.animetoon.eu/* // @include http://www.animetoon.org/* // @include http://www.animetoon.tv/* // @include http://www.animeultima.io/* // @include http://animewow.eu/* // @include http://www.animewow.eu/* // @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.eu/* // @include http://www.dramagalaxy.com/* // @include http://www.dramagalaxy.tv/* // @include http://dubbedanime.net/* // @include http://www.dubzonline.cm/* // @include http://www.dubzonline.com/* // @include http://freeanime.com/* // @include http://www.gogoanime.com/* // @include http://www.goodanime.co/* // @include http://www.goodanime.eu/* // @include http://www.goodanime.net/* // @include http://www.gooddrama.net/* // @include http://www.lovemyanime.net/* // @include http://www.theanime.tv/* // @include http://www.videozoo.me/* // @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/* // @version 1.11 // @grant GM_xmlhttpRequest // @icon data:image/gif;base64,R0lGODlhMAAwAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAwADAAAALQnI+py+0Po5y02ouz3rz7D4biBJTmiabqyrbuC8fyHAf2jedpzuOvAAwKh6mhUfg7Hks3gHLpehptwIBTioxig0zrdStIgrslMFA8pCKp1oAZjXW6w/Mt/Nl2t8HeFl7o5QZgBagEYyawNxhUl7h4dlelFlZG+QVY6aglmIjjuKd50xla9RKI0mSCqaPJSMM0aEK4mhfbpSnTabM4WXrShtpHI6gqKvmKnCwns0tm2lOsLP3aUy08aK0zvc3d7b09Ei4+Tl5ufo6err7O3n5QAAA7 // @compatible firefox // @downloadURL none // ==/UserScript== "use strict"; var doc=document, isTop=window.self==window.top, domain; try { domain = doc.domain.match(/^(?:www\.)?(.*)$/)[1]; } catch(e) { domain = 'unknown'; alert('document.domain'); } yahvt(); function sites(){ var a,i,o,e,b; //console.log('domain='+domain); switch(location.hostname.match(/([^.]+)\.\w+$/)[1]) { case 'anilinkz'://.tv allowFullscreen('#player'); 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=objs('.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 = ''; }; } break; case 'animefushigi'://.co,com allowFullscreen('#vidboxx', '.videoloadbg'); break; case 'animehere'://.com allowFullscreen('#playbox'); break; case 'animenova'://.org,tv case 'animeplus'://.tv case 'animesky'://.net case 'animetoon'://.eu,org,tv case 'animewow'://.eu,org case 'dramagalaxy'://.com,eu,tv case 'dramago'://.com case 'gooddrama'://.net allowFullscreen('#streams'); break; case 'animeseason'://.com if(obj('#series_info')) SetStyle('table a:visited{color:gray;}table a:hover{color:#FC0;}'); allowFullscreen('#video_source', 0, '#player_list A'); break; case 'animeboy'://.org,tv case 'dramastream'://.org allowFullscreen('div[align]', 'center'); break; case 'anime-sub'://.com allowFullscreen('#movie-content'); break; case 'animeultima'://.io allowFullscreen('#pembed'); break; case 'bestanimes'://.tv allowFullscreen('.post'); break; case 'clipfish'://.de obj('+SCRIPT', doc.body).innerHTML = 'checkMobile=function(){isMobile=true;}'; break; case 'freeanime'://.com obj('+SCRIPT', doc.body).innerHTML = '$(window).unbind();\n$("#header").css("background-attachment","scroll")'; allowFullscreen('.z-video', 0, 'ul.z-tabs-nav LI', 999); break; case 'dubzonline'://.cm,com case 'theanime'://.tv case 'goodanime'://.co,eu,net case 'videozoo'://.me allowFullscreen('#content'); return(location.pathname == '/embed.php'); case 'lovemyanime'://.net allowFullscreen('.player-area'); break; case 'animes-stream24'://.net allowFullscreen('#main'); break; case 'gogoanime'://.com return location.pathname=='/flowplayer/' || allowFullscreen('#content'); case 'arkvid': return domain=='player.arkvid.tv'; case 'mangaotaku': // animeboy,dramastream return 1;// return(location.pathname == '/dr_video_player.php'); 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('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) { //if(!v) v = obj('VIDEO'); (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 NoScriptClickBugHandler(event) { var v = event.currentTarget; if(v.paused) v.play(); else v.pause(); } 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('Packed script detected.'); } catch(e) { console.log('Packed script parse error.'); } } return s = unescape(s.replace(/\s\/\/.*$/gm,'').replace(/\s+/gm,' ').replace(/\/\*.*\*\//g,'').replace(/'/g,'"')); } } 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[imy]*$/.test(pattern.toSource()); do { var m = pattern.exec(s); if(!m) break; add(decodeURIComponent(unescape(m[1]))); } while(g); } var v = [], s, m, a, i, p; a = obj('VIDEO', doc.body); if(a) {//usually doesn't exist yet add(a.getAttribute('src')); a = objs('SOURCE', a); for(i of a) { add(i.getAttribute('src')); } } a = objs('SCRIPT', (domain=='videozoo.me' ? doc.documentElement : doc.body)); for(i of a) { if(getScript(i)) { find(/"(http:\/\/[^"]+\.(?:mp4|flv)\b[^"]*)"/gi); find(/"(.+\.php\b.+\.(?:mp4|flv))"/gi); find(/"([^"]+\bpicasa\.php\b[^"]+)"/gi); find(/"(https\:\/\/[^"]*\.google(?:video\.com\/videoplayback|usercontent.com\/)[^"]+)"/gi); } } if(/trollvid\.net$/i.test(domain)) {//Is this of any use today? for(i of a) { s = i.innerHTML; m = s.match(/['"](http.+?data.*?file.*?)['"]/i); addm1(m); } a = objs('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); } } } else if('videobam.com' == domain) {//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,'/')); } } try {// even if it looks wierd... m = doc.querySelector('#flowplayer+script').innerHTML.replace(/\s+/g, ' ').match(/\/\* playlist\: \[ \{ url\: '(.*)'/)[1]; if(!/\<|\>/.test(m)) { console.log('html5_path in comment found.'); add(m); } } catch(e){} try {// animeboy add(unescape(obj('NOSCRIPT').innerHTML.match(/duration: ' + Math.floor(t/60) + ':' + ('0' + Math.floor(t%60)).slice(-2); } else div.style.color = '#666'; m = src.match(/https?:\/\/([^:?/]+)/); if(m) txt += '
video host name: ' + m[1]; m = src.match(/.*\/([^?/]*)/); if(m) txt += '
video file name: ' + m[1]; txt += '

A - toggle stretch mode
F - toggle full screen mode
I - '+(meta ? 'this' : 'some')+' info
Z - toggle zoom to 100%'; if(meta) { adr.push('@web.de?subject=yahvt%20at%20', document.domain); txt += '

yahvt is public domain by gnblizz.'; } div.innerHTML = txt; v.parentNode.appendChild(div); window.setTimeout(StopInfo, 15000); } function StopInfo() { var o = v.parentNode.querySelector('div.info'); if(o) RemoveElement(o); } function NextPart(name) { var m = name.match(/^(.*(?:part|clip)_?0?)(\d+)(.*)$/); if(m) { m[2] = parseInt(m[2]);// current part number m[1] = m[1]+(m[0]=m[2]+1)+m.pop();// next part URL } return m; } var nvf = NextPart(doc.URL), txt = ''; if(obj('#flowplayer')) txt += '
'; else if(obj('#player')) txt += '
'; doc.body.innerHTML = txt; console.log('starting ' + domain + (nvf ? (' video part '+nvf[2]) : ' video')); var v = obj('VIDEO'); v.onloadedmetadata = function(event) { StopInfo(); //console.log('now playing: '+v.currentSrc); if(remembered('fullscreen', true)=='yes') SetFullScreenMode(v); v.focus(); }; v.onkeypress = function(event) { if(event.altKey || event.metaKey || event.ctrlKey) return; var key = event.key; if(key.length == 1) { switch(key.toUpperCase()) { case 'A':// toggle stretch mode v.style.objectFit = v.style.objectFit ? '' : 'fill'; v.parentNode.style.height = '100%'; break; case 'H':// toggle LMB behavior ((altClick = !altClick) ? v.addEventListener : v.removeEventListener).call(v, 'click', NoScriptClickBugHandler, false); break; case 'I':// show some info ShowSomeInfo(true); break; case 'F':// toggle full screen if(!EndFullScreenMode()) SetFullScreenMode(v); break; case 'Y': case 'Z':// toggle zoom mode if(v.parentNode.style.width) { v.parentNode.style.width = ''; v.parentNode.style.margin = ''; } else if(v.videoWidth) { v.parentNode.style.width = v.videoWidth+'px'; v.parentNode.style.minHeight = v.videoHeight+'px'; v.parentNode.style.margin = '0px auto'; } break; default: return; } } else if(!event.shiftKey) { switch(key) { case 'ArrowRight': v.currentTime += v.paused ? .5 : 5; break; case 'ArrowLeft': v.currentTime -= v.paused ? .5 : 5; break; default: return; } } else return; event.preventDefault(); event.stopImmediatePropagation(); }; 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('video load error'); if(nvf && nvf[2]>1) doc.body.innerHTML = '


No part '+nvf[2]+' could be found, so this must be...

The End
'; remembered('fullscreen', true);// discard value }; v.onended = function(event) { var wasFullScreen = EndFullScreenMode(); if(!isTop && !obj('#VideoCloseButton')) { var btnClose = MakeAButton('x', 'close', 0); btnClose.id = 'VideoCloseButton'; btnClose.onclick = function(event){ location.replace('about:blank'); }; } if(nvf) { var btnNext = MakeAButton(nvf[0], 'on to part '+nvf[0], 1); btnNext.onclick = function(event) { console.log('redirecting to part '+nvf[0]); Remember('autoplay'); Remember('fullscreen', (wasFullScreen ? 'yes' : '')); location.replace(nvf[1]); }; TestResource(nvf[1], btnNext); } else {//nfv var vf = v.currentSrc, m = vf.match(/^(.*(?:part|clip)_?0?)(\d+)(.*)$/); if(m) { console.log('using alternate next part algorithm (experimental)'); var inp = parseInt(m[2])+1; vf = m[1] + inp + m[3]; var btnNext2 = MakeAButton(inp, 'on to part '+inp, 1); btnNext2.onclick = function(event) { Remember('fullscreen', (wasFullScreen ? 'yes' : '')); av = [vf]; insertVideo(); }; console.log('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('video resource found'); btnNext2.click(); } else { console.log('invalid video resource'); } RemoveElement(btnNext2); }, onerror: function(response) { console.log('--onerror-response:\n'+response.responseHeaders); RemoveElement(btnNext2); } }); } catch(e) { TestResource(vf, btnNext2); } }//m }//!nfv };//v.onended ShowSomeInfo(false); OnFullScreenChange(function(event) { obj('VIDEO').focus(); }); } try { if(sites()) { var av = findVideoFiles(); if(av && av.length) { if(av[0].match(/\/blank.mp4$/)) av.push(av.shift()); var v = obj('VIDEO'); if(v) { v.pause(); v.src = ''; } //SetStyle('body,html{padding:0px;margin:0px;height:100%;overflow:hidden;background:#000;color:#fff;font-size:14px;}\nvideo{outline:0;}\n#player,#flowplayer{display:none}\n.info{position:absolute;top:50px;left:50px;text-shadow:1px 1px black;}'); SetStyle( MakeCSSStringX('body,html',{padding:0, margin:0, height:'100%', overflow:'hidden', background:'#000', color:'#fff', font_size:14}) + MakeCSSStringX('video', {outline:0}) + MakeCSSStringX('#player,#flowplayer', {display:'none'}) + MakeCSSStringX('.info', {position:'absolute', top:50, left:50, text_shadow:'1px 1px black'}) + MakeCSSStringX('.info a', {color:'unset'}) ); console.log('Found '+av.length+' video source'+(av.length==1 ? '' : 's')+' at '+domain+'.'); var autoplay = remembered('autoplay', true) == 'yes'; if(!isTop && !autoplay) { doc.body.innerHTML = '

Video '+((/(part|clip)_?\d/.test(av[0]+doc.URL)) ? 'part ' : '')+'found at ' + domainName(doc.URL) + '.

'; autoplay = true; obj('BUTTON').onclick = function() { insertVideo(); } } else { insertVideo(); } } else { if(/^video(?:wing|zoo).me$/.test(domain) && !/\bnoflash\b/i.test(location.search)) { console.log('redirecting to location + noflash'); location.search = location.search ? location.search+'&noflash' : '?noflash'; } var as = objs('SCRIPT'), i; for(i of as) { if(/_url\s*=\s*\"video not found\"/i.test(i.innerHTML)) { doc.body.innerHTML = '

Video not found.

'; break; } } } } } catch(e) { console.log('yahvt: ' + e); } } //()); function TestResource(url, btn) { var req = new XMLHttpRequest(); if(req) { req.open('HEAD', url, true); req.onloadend = function () { switch(req.status) { case 200: if(req.statusText != 'Not Found') btn.click(); case 404: RemoveElement(btn); } }; req.send(); } } function obj(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]; case '+': var a = name.split(','); name = a.shift(); var m = name.match(/^\+([A-Za-z]+)\b/), node = doc.createElement(m[1]); m = name.match(/\.\w+/); if(m) node.className = m[0].slice(1); m = name.match(/#\w+/); if(m) node.id = m[0].slice(1); while(a.length) { var l = a.shift().split('='); if(!l[1]) l.push(l[0]); else if(/^".*"$/.test(l[1])) l[1] = l[1].slice(1,-1); node.setAttribute(l[0], l[1]); }; if(parent != doc) parent.appendChild(node); return node; } return parent.getElementsByTagName(name)[0]; } function objs(name, parent) { if(!parent) parent = doc; return (name.charAt(0)=='.') ? parent.getElementsByClassName(name.slice(1)) : parent.getElementsByTagName(name); } function SetStyle(style) { obj('+STYLE', obj('HEAD')).innerHTML = style; } function RemoveElement(node) { if(typeof(node)=='string') node = obj(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) { switch(value) { case '': sessionStorage.removeItem(name); break; case undefined: value = 'yes'; default: sessionStorage.setItem(name, value); } } function remembered(name, forget) { var x = sessionStorage.getItem(name); if(forget) sessionStorage.removeItem(name); return x; } function MakeAButton(caption, help, style, parent) { var b = obj('+BUTTON,type=button'); b.innerHTML = caption; if(help) b.setAttribute('title', help); if(typeof(style)=='number') style = 'top:0px;right:'+(30*style)+'px;height:25px;min-width:25px;'; b.setAttribute('style', style); if(!b.style.position) b.style.position = 'absolute'; if(!parent) parent = doc.body; parent.appendChild(b); return b; } function MakeCSSString(d) { var names = Object.getOwnPropertyNames(d), style = '', x, v; for(x of names) { v = d[x]; if(typeof(v) == 'number') v += 'px'; style += x.replace(/_/g,'-') + ':' + v + '; ' } return style; } function MakeCSSStringX(name, d) { return name + '{' + MakeCSSString(d) + '}\n'; } // public domain by gnblizz // contact me with my username + '@web.de'