Greasy Fork is available in English.

yahvt

yet another html5 video tool

Version vom 09.12.2015. Aktuellste Version

// ==UserScript==
// @name        yahvt
// @description yet another html5 video tool
// @namespace   gnblizz
// @include     http://anilinkz.tv/*
// @include     http://www.animeboy.org/*
// @include     http://www.animecenter.tv/*
// @include     http://www.animedreaming.tv/*
// @include     http://anime-exceed.com/*
// @include     http://www.animefreak.tv/*
// @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://ww1.animes-stream24.net/*
// @include     http://www.anime-sub.com/*
// @include     http://www.animetoon.eu/*
// @include     http://www.animetoon.tv/*
// @include     http://www.animeultima.io/*
// @include     http://animewow.eu/*
// @include     http://www.animewow.eu/*
// @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://dubbedanime.net/*
// @include     http://www.dubzonline.com/*
// @include     http://freeanime.com/*
// @include     http://www.gogoanime.com/*
// @include     http://www.goodanime.eu/*
// @include     http://www.goodanime.net/*
// @include     http://www.gooddrama.net/*
// @include     http://www.kumby.com/*
// @include     http://www.lovemyanime.net/*
// @include     http://www.otakucenter.com/*
// @include     http://www.theanime.tv/*
// @include     http://www.videozoo.me/*
// @include     http://www.waoanime.tv/*
// @include     *newembed*
// @include     *embed*
// @include     *gogo/*
// @include     *widget/*
// @include     http://player.arkvid.tv/*
// @version     1.04
// @grant       GM_xmlhttpRequest
// @icon        data:image/gif;base64,R0lGODlhMAAwAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAwADAAAALQnI+py+0Po5y02ouz3rz7D4biBJTmiabqyrbuC8fyHAf2jedpzuOvAAwKh6mhUfg7Hks3gHLpehptwIBTioxig0zrdStIgrslMFA8pCKp1oAZjXW6w/Mt/Nl2t8HeFl7o5QZgBagEYyawNxhUl7h4dlelFlZG+QVY6aglmIjjuKd50xla9RKI0mSCqaPJSMM0aEK4mhfbpSnTabM4WXrShtpHI6gqKvmKnCwns0tm2lOsLP3aUy08aK0zvc3d7b09Ei4+Tl5ufo6err7O3n5QAAA7
// @compatible  firefox
// ==/UserScript==
"use strict";
var domain = document.domain ? document.domain.match(/^(?:www\.)?(.*)$/)[1] : 'none';

