Onens.Clean.Player

Thanks to OpenGG, Harv.c, KaFan15536900

  1. // ==UserScript==
  2. // @name Onens.Clean.Player
  3. // @namespace http://onens.com/
  4. // @description Thanks to OpenGG, Harv.c, KaFan15536900
  5. // @version 2.3.5
  6. // @include http://*/*
  7. // @include https://*/*
  8. // @grant GM_xmlhttpRequest
  9. // @run-at document-end
  10. // ==/UserScript==
  11.  
  12. Function.prototype.bind = function() {
  13. var fn = this,
  14. arg = Array.prototype.slice.call(arguments),
  15. obj = arg.shift();
  16. return function() {
  17. return fn.apply(obj, arg.concat(Array.prototype.slice.call(arguments)));
  18. };
  19. };
  20.  
  21. String.prototype.sprintf = function() {
  22. var str = this.toString(),
  23. arg = Array.prototype.slice.call(arguments);
  24. if (arg.length)
  25. for (var i in arg)
  26. str = str.replace('%s', arg[i]);
  27.  
  28. return str;
  29. };
  30.  
  31. var OCPlayer = {
  32. done: [],
  33. host: 'http://code.taobao.org/svn/ocp/trunk/player/',
  34. rule: [{ // YOUKU_COM
  35. find: /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/swf\/q?(player|loader)([^\.]+)?\.swf/i,
  36. replace: 'loader.swf'
  37. }, { // YOUKU_OUT
  38. find: /http:\/\/player\.youku\.com\/player\.php\/.*sid\/([\w=]+).*(\/v)?\.swf.*/i,
  39. replace: 'loader.swf?showAd=0&VideoIDS=$1'
  40. }, { // KU6_COM
  41. find: /http:\/\/player\.ku6cdn\.com\/default\/.*\/\d+\/(v|player)\.swf/i,
  42. replace: 'ku6.swf'
  43. }, { // KU6_OUT
  44. find: /http:\/\/player\.ku6\.com\/(inside|refer)\/([^\/]+)\/v\.swf.*/i,
  45. replace: 'ku6_out.swf?vid=$2'
  46. }, { // IQIYI_COM
  47. // find: /http:\/\/www\.iqiyi\.com\/(player\/\d+\/Player|common\/flashplayer\/\d+\/(Main|Coop|Share|Enjoy)?Player_?.*)\.swf/i,
  48. find: /http:\/\/www\.iqiyi\.com\/(player\/(\d+\/Player|[a-z0-9]*)|common\/flashplayer\/\d+\/(((PPS)?Main|Share|Enjo.)?Player[^\.]*|1355f98c2359))\.swf/i,
  49. replace: function(el, find) {
  50. var url = 'iqiyi.swf';
  51. if (!/(^((?!baidu|61|178).)*\.iqiyi\.com|pps\.tv)/i.test(window.location.host))
  52. url = 'iqiyi_out.swf';
  53. else if (document.querySelector('span[data-flashplayerparam-flashurl]'))
  54. url = 'iqiyi5.swf';
  55.  
  56. this.Reload.bind(this, el, find, url)();
  57. }
  58. // }, { // IQIYI_P2PCORE
  59. // find: /^http:\/\/www\.iqiyi\.com\/common\/flashplayer\/(?!20151119)\d+\/30.*\.swf/i,
  60. // replace: 'http://www.iqiyi.com/common/flashplayer/20151119/3022.swf'
  61. }, { // IQIYI_BILIBILI
  62. find: /http:\/\/www\.bilibili\.tv\/iqiyi\.swf/i,
  63. replace: 'iqiyi.swf'
  64. }, { // IQIYI_PPS
  65. find: /http:\/\/www\.iqiyi\.com\/common\/.*\/pps[\w]+.swf/i,
  66. replace: 'iqiyi_out.swf'
  67. }, { // IQIYI_OUT
  68. find: /http:\/\/(player|dispatcher)\.video\.i?qiyi\.com\/(.*[\?&]vid=)?([^\/&]+).*/i,
  69. replace: function(el, find) {
  70. var url = 'iqiyi_out.swf?vid=$3',
  71. match = (el.data || el.src).match(/(autoplay)=\d+/ig);
  72. if (match)
  73. url += '&' + match.join('&');
  74.  
  75. this.Reload.bind(this, el, find, url)();
  76. }
  77. }, { // TUDOU_COM
  78. find: /http:\/\/js\.tudouui\.com\/.*PortalPlayer[^\.]*\.swf/i,
  79. replace: 'tudou.swf'
  80. }, { // TUDOU_OLC
  81. find: /http:\/\/js\.tudouui\.com\/.*olc[^\.]*\.swf/i,
  82. replace: 'http://code.taobao.org/svn/ocp/trunk/player/olc_8.swf'
  83. }, { // TUDOU_SP
  84. find: /http:\/\/js\.tudouui\.com\/.*SocialPlayer_[^\.]*\.swf$/i,
  85. replace: 'http://code.taobao.org/svn/ocp/trunk/player/sp.swf'
  86. }, { // LETV_COM
  87. find: /http:\/\/.*letv[\w]*\.com\/(hz|.*\/((?!(Live|seed|Disk))(S[\w]{2,3})?(?!Live)[\w]{4}|swf))Player*\.swf\/?\??/i,
  88. replace: function(el, find) {
  89. /^v\.baidu\.com/i.test(window.location.host) || this.Reload.bind(this, el, find, 'http://code.taobao.org/svn/ocp/trunk/player/letv.swf?')();
  90. }
  91. }, { // LETV_COM
  92. find: /http:\/\/.*letv[\w]*\.com\/.*\/(letv-wrapper|letvbili|lbplayer)\.swf/i,
  93. replace: 'letv.swf'
  94. // }, { // LETV_SKIN
  95. // find: /http:\/\/.*letv[\w]*\.com\/p\/\d+\/\d+\/(?!15)\d*\/newplayer\/\d+\/S?SLetvPlayer\.swf/i,
  96. // replace: 'http://player.letvcdn.com/p/201407/24/15/newplayer/1/SSLetvPlayer.swf'
  97. }, { // LETV_CLOUD
  98. find: /http:\/\/assets\.dwstatic\.com\/.*\/vpp\.swf/i,
  99. replace: 'http://yuntv.letv.com/bcloud.swf'
  100. }, { // LETV_OUT
  101. find: /http:\/\/.*letv\.com\/player\/swfplayer\.swf(\?.*)/i,
  102. replace: 'letv.swf$1'
  103. }, { // PPLIVE
  104. find: /http:\/\/player\.pplive\.cn\/ikan\/.*\/player4player2\.swf/i,
  105. replace: 'player4player2.swf'
  106. }, { // SOHU_COM
  107. find: /http:\/\/(tv\.sohu\.com\/upload\/swf\/(p2p\/)?\d+|(\d+\.){3}\d+\/webplayer)\/(Main|PlayerShell)\.swf/i,
  108. replace: 'sohu/sohu_live.swf'
  109. }],
  110.  
  111. extra: [{ // TUDOU_OUT
  112. find: /http:\/\/www\.tudou\.com\/.*(\/v\.swf)?/i,
  113. replace: function(el, find) {
  114. if (/firefox/i.test(navigator.userAgent)) {
  115. GM_xmlhttpRequest({
  116. url: el.data || el.src,
  117. method: 'HEAD',
  118. onload: function(response) {
  119. var url = response.finalUrl;
  120. if (url) {
  121. url = url.replace(/http:\/\/js\.tudouui\.com\/.*?\/olc_[^.]*?\.swf/i, this.host + 'olc_8.swf');
  122. url = url.replace(/http:\/\/js\.tudouui\.com\/.*?\/SocialPlayer_[^.]*?\.swf/i, this.host + 'sp.swf');
  123. this.Reload.bind(this, el, find, url)();
  124. }
  125. }.bind(this)
  126. });
  127. }
  128. }
  129. }],
  130.  
  131. init_css: 'object,embed{-webkit-animation-duration:.001s;-webkit-animation-name:playerInserted;-ms-animation-duration:.001s;-ms-animation-name:playerInserted;-o-animation-duration:.001s;-o-animation-name:playerInserted;animation-duration:.001s;animation-name:playerInserted;}@-webkit-keyframes playerInserted{from{opacity:0.99;}to{opacity:1;}}@-ms-keyframes playerInserted{from{opacity:0.99;}to{opacity:1;}}@-o-keyframes playerInserted{from{opacity:0.99;}to{opacity:1;}}@keyframes playerInserted{from{opacity:0.99;}to{opacity:1;}}',
  132.  
  133. tips_css: '.ocplayer_tips{font:12px Arial, Verdana;padding:0 8px;cursor:default;border:1px solid #d5d5d5;line-height:25px;opacity:.2;background:#f5f5f5;position:fixed;right:0;bottom:-1px;z-index:999999}.ocplayer_tips:hover{opacity:.8}',
  134.  
  135. tips_html: '<span style="color:green">Onens.Clean.Player \u5DF2\u542F\u7528</span> &nbsp; <a href="http://gesion.duapp.com/script/onens.clean.player.user.js" style="color:red" title="\u5347\u7EA7\u65B0\u7248" target="_blank">\u5347\u7EA7</a> &nbsp; <a href="http://blog.onens.com/onens-clean-player.html" style="color:blue" title="\u53CD\u9988\u95EE\u9898" target="_blank">\u53CD\u9988</a> &nbsp; <a href="http://blog.onens.com/donation" style="color:orange" title="\u6350\u52A9\u9879\u76EE" target="_blank">\u6350\u52A9</a> &nbsp; <a href="javascript:;" class="tips_close" style="color:gray" title="\u9690\u85CF\u63D0\u793A">\u9690\u85CF</a>',
  136.  
  137. Handler: function(e) {
  138. if (e.animationName != 'playerInserted')
  139. return;
  140.  
  141. var el = e.target;
  142. if (this.done.indexOf(el) != -1)
  143. return;
  144.  
  145. this.done.push(el);
  146.  
  147. var player = el.data || el.src;
  148. if (!player)
  149. return;
  150.  
  151. for (var i in this.rule) {
  152. var find = this.rule[i]['find'];
  153. if (find.test(player)) {
  154. var replace = this.rule[i]['replace'];
  155. if (typeof replace == 'function')
  156. this.flag ? replace.bind(this, el, find)() : this.list.push(replace.bind(this, el, find));
  157. else
  158. this.flag || this.Reload.bind(this, el, find, replace)();
  159.  
  160. break;
  161. }
  162. }
  163. },
  164.  
  165. Reload: function(el, find, replace) {
  166. // replace = /^https?:\/\//i.test(replace) ? replace : (this.flag ? chrome.extension.getURL('player/' + replace) : this.host + replace);
  167. replace = /^https?:\/\//i.test(replace) ? replace : this.host + replace;
  168. el.data && (el.data = el.data.replace(find, replace)) || el.src && ((el.src = el.src.replace(find, replace)) && (el.style.display = 'block'));
  169. var next = el.nextSibling,
  170. node = el.parentNode,
  171. elem = el.cloneNode(true);
  172. this.done.push(elem);
  173. if (node) {
  174. node.removeChild(el);
  175. next ? node.insertBefore(elem, next) : node.appendChild(elem);
  176. }
  177. this.flag || this.Tips();
  178. },
  179.  
  180. Script: function() {
  181. this.rule = this.rule.concat(this.extra);
  182.  
  183. var events = ['webkitAnimationStart', 'msAnimationStart', 'oAnimationStart', 'animationstart'];
  184. for (var i in events)
  185. document.addEventListener(events[i], this.Handler.bind(this), false);
  186. },
  187.  
  188. Style: function(css) {
  189. var style = document.createElement('style');
  190. style.setAttribute('type', 'text/css');
  191. style.innerHTML = css || this.init_css;
  192. document.getElementsByTagName('head')[0].appendChild(style);
  193. },
  194.  
  195. Timer: function() {
  196. this.list = [];
  197. setInterval(function() {
  198. this.list.length && this.list.shift()();
  199. }.bind(this), 100);
  200. },
  201.  
  202. Tips: function() {
  203. if (this.done.indexOf('tips') != -1)
  204. return;
  205.  
  206. this.done.push('tips');
  207.  
  208. this.Style(this.tips_css);
  209.  
  210. var div = document.createElement('div');
  211. div.className = 'ocplayer_tips';
  212. div.innerHTML = this.tips_html;
  213. div.querySelector('.tips_close').addEventListener('click', function(e) {
  214. e.stopPropagation && e.stopPropagation();
  215. e.preventDefault && e.preventDefault();
  216. div.parentNode.removeChild(div);
  217. }, false);
  218. (document.documentElement || document.body).appendChild(div);
  219. },
  220.  
  221. Chrome: function() {
  222. chrome.windows.onFocusChanged.addListener(function(winId) {
  223. this.Icon();
  224. }.bind(this));
  225.  
  226. chrome.tabs.onSelectionChanged.addListener(function(tabId) {
  227. this.Icon();
  228. }.bind(this));
  229.  
  230. chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  231. changeInfo.status == 'complete' && this.Icon();
  232. }.bind(this));
  233.  
  234. chrome.webRequest.onBeforeRequest.addListener(function(details) {
  235. if (details.tabId == -1)
  236. return;
  237.  
  238. var url = details.url;
  239.  
  240. for (var i in this.rule) {
  241. var find = this.rule[i]['find'];
  242. if (find.test(url)) {
  243. chrome.tabs.get(details.tabId, function(tab) {
  244. var key = this.Tab(tab);
  245. key && this.done.push(key);
  246. this.Icon();
  247. }.bind(this));
  248.  
  249. var replace = this.rule[i]['replace'];
  250. if (typeof replace == 'string') {
  251. // replace = /^https?:\/\//i.test(replace) ? replace : chrome.extension.getURL('player/' + replace);
  252. replace = /^https?:\/\//i.test(replace) ? replace : this.host + replace;
  253. } else {
  254. break;
  255. }
  256.  
  257. return {
  258. redirectUrl: url.replace(find, replace)
  259. };
  260. }
  261. }
  262.  
  263. return {
  264. cancel: false
  265. };
  266. }.bind(this), {
  267. urls: ['<all_urls>']
  268. }, ['blocking']);
  269. },
  270.  
  271. Youku: function() {
  272. chrome.webRequest.onCompleted.addListener(function(details) {
  273. chrome.cookies.set({
  274. url: details.url,
  275. name: 'view',
  276. value: '0',
  277. path: '/',
  278. domain: '.youku.com'
  279. });
  280. }, {
  281. urls: ['http://*.youku.com/*'],
  282. types: ['main_frame']
  283. });
  284. },
  285.  
  286. Icon: function() {
  287. chrome.tabs.getSelected(null, function(tab) {
  288. var key = this.Tab(tab);
  289. if (!key)
  290. return;
  291.  
  292. var path, title;
  293. if (this.done.indexOf(key) != -1) {
  294. path = 'images/icon-22.png';
  295. title = 'Onens.Clean.Player \u5DF2\u542F\u7528';
  296. } else {
  297. path = 'images/icon-22-gray.png';
  298. title = 'Onens.Clean.Player \u672A\u542F\u7528';
  299. }
  300.  
  301. chrome.browserAction.setIcon({
  302. path: path
  303. });
  304.  
  305. chrome.browserAction.setTitle({
  306. title: title
  307. });
  308. }.bind(this));
  309. },
  310.  
  311. Tab: function(tab) {
  312. return typeof tab == 'object' ? tab.windowId + '|' + tab.id + '|' + tab.url : false;
  313. },
  314.  
  315. Init: function() {
  316. this.flag = typeof GM_xmlhttpRequest == 'undefined';
  317. if (this.flag) {
  318. if (!/^https?:\/\//i.test(window.location.href)) {
  319. this.Youku();
  320. this.Chrome();
  321. } else {
  322. this.Script();
  323. }
  324. } else {
  325. this.Timer();
  326. this.Style();
  327. this.Script();
  328. }
  329. }
  330. };
  331.  
  332. OCPlayer.Init();