iqiyi-player-switch

爱奇艺flash播放器与html5播放器随意切换,改善html5播放器播放体验。

目前为 2017-06-19 提交的版本,查看 最新版本

  1. 'use strict';
  2.  
  3. var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
  4.  
  5. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  6.  
  7. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  8.  
  9. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  10.  
  11. // ==UserScript==
  12. // @name iqiyi-player-switch
  13. // @namespace https://github.com/gooyie/userscript-iqiyi-player-switch
  14. // @homepageURL https://github.com/gooyie/userscript-iqiyi-player-switch
  15. // @supportURL https://github.com/gooyie/userscript-iqiyi-player-switch/issues
  16. // @version 1.8.5
  17. // @description 爱奇艺flash播放器与html5播放器随意切换,改善html5播放器播放体验。
  18. // @author gooyie
  19. // @license MIT License
  20. //
  21. // @include *://*.iqiyi.com/*
  22. // @include *://v.baidu.com/*
  23. // @grant GM_registerMenuCommand
  24. // @grant GM_xmlhttpRequest
  25. // @grant GM_addStyle
  26. // @grant GM_getValue
  27. // @grant GM_setValue
  28. // @grant GM_info
  29. // @grant unsafeWindow
  30. // @connect qiyi.com
  31. // @require https://greasyfork.org/scripts/29319-web-streams-polyfill/code/web-streams-polyfill.js?version=191261
  32. // @require https://greasyfork.org/scripts/29306-fetch-readablestream/code/fetch-readablestream.js?version=191832
  33. // @require https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/3.3.4/adapter.min.js
  34. // @require https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.7.0/js/md5.min.js
  35. // @run-at document-start
  36. // ==/UserScript==
  37.  
  38. (function () {
  39. 'use strict';
  40.  
  41. var PLAYER_TYPE = {
  42. Html5VOD: 'h5_VOD',
  43. FlashVOD: 'flash_VOD'
  44. };
  45. /* eslint-disable no-console */
  46.  
  47. var Logger = function () {
  48. function Logger() {
  49. _classCallCheck(this, Logger);
  50. }
  51.  
  52. _createClass(Logger, null, [{
  53. key: 'log',
  54. value: function log() {
  55. var _console;
  56.  
  57. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  58. args[_key] = arguments[_key];
  59. }
  60.  
  61. (_console = console).log.apply(_console, ['%c' + this.tag + '%c' + args.shift(), 'color: green; font-weight: bolder', 'color: blue'].concat(args));
  62. }
  63. }, {
  64. key: 'info',
  65. value: function info() {
  66. var _console2;
  67.  
  68. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  69. args[_key2] = arguments[_key2];
  70. }
  71.  
  72. (_console2 = console).info.apply(_console2, [this.tag + args.shift()].concat(args));
  73. }
  74. }, {
  75. key: 'debug',
  76. value: function debug() {
  77. var _console3;
  78.  
  79. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  80. args[_key3] = arguments[_key3];
  81. }
  82.  
  83. (_console3 = console).debug.apply(_console3, [this.tag + args.shift()].concat(args));
  84. }
  85. }, {
  86. key: 'warn',
  87. value: function warn() {
  88. var _console4;
  89.  
  90. for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
  91. args[_key4] = arguments[_key4];
  92. }
  93.  
  94. (_console4 = console).warn.apply(_console4, [this.tag + args.shift()].concat(args));
  95. }
  96. }, {
  97. key: 'error',
  98. value: function error() {
  99. var _console5;
  100.  
  101. for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
  102. args[_key5] = arguments[_key5];
  103. }
  104.  
  105. (_console5 = console).error.apply(_console5, [this.tag + args.shift()].concat(args));
  106. }
  107. }, {
  108. key: 'tag',
  109. get: function get() {
  110. return '[' + GM_info.script.name + ']';
  111. }
  112. }]);
  113.  
  114. return Logger;
  115. }();
  116. /* eslint-enable no-console */
  117.  
  118.  
  119. var Cookies = function () {
  120. function Cookies() {
  121. _classCallCheck(this, Cookies);
  122. }
  123.  
  124. _createClass(Cookies, null, [{
  125. key: 'get',
  126. value: function get(key) {
  127. var value = void 0;
  128. if (new RegExp('^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+$').test(key)) {
  129. // eslint-disable-line no-control-regex
  130. var re = new RegExp('(^| )' + key + '=([^;]*)(;|$)');
  131. var rs = re.exec(document.cookie);
  132. value = rs ? rs[2] : '';
  133. }
  134. return value ? decodeURIComponent(value) : '';
  135. }
  136. }, {
  137. key: 'set',
  138. value: function set(k, v) {
  139. var o = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  140.  
  141. var n = o.expires;
  142. if ('number' == typeof o.expires) {
  143. n = new Date();
  144. n.setTime(n.getTime() + o.expires);
  145. }
  146. var key = k;
  147. var value = encodeURIComponent(v);
  148. var path = o.path ? '; path=' + o.path : '';
  149. var expires = n ? '; expires=' + n.toGMTString() : '';
  150. var domain = o.domain ? '; domain=' + o.domain : '';
  151. document.cookie = key + '=' + value + path + expires + domain;
  152. }
  153. }, {
  154. key: 'remove',
  155. value: function remove(k) {
  156. var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  157.  
  158. o.expires = new Date(0);
  159. this.set(k, '', o);
  160. }
  161. }]);
  162.  
  163. return Cookies;
  164. }();
  165.  
  166. var Detector = function () {
  167. function Detector() {
  168. _classCallCheck(this, Detector);
  169. }
  170.  
  171. _createClass(Detector, null, [{
  172. key: 'isSupportHtml5',
  173. value: function isSupportHtml5() {
  174. var v = document.createElement('video');
  175. return !!(v.canPlayType('audio/mp4; codecs="mp4a.40.2"') && v.canPlayType('video/mp4; codecs="avc1.640029"') && v.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"'));
  176. }
  177. }, {
  178. key: 'isSupportVms',
  179. value: function isSupportVms() {
  180. return !!(window.MediaSource && window.URL && window.WebSocket && window.ReadableStream && (window.RTCSessionDescription || window.webkitRTCSessionDescription) && (window.RTCPeerConnection || window.webkitRTCPeerConnection) && (window.RTCIceCandidate || window.webkitRTCIceCandidate));
  181. }
  182. }, {
  183. key: 'isSupportM3u8',
  184. value: function isSupportM3u8() {
  185. var v = document.createElement('video');
  186. return !!(v.canPlayType('application/x-mpegurl') && v.canPlayType('application/vnd.apple.mpegurl'));
  187. }
  188. }, {
  189. key: 'isChrome',
  190. value: function isChrome() {
  191. return (/chrome/i.test(navigator.userAgent)
  192. );
  193. }
  194. }, {
  195. key: 'isFirefox',
  196. value: function isFirefox() {
  197. return (/firefox/i.test(navigator.userAgent)
  198. );
  199. }
  200. }, {
  201. key: 'isEdge',
  202. value: function isEdge() {
  203. return (/edge/i.test(navigator.userAgent)
  204. );
  205. }
  206. }, {
  207. key: 'isInnerFrame',
  208. value: function isInnerFrame() {
  209. return window.top !== window.self;
  210. }
  211. }, {
  212. key: 'isOutsite',
  213. value: function isOutsite() {
  214. return !/\.iqiyi\.com$/.test(location.host);
  215. }
  216. }]);
  217.  
  218. return Detector;
  219. }();
  220.  
  221. var Hooker = function () {
  222. function Hooker() {
  223. _classCallCheck(this, Hooker);
  224. }
  225.  
  226. _createClass(Hooker, null, [{
  227. key: 'hookCall',
  228. value: function hookCall() {
  229. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  230.  
  231. var call = Function.prototype.call;
  232. Function.prototype.call = function () {
  233. for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
  234. args[_key6] = arguments[_key6];
  235. }
  236.  
  237. var ret = call.apply(this, args);
  238. try {
  239. if (args) cb.apply(undefined, args);
  240. } catch (err) {
  241. Logger.error(err.stack);
  242. }
  243. return ret;
  244. };
  245.  
  246. Function.prototype.call.toString = Function.prototype.call.toLocaleString = function () {
  247. return 'function call() { [native code] }';
  248. };
  249. }
  250. }, {
  251. key: '_isFactoryCall',
  252. value: function _isFactoryCall(args) {
  253. // module.exports, module, module.exports, require
  254. return args.length === 4 && args[1] instanceof Object && args[1].hasOwnProperty('exports');
  255. }
  256. }, {
  257. key: 'hookFactoryCall',
  258. value: function hookFactoryCall() {
  259. var _this = this;
  260.  
  261. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  262.  
  263. this.hookCall(function () {
  264. for (var _len7 = arguments.length, args = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
  265. args[_key7] = arguments[_key7];
  266. }
  267.  
  268. if (_this._isFactoryCall(args)) cb.apply(undefined, args);
  269. });
  270. }
  271. }, {
  272. key: '_isJqueryFactoryCall',
  273. value: function _isJqueryFactoryCall(exports) {
  274. return exports.hasOwnProperty('fn') && exports.fn.hasOwnProperty('jquery');
  275. }
  276. }, {
  277. key: 'hookJquery',
  278. value: function hookJquery() {
  279. var _this2 = this;
  280.  
  281. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  282.  
  283. this.hookFactoryCall(function () {
  284. for (var _len8 = arguments.length, args = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
  285. args[_key8] = arguments[_key8];
  286. }
  287.  
  288. if (_this2._isJqueryFactoryCall(args[1].exports)) cb(args[1].exports);
  289. });
  290. }
  291. }, {
  292. key: 'hookJqueryAjax',
  293. value: function hookJqueryAjax() {
  294. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  295.  
  296. this.hookJquery(function (exports) {
  297. var ajax = exports.ajax.bind(exports);
  298.  
  299. exports.ajax = function (url) {
  300. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  301.  
  302. if ((typeof url === 'undefined' ? 'undefined' : _typeof(url)) === 'object') {
  303. var _ref = [url.url, url];
  304. url = _ref[0];
  305. options = _ref[1];
  306. }
  307.  
  308. var isHijacked = cb(url, options);
  309. if (isHijacked) return;
  310.  
  311. return ajax(url, options);
  312. };
  313. });
  314. }
  315. }, {
  316. key: '_isHttpFactoryCall',
  317. value: function _isHttpFactoryCall() {
  318. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  319.  
  320. return exports.hasOwnProperty('jsonp') && exports.hasOwnProperty('ajax');
  321. }
  322. }, {
  323. key: 'hookHttp',
  324. value: function hookHttp() {
  325. var _this3 = this;
  326.  
  327. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  328.  
  329. this.hookFactoryCall(function () {
  330. for (var _len9 = arguments.length, args = Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
  331. args[_key9] = arguments[_key9];
  332. }
  333.  
  334. if (_this3._isHttpFactoryCall(args[1].exports)) cb(args[1].exports);
  335. });
  336. }
  337. }, {
  338. key: 'hookHttpJsonp',
  339. value: function hookHttpJsonp() {
  340. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  341.  
  342. this.hookHttp(function (exports) {
  343. var jsonp = exports.jsonp.bind(exports);
  344.  
  345. exports.jsonp = function (options) {
  346. var isHijacked = cb(options);
  347. if (isHijacked) return;
  348. return jsonp(options);
  349. };
  350. });
  351. }
  352. }, {
  353. key: '_isLogoFactoryCall',
  354. value: function _isLogoFactoryCall() {
  355. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  356.  
  357. return 'function' === typeof exports && exports.prototype.hasOwnProperty('showLogo');
  358. }
  359. }, {
  360. key: 'hookLogo',
  361. value: function hookLogo() {
  362. var _this4 = this;
  363.  
  364. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  365.  
  366. this.hookFactoryCall(function () {
  367. for (var _len10 = arguments.length, args = Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
  368. args[_key10] = arguments[_key10];
  369. }
  370.  
  371. if (_this4._isLogoFactoryCall(args[1].exports)) cb(args[1].exports);
  372. });
  373. }
  374. }, {
  375. key: '_isFullScreenFactoryCall',
  376. value: function _isFullScreenFactoryCall() {
  377. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  378.  
  379. return exports.__proto__ && exports.__proto__.hasOwnProperty('isFullScreen');
  380. }
  381. }, {
  382. key: 'hookFullScreen',
  383. value: function hookFullScreen() {
  384. var _this5 = this;
  385.  
  386. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  387.  
  388. this.hookFactoryCall(function () {
  389. for (var _len11 = arguments.length, args = Array(_len11), _key11 = 0; _key11 < _len11; _key11++) {
  390. args[_key11] = arguments[_key11];
  391. }
  392.  
  393. if (_this5._isFullScreenFactoryCall(args[1].exports)) cb(args[1].exports);
  394. });
  395. }
  396. }, {
  397. key: '_isWebFullScreenFactoryCall',
  398. value: function _isWebFullScreenFactoryCall() {
  399. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  400.  
  401. return exports.__proto__ && exports.__proto__.hasOwnProperty('isWebFullScreen');
  402. }
  403. }, {
  404. key: 'hookWebFullScreen',
  405. value: function hookWebFullScreen() {
  406. var _this6 = this;
  407.  
  408. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  409.  
  410. this.hookFactoryCall(function () {
  411. for (var _len12 = arguments.length, args = Array(_len12), _key12 = 0; _key12 < _len12; _key12++) {
  412. args[_key12] = arguments[_key12];
  413. }
  414.  
  415. if (_this6._isWebFullScreenFactoryCall(args[1].exports)) cb(args[1].exports);
  416. });
  417. }
  418. }, {
  419. key: '_isPluginControlsFactoryCall',
  420. value: function _isPluginControlsFactoryCall() {
  421. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  422.  
  423. return 'function' === typeof exports && exports.prototype.hasOwnProperty('initFullScreen');
  424. }
  425. }, {
  426. key: 'hookPluginControls',
  427. value: function hookPluginControls() {
  428. var _this7 = this;
  429.  
  430. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  431.  
  432. this.hookFactoryCall(function () {
  433. for (var _len13 = arguments.length, args = Array(_len13), _key13 = 0; _key13 < _len13; _key13++) {
  434. args[_key13] = arguments[_key13];
  435. }
  436.  
  437. if (_this7._isPluginControlsFactoryCall(args[1].exports)) cb(args[1].exports);
  438. });
  439. }
  440. }, {
  441. key: '_isCoreFactoryCall',
  442. value: function _isCoreFactoryCall() {
  443. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  444.  
  445. return 'function' === typeof exports && exports.prototype.hasOwnProperty('getdefaultvds') && exports.prototype.hasOwnProperty('getMovieInfo');
  446. }
  447. }, {
  448. key: 'hookCore',
  449. value: function hookCore() {
  450. var _this8 = this;
  451.  
  452. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  453.  
  454. this.hookFactoryCall(function () {
  455. for (var _len14 = arguments.length, args = Array(_len14), _key14 = 0; _key14 < _len14; _key14++) {
  456. args[_key14] = arguments[_key14];
  457. }
  458.  
  459. if (_this8._isCoreFactoryCall(args[1].exports)) cb(args[1].exports);
  460. });
  461. }
  462. }, {
  463. key: '_isSkinBaseFactoryCall',
  464. value: function _isSkinBaseFactoryCall() {
  465. var exports = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  466.  
  467. return 'function' === typeof exports && exports.prototype.hasOwnProperty('_checkPlugin');
  468. }
  469. }, {
  470. key: 'hookSkinBase',
  471. value: function hookSkinBase() {
  472. var _this9 = this;
  473.  
  474. var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
  475.  
  476. this.hookFactoryCall(function () {
  477. for (var _len15 = arguments.length, args = Array(_len15), _key15 = 0; _key15 < _len15; _key15++) {
  478. args[_key15] = arguments[_key15];
  479. }
  480.  
  481. if (_this9._isSkinBaseFactoryCall(args[1].exports)) cb(args[1].exports);
  482. });
  483. }
  484. }]);
  485.  
  486. return Hooker;
  487. }();
  488.  
  489. var Faker = function () {
  490. function Faker() {
  491. _classCallCheck(this, Faker);
  492. }
  493.  
  494. _createClass(Faker, null, [{
  495. key: 'fakeMacPlatform',
  496. value: function fakeMacPlatform() {
  497. var PLAFORM_MAC = 'mac';
  498. Object.defineProperty(unsafeWindow.navigator, 'platform', { get: function get() {
  499. return PLAFORM_MAC;
  500. } });
  501. }
  502. }, {
  503. key: 'fakeSafari',
  504. value: function fakeSafari() {
  505. var UA_SAFARY = 'safari';
  506. Object.defineProperty(unsafeWindow.navigator, 'userAgent', { get: function get() {
  507. return UA_SAFARY;
  508. } });
  509. }
  510. }, {
  511. key: 'fakeChrome',
  512. value: function fakeChrome() {
  513. var UA_CHROME = 'chrome';
  514. Object.defineProperty(unsafeWindow.navigator, 'userAgent', { get: function get() {
  515. return UA_CHROME;
  516. } });
  517. }
  518. }, {
  519. key: '_calcSign',
  520. value: function _calcSign(authcookie) {
  521. var RESPONSE_KEY = '-0J1d9d^ESd)9jSsja';
  522. return md5(authcookie.substring(5, 39).split('').reverse().join('') + '<1<' + RESPONSE_KEY);
  523. }
  524. }, {
  525. key: 'fakeVipRes',
  526. value: function fakeVipRes(authcookie) {
  527. var json = {
  528. code: 'A00000',
  529. data: {
  530. sign: this._calcSign(authcookie)
  531. }
  532. };
  533. return json;
  534. }
  535. }, {
  536. key: 'fakeAdRes',
  537. value: function fakeAdRes() {
  538. var json = {};
  539. return json;
  540. }
  541. }, {
  542. key: 'fakePassportCookie',
  543. value: function fakePassportCookie() {
  544. Cookies.set('P00001', 'faked_passport', { domain: '.iqiyi.com' });
  545. Logger.log('faked passport cookie');
  546. }
  547. }]);
  548.  
  549. return Faker;
  550. }();
  551.  
  552. var Mocker = function () {
  553. function Mocker() {
  554. _classCallCheck(this, Mocker);
  555. }
  556.  
  557. _createClass(Mocker, null, [{
  558. key: 'mock',
  559. value: function mock() {
  560. this.mockForBestDefintion();
  561. this.mockAd();
  562. this.mockVip();
  563. this.mockLogo();
  564. this.mockCheckPlugin();
  565. }
  566. }, {
  567. key: 'mockToUseVms',
  568. value: function mockToUseVms() {
  569. Faker.fakeChrome();
  570. }
  571. }, {
  572. key: 'mockToUseM3u8',
  573. value: function mockToUseM3u8() {
  574. Faker.fakeMacPlatform();
  575. Faker.fakeSafari();
  576. }
  577. }, {
  578. key: '_isVideoReq',
  579. value: function _isVideoReq(url) {
  580. return (/^https?:\/\/(?:\d+.?){4}\/videos\/v.*$/.test(url)
  581. );
  582. }
  583. }, {
  584. key: 'mockForBestDefintion',
  585. value: function mockForBestDefintion() {
  586. var _this10 = this;
  587.  
  588. // apply shims
  589. if (Detector.isFirefox()) {
  590. var fetch = unsafeWindow.fetch.bind(unsafeWindow);
  591.  
  592. unsafeWindow.fetch = function (url, opts) {
  593. if (_this10._isVideoReq(url)) {
  594. Logger.log('fetching stream ' + url);
  595. return fetchStream(url, opts); // xhr with moz-chunked-arraybuffer
  596. } else {
  597. return fetch(url, opts);
  598. }
  599. };
  600. } else if (Detector.isEdge()) {
  601. // export to the global window object
  602. unsafeWindow.RTCIceCandidate = window.RTCIceCandidate;
  603. unsafeWindow.RTCPeerConnection = window.RTCPeerConnection;
  604. unsafeWindow.RTCSessionDescription = window.RTCSessionDescription;
  605. }
  606. // auto fall-back
  607. if (Detector.isSupportVms()) {
  608. if (!Detector.isChrome()) this.mockToUseVms(); // vms, 1080p or higher
  609. } else if (Detector.isSupportM3u8()) {
  610. this.mockToUseM3u8(); // tmts m3u8
  611. } else {
  612. // by default, tmts mp4 ...
  613. }
  614. }
  615. }, {
  616. key: '_isAdReq',
  617. value: function _isAdReq(url) {
  618. var AD_URL = 'http://t7z.cupid.iqiyi.com/show2';
  619. return url.indexOf(AD_URL) === 0;
  620. }
  621. }, {
  622. key: 'mockAd',
  623. value: function mockAd() {
  624. var _this11 = this;
  625.  
  626. Hooker.hookJqueryAjax(function (url, options) {
  627. if (_this11._isAdReq(url)) {
  628. var res = Faker.fakeAdRes();
  629. (options.complete || options.success)({ responseJSON: res }, 'success');
  630. Logger.log('mocked ad request ' + url);
  631. return true;
  632. }
  633. });
  634. }
  635. }, {
  636. key: '_isCheckVipReq',
  637. value: function _isCheckVipReq(url) {
  638. var CHECK_VIP_URL = 'https://cmonitor.iqiyi.com/apis/user/check_vip.action';
  639. return url === CHECK_VIP_URL;
  640. }
  641. }, {
  642. key: '_isLogin',
  643. value: function _isLogin() {
  644. return !!Cookies.get('P00001');
  645. }
  646. }, {
  647. key: 'mockVip',
  648. value: function mockVip() {
  649. var _this12 = this;
  650.  
  651. if (!this._isLogin()) Faker.fakePassportCookie();
  652.  
  653. Hooker.hookHttpJsonp(function (options) {
  654. var url = options.url;
  655.  
  656. if (_this12._isCheckVipReq(url)) {
  657. var res = Faker.fakeVipRes(options.params.authcookie);
  658. options.success(res);
  659. Logger.log('mocked check vip request ' + url);
  660. return true;
  661. }
  662. });
  663. }
  664. }, {
  665. key: 'mockLogo',
  666. value: function mockLogo() {
  667. Hooker.hookLogo(function (exports) {
  668. return exports.prototype.showLogo = function () {};
  669. });
  670. }
  671. }, {
  672. key: 'mockCheckPlugin',
  673. value: function mockCheckPlugin() {
  674. Hooker.hookSkinBase(function (exports) {
  675. exports.prototype._checkPlugin = function () {};
  676. });
  677. }
  678. }]);
  679.  
  680. return Mocker;
  681. }();
  682.  
  683. var Switcher = function () {
  684. function Switcher() {
  685. _classCallCheck(this, Switcher);
  686. }
  687.  
  688. _createClass(Switcher, null, [{
  689. key: 'switchTo',
  690. value: function switchTo(toType) {
  691. Logger.log('switching to ' + toType + ' ...');
  692.  
  693. GM_setValue('player_forcedType', toType);
  694. document.location.reload();
  695. }
  696. }]);
  697.  
  698. return Switcher;
  699. }();
  700.  
  701. var Finder = function () {
  702. function Finder() {
  703. _classCallCheck(this, Finder);
  704. }
  705.  
  706. _createClass(Finder, null, [{
  707. key: 'findVid',
  708. value: function findVid(text) {
  709. var result = /vid=([\da-z]+)/.exec(text);
  710. return result ? result[1] : null;
  711. }
  712. }, {
  713. key: 'findTvid',
  714. value: function findTvid(text) {
  715. var result = /tvId=(\d+)/.exec(text);
  716. return result ? result[1] : null;
  717. }
  718. }, {
  719. key: 'findEmbedNodes',
  720. value: function findEmbedNodes() {
  721. var nodes = document.querySelectorAll('object, embed');
  722. return nodes.length > 0 ? nodes : null;
  723. }
  724. }]);
  725.  
  726. return Finder;
  727. }();
  728.  
  729. function getVideoUrl(tvid, vid) {
  730. return new Promise(function (resolve, reject) {
  731. GM_xmlhttpRequest({
  732. url: 'http://cache.video.qiyi.com/jp/vi/' + tvid + '/' + vid + '/?callback=callback',
  733. method: 'GET',
  734. timeout: 8e3,
  735. onload: function onload(details) {
  736. try {
  737. var json = JSON.parse(/callback\s*\(\s*(\{.*\})\s*\)/.exec(details.responseText)[1]);
  738. resolve(json.vu);
  739. } catch (err) {
  740. reject(err);
  741. }
  742. },
  743. onerror: reject,
  744. onabort: reject,
  745. ontimeout: reject
  746. });
  747. });
  748. }
  749.  
  750. function embedSrc(targetNode, _ref2) {
  751. var tvid = _ref2.tvid,
  752. vid = _ref2.vid;
  753.  
  754. targetNode.innerHTML = '<div class="' + GM_info.script.name + ' info">\u6B63\u5728\u83B7\u53D6\u89C6\u9891\u6E90...</div>';
  755.  
  756. getVideoUrl(tvid, vid).then(function (url) {
  757. targetNode.innerHTML = '<iframe id="innerFrame" src="' + url + '" frameborder="0" allowfullscreen="true" width="100%" height="100%"></iframe>';
  758. }).catch(function (err) {
  759. targetNode.innerHTML = '<div class="' + GM_info.script.name + ' error"><p>\u83B7\u53D6\u89C6\u9891\u6E90\u51FA\u9519\uFF01</p><p>' + err.message + '</p></div>';
  760. });
  761. }
  762.  
  763. function replaceFlash() {
  764. var observer = new MutationObserver(function (records, self) {
  765. var _iteratorNormalCompletion = true;
  766. var _didIteratorError = false;
  767. var _iteratorError = undefined;
  768.  
  769. try {
  770. for (var _iterator = records[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
  771. var record = _step.value;
  772.  
  773. if (record.type !== 'childList' || !record.addedNodes) continue;
  774.  
  775. var _iteratorNormalCompletion2 = true;
  776. var _didIteratorError2 = false;
  777. var _iteratorError2 = undefined;
  778.  
  779. try {
  780. for (var _iterator2 = record.addedNodes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
  781. var node = _step2.value;
  782.  
  783. if (node.nodeName !== 'OBJECT' && node.nodeName !== 'EMBED') continue;
  784.  
  785. var text = node.outerHTML;
  786. var vid = Finder.findVid(text);
  787. var tvid = Finder.findTvid(text);
  788.  
  789. if (tvid && vid) {
  790. Logger.log('finded player', node);
  791. embedSrc(node.parentNode, { tvid: tvid, vid: vid });
  792. self.disconnect();
  793. Logger.log('stoped observation');
  794. }
  795. }
  796. } catch (err) {
  797. _didIteratorError2 = true;
  798. _iteratorError2 = err;
  799. } finally {
  800. try {
  801. if (!_iteratorNormalCompletion2 && _iterator2.return) {
  802. _iterator2.return();
  803. }
  804. } finally {
  805. if (_didIteratorError2) {
  806. throw _iteratorError2;
  807. }
  808. }
  809. }
  810. }
  811. } catch (err) {
  812. _didIteratorError = true;
  813. _iteratorError = err;
  814. } finally {
  815. try {
  816. if (!_iteratorNormalCompletion && _iterator.return) {
  817. _iterator.return();
  818. }
  819. } finally {
  820. if (_didIteratorError) {
  821. throw _iteratorError;
  822. }
  823. }
  824. }
  825. });
  826.  
  827. observer.observe(document.body || document.documentElement, { subtree: true, childList: true });
  828. Logger.log('started observation');
  829. }
  830.  
  831. function adapteIframe() {
  832. var style = '\n body[class|="qypage"] {\n overflow: hidden !important;\n background: #000 !important;\n visibility: hidden;\n }\n\n .mod-func {\n display: none !important;\n }\n\n .' + GM_info.script.name + '.info {\n width: 20em;\n height: 5em;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n margin: auto;\n text-align: center;\n line-height: 5em;\n font-size: 1em;\n color: #ccc;\n }\n\n .' + GM_info.script.name + '.error {\n height: 3em;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n margin: auto;\n text-align: center;\n font-size: 1em;\n color: #c00;\n }\n ';
  833.  
  834. GM_addStyle(style);
  835.  
  836. Hooker.hookWebFullScreen(function (exports) {
  837. var init = exports.__proto__.init;
  838. exports.__proto__.init = function (wrapper, btn) {
  839. init.apply(this, [wrapper, btn]);
  840. this.enter();
  841.  
  842. btn[0].style.display = 'none';
  843. document.body.style.visibility = 'visible';
  844. };
  845.  
  846. exports.__proto__.exit = function () {};
  847. });
  848.  
  849. Hooker.hookCore(function (exports) {
  850. exports.prototype.hasNextVideo = function () {
  851. return null;
  852. };
  853. });
  854. }
  855.  
  856. function forceHtml5() {
  857. Logger.log('setting player_forcedType cookie as ' + PLAYER_TYPE.Html5VOD);
  858. Cookies.set('player_forcedType', PLAYER_TYPE.Html5VOD, { domain: '.iqiyi.com' });
  859. }
  860.  
  861. function forceFlash() {
  862. Logger.log('setting player_forcedType cookie as ' + PLAYER_TYPE.FlashVOD);
  863. Cookies.set('player_forcedType', PLAYER_TYPE.FlashVOD, { domain: '.iqiyi.com' });
  864. }
  865.  
  866. function clean() {
  867. Cookies.remove('player_forcedType', { domain: '.iqiyi.com' });
  868. if (Cookies.get('P00001') === 'faked_passport') Cookies.remove('P00001', { domain: '.iqiyi.com' });
  869. Logger.log('removed cookies.');
  870. }
  871.  
  872. function registerMenu() {
  873. var MENU_NAME = {
  874. HTML5: 'HTML5播放器',
  875. FLASH: 'Flash播放器'
  876. };
  877.  
  878. var currType = GM_getValue('player_forcedType', PLAYER_TYPE.Html5VOD); // 默认为Html5播放器,免去切换。
  879.  
  880. var _ref3 = currType === PLAYER_TYPE.Html5VOD ? [PLAYER_TYPE.FlashVOD, MENU_NAME.FLASH] : [PLAYER_TYPE.Html5VOD, MENU_NAME.HTML5],
  881. _ref4 = _slicedToArray(_ref3, 2),
  882. toType = _ref4[0],
  883. name = _ref4[1];
  884.  
  885. GM_registerMenuCommand(name, function () {
  886. return Switcher.switchTo(toType);
  887. }, null);
  888. Logger.log('registered menu.');
  889. }
  890.  
  891. //=============================================================================
  892.  
  893. registerMenu();
  894.  
  895. var currType = GM_getValue('player_forcedType', PLAYER_TYPE.Html5VOD);
  896. if (currType === PLAYER_TYPE.Html5VOD) {
  897. if (!Detector.isSupportHtml5()) {
  898. alert('╮(╯▽╰)╭ 你的浏览器播放不了html5视频~~~~');
  899. return;
  900. }
  901.  
  902. forceHtml5();
  903. Mocker.mock();
  904.  
  905. if (Detector.isInnerFrame()) adapteIframe();
  906. if (Detector.isOutsite()) replaceFlash();
  907. } else {
  908. forceFlash();
  909. }
  910.  
  911. window.addEventListener('unload', function () {
  912. return clean();
  913. });
  914. })();