function sites(){
  var a,i,o,e,b;
  switch(domain) {
  case 'animeseason.com':
    if(obj('#series_info'))
      SetStyle('table a:visited{color:gray;}table a:hover{color:#FC0;}');
    allowFullscreen('#video_source', '#player_list A');
    break;
  case 'anime-exceed.com':
    if(!/^\/cool\//.test(location.pathname))
      allowFullscreen((window.self==window.top)?'#player':'body');
    break;
  case 'animefreak.tv':
    i=(a=objs('.multi')).length;
    if(i)do {
      o = a[--i];
      e = o.getAttribute('onclick');
      if(e && /loadParts\('http/.test(e))
	o.onclick = function(event) {
	  var vid_file = decodeURIComponent(this.getAttribute('onclick').match(/loadParts\('([^']+)'/)[1]);
	  document.getElementById("player").innerHTML = '<video controls width="100%" height="412" src="' + vid_file + '" allowfullscreen="true" autoplay></video>';
	};
    } while(i);
    break;
  case 'bestanimes.tv':
    allowFullscreen('.post');
    break;
  case 'clipfish.de':
    obj('+SCRIPT', document.body).innerHTML = 'checkMobile=function(){isMobile=true;}';
    break;
  case 'freeanime.com':
    obj('+SCRIPT', document.body).innerHTML = '$(window).unbind();\n$("#header").css("background-attachment","scroll")';
    allowFullscreen('.z-video', 'ul.z-tabs-nav LI', 999);
    break;
  case 'videowing.me':
  case 'videozoo.me':
    if(!/\bnoflash\b/i.test(location.search))
      location.search = location.search ? (location.search+'&noflash') : '?noflash';
  case 'player.arkvid.tv':
  case 'gogoanime.com':
    return 1;
  case 'yucache.net':
  case 'yourupload.com':
    if(document.URL.match(/[?&]/) == '&') // bad URL?
       document.location.replace(document.URL.replace('&', '?'));
  default:
    return(/\/((?:new)?embed|gogo\/|widget\/)/.test(document.URL));
  }

function allowFullscreen(video, mirrors, delay) {
  if(delay)
    window.setTimeout( function() { allowFullscreen(video, mirrors); }, delay);
  else {
    if(mirrors) {
      var a = document.querySelectorAll(mirrors), i = a.length;
      if(i) do {
	a[--i].addEventListener('click', function() {
	  window.setTimeout( function() { document.querySelector(video+' IFRAME').setAttribute('allowfullscreen', 'true'); }, 99);
	});
      } while(i);
    }
    var ifr = document.querySelector(video+' IFRAME');
    if(ifr) ifr.setAttribute('allowfullscreen', 'true');
    else console.log(video+' IFRAME not found in '+document.URL);
  }
}}

function findVideoFile() {
  var s, m, a, i, p;
  var timer;//videozoo
  s = obj('VIDEO', document.body);
  if(s) {
    m = s.getAttribute('src'); if(m) return m;
    if((a = obj('SOURCE', s)) && (m = a.getAttribute('src'))) return m;
  }
  a = objs('SCRIPT', document.body); i = a.length;
  if(i) {
    do {
      s = getScript(a[--i]);
      m = s.match(/"(http:\/\/[^"]+\.(?:mp4|flv)\b[^"]*)"/i); if(m) return m[1];
      m = s.match(/"(.+\.php\b.+\.(?:mp4|flv))"/i); if(m) return m[1];
      m = s.match(/"([^"]+\bpicasa\.php\b[^"]+)"/i); if(m) return m[1];
      m = s.match(/"(https\:\/\/[^"]*\.googlevideo\.com\/videoplayback[^"]+)"/i); if(m) return m[1];
      m = s.match(/"(https\:\/\/[^"]*\.googleusercontent.com\/[^"]+)"/i); if(m) return m[1];
    } while(i); i = a.length;
    // videonest.net code removed, due to exception 403008
  }
  if(/trollvid\.net$/i.test(domain)) {
    if(i) do {
        s = a[--i].innerHTML; m = s.match(/['"](http.*data.*file.*)['"]/i); if(m) return m[1];
    } while(i);
    a = objs('SCRIPT', document.head); i = a.length;
    if(i) do {
      s = a[--i].innerHTML; m = s.match(/unescape\(atob\('(.*)'/i); if(m) { m = unescape(atob(m[1])); if(/\.(mp4|flv)/i.test(m)) return m;}
    } while(i);
  } else if('videobam.com' == domain) {
    if(i) do {
      s = a[--i].innerHTML; m = s.match(/['"](http:\\\/\\\/[^'"]+\.(?:mp4|flv)\b[^'"]*)['"]/i); if(m) return m[1].replace(/\\\//g,'/');
    } while(i); i = a.length;
  }
  a = objs('PARAM'); i = a.length; if(i) do {
    p = a[--i].getAttribute('value'); m = p.match(/video=(http:\/\/[^'"]+\.mp4[^'"&]*)/i); if(m) return m[1];
  } while(i);
  a = objs('EMBED'); i = a.length; if(i) do {
    p = a[--i].getAttribute('src'); m = p.match(/video=(http:\/\/[^'"]+\.mp4[^'"&]*)/i); if(m) return m[1];
  } while(i);

function getScript(s) {
  return unescape(s.innerHTML.replace(/\s\/\/.*$/gm,'').replace(/\s+/gm,' ').replace(/\/\*.*\*\//g,'').replace(/'/g,'"'));
}}

(function yahvt() {
  if(sites()) {
    var vf, autoplay = false;
    try { vf = findVideoFile(); } catch(e) { console.log('yahvt: ' + e); }
    if(vf) {
      vf = decodeURIComponent(vf).replace(/\?/g,'&').replace('&','?');
      
      if(GetCookie('us_autoplay','')=='yes') {
	SetCookie('us_autoplay', '', -1);
	autoplay = true;
      }
      if(window.self != window.top && !autoplay) {
	document.body.innerHTML = '<center><p>Video '+((/(part|clip)_?\d/.test(vf+document.URL)) ? 'part ' : '')+'found at ' + domainName(document.URL) + '.</p><button type="button" style="padding:10px;width:98%">play</button></center><div id="flowplayer" style="display:none"></div>';
	obj('BUTTON').onclick = function() { autoplay = true; insertVideo(); }
      } else {
	insertVideo();
      }
    } else {
      var as = objs('SCRIPT'), i = as.length;
      if(i) do {
	if(/_url.*=.*\"video not found\"/i.test(as[--i].innerHTML)) {
	  document.body.innerHTML = '<p>Video not found.</p>';
	  break;
	}
      } while(i);
    }
  }

function insertVideo() {
  document.body.innerHTML = '<video width="100%" height="100%" ' + (autoplay ? 'autoplay ' : '') + 'controls src="' + vf + '"></video><div id="flowplayer" style="display:none"></div>';
  var v = obj('VIDEO'), fs = GetCookie('us_fullscreen', '')=='yes', nvf = NextPart(document.URL), retry = 3;
  console.log('starting ' + domain + (nvf ? (' video part '+nvf[2]+': ') : ' video: ') + vf);
  if(fs) SetCookie('us_fullscreen', '', -1);
  v.oncanplay = function(e) {
    if(fs) SetFullScreenMode();
    // v.parentNode.onclick=function(ev) { ev.preventDefault(); ev.stopPropagation(); };
  };
  v.onerror = function(e) {
    if((e.target.error.code == 4) && (--retry >= 0)) {
      //console.log('retry ' + retry);
      v.removeAttribute('src');
      if(vf.match(/&html5(=true)?/))
	vf = vf.replace(/&html5(=true)?/, '&noflash');
      else if(vf.match(/&noflash(=true)?/))
	vf = vf.replace(/&noflash(=true)?/, '');
      else
	vf = vf + '&html5=true';
      v.setAttribute('src', vf);
      v.setAttribute('autoplay', 'true');
      return;
    }
    if((e.target.error.code==4) && nvf && (nvf[0]>2))
      document.body.innerHTML = '<center>The End</center><div id="flowplayer" style="display:none"></div>';
    else if(!/\bnoflash\b/.test(location.search))
      location.search = location.search ? location.search + '&noflash' : '?noflash';
    else
      console.log('e.target.error.code='+e.target.error.code);
  };
  v.onended = function(e) {
    var scr = EndFullScreenMode();
    if(window.self != window.top && !obj('#VideoCloseButton')) {
      var btnClose = MakeAButton('x', 'close', 0);
      btnClose.id = 'VideoCloseButton';
      btnClose.onclick = function(e){ location.replace('about:blank'); };
    }
    if(nvf) {
      console.log('redirecting to part '+nvf[0]);
      var btnNext = MakeAButton(nvf[0], 'on to part '+nvf[0], 1);
      btnNext.onclick = function(e) {
	SetCookie('us_autoplay', 'yes', 3);
	SetCookie('us_fullscreen', 'yes', (scr ? 3 : -1));
	location.replace(nvf[1]);
      };
      switch(resourceExists(nvf[1])) { // can't tell if it's valid, though
      case true: btnNext.click();
      case false: RemoveElement(btnNext);
      }
    } else if(vf) {
      var m = vf.match(/^(.*(?:part|clip)_?0?)(\d+)(.*)$/);
      if(m) {
	var inp = parseInt(m[2])+1;
	vf = m[1] + inp + m[3];
	var btnNext2 = MakeAButton(inp, 'on to part '+inp, 1);
	btnNext2.onclick = function(e) {
	  SetCookie('us_fullscreen', 'yes', (scr ? 3 : -1));
	  insertVideo();
	};
	console.log('about to insert video part '+inp);
	if(GM_xmlhttpRequest) {
	  var rv = GM_xmlhttpRequest({
	    url: vf,
	    method: "HEAD",
	    onload: function(response) {
	      console.log(' response.status='+response.status
	        +'\n response.statusText='+response.statusText
	        +'\n response.readyState='+response.readyState
	        +'\n response.responseHeaders='+response.responseHeaders
	        +'\n response.responseText='+response.responseText
	        +'\n response.finalUrl='+response.finalUrl
	        +'\n');
	      if(/^Content-Type:[^\n]*video/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);
	    }
	  });
	} else {
	  switch(resourceExists(vf)) { // CORS blocked most likely
	  case true: btnNext2.click();
	  case false: RemoveElement(btnNext2);
	  }
	}
      } else {
	//console.log('no match');
      }
    }
  };//.onended

function NextPart(name) {
  var m = name.match(/^(.*(?:part|clip)_?0?)(\d+)(.*)$/);
  if(m) {
    m[2] = parseInt(m[2]);
    m[1] = m[1]+(m[2]+1)+m.pop();
    m[0] = m[2]+1;
    }
  return m;
}}}());

function resourceExists(url){
  try {
    var http = new XMLHttpRequest();
    http.open('HEAD', url, false);
    http.send();
    return http.status != 404;
  } catch(e){}
}

function SetFullScreenMode() {
  var v = obj('VIDEO'); // full-screen-api.allow-trusted-requests-only;false (about:config)
  try{
    v.mozRequestFullScreen();
  }catch(e){
    console.log('mozRequestFullScreen did throw an error.');
    alert('Please inform the autor of yahvt,\nthat someone uses it with a browser\nwhich is possibly not FireFox.\nThank You');
  }
}

function EndFullScreenMode() {
  try {
    if(document.mozFullScreenElement) {
      document.mozCancelFullScreen();
      return true;
    }
  }catch(e){}
  return false;
}

function obj(name, parent) {
  if(!parent) parent = document;
  var node = null;
  switch (name.charAt(0)) {
  case '#': node = parent.getElementById(name.slice(1)); break;
  case '.': node = parent.getElementsByClassName(name.slice(1))[0]; break;
  case '+': node = document.createElement(name.slice(1).toUpperCase()); if(parent != document) parent.appendChild(node); break;
  default:  node = parent.getElementsByTagName(name)[0]; break;
  }
  return node;
}

function objs(name, parent) {
  if(!parent) parent = document;
  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 SetCookie(name, value, min) {
  if(!min) min = 10080; // a week as default
  var d = new Date();
  d.setTime(min*60000+d.getTime());
  document.cookie=name+'='+value+';expires='+ d.toUTCString()+';'+'path=..';
}

function GetCookie(name, dflt) {
  var r = new RegExp(name+'=([^;]+)', '');
  var m = document.cookie.match(r);
  return(m ? m[1] : dflt);
}

function MakeAButton(caption, help, style, parent) {
  var b = obj('+BUTTON');
  b.setAttribute('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 = document.body;
  parent.appendChild(b);
  return b;
}

// public domain by gnblizz
// contact me with my username + '@web.de'