ykh5p

改善优酷官方html5播放器播放体验

目前为 2017-10-17 提交的版本。查看 最新版本

  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 _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; }; }();
  6.  
  7. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  8.  
  9. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  10.  
  11. function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  12.  
  13. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14.  
  15. // ==UserScript==
  16. // @name ykh5p
  17. // @namespace https://github.com/gooyie/ykh5p
  18. // @homepageURL https://github.com/gooyie/ykh5p
  19. // @supportURL https://github.com/gooyie/ykh5p/issues
  20. // @version 0.12.0
  21. // @description 改善优酷官方html5播放器播放体验
  22. // @author gooyie
  23. // @license MIT License
  24. //
  25. // @include *://v.youku.com/*
  26. // @include *://player.youku.com/embed/*
  27. // @grant GM_info
  28. // @grant GM_addStyle
  29. // @grant unsafeWindow
  30. // @run-at document-start
  31. // ==/UserScript==
  32.  
  33. (function () {
  34. 'use strict';
  35.  
  36. /* eslint-disable no-console */
  37.  
  38. var Logger = function () {
  39. function Logger() {
  40. _classCallCheck(this, Logger);
  41. }
  42.  
  43. _createClass(Logger, null, [{
  44. key: 'log',
  45. value: function log() {
  46. var _console;
  47.  
  48. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  49. args[_key] = arguments[_key];
  50. }
  51.  
  52. (_console = console).log.apply(_console, ['%c' + this.tag + '%c' + args.shift(), 'color: #fff; background: #2FB3FF', ''].concat(args));
  53. }
  54. }, {
  55. key: 'info',
  56. value: function info() {
  57. var _console2;
  58.  
  59. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  60. args[_key2] = arguments[_key2];
  61. }
  62.  
  63. (_console2 = console).info.apply(_console2, [this.tag + args.shift()].concat(args));
  64. }
  65. }, {
  66. key: 'debug',
  67. value: function debug() {
  68. var _console3;
  69.  
  70. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  71. args[_key3] = arguments[_key3];
  72. }
  73.  
  74. (_console3 = console).debug.apply(_console3, [this.tag + args.shift()].concat(args));
  75. }
  76. }, {
  77. key: 'warn',
  78. value: function warn() {
  79. var _console4;
  80.  
  81. for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
  82. args[_key4] = arguments[_key4];
  83. }
  84.  
  85. (_console4 = console).warn.apply(_console4, [this.tag + args.shift()].concat(args));
  86. }
  87. }, {
  88. key: 'error',
  89. value: function error() {
  90. var _console5;
  91.  
  92. for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
  93. args[_key5] = arguments[_key5];
  94. }
  95.  
  96. (_console5 = console).error.apply(_console5, [this.tag + args.shift()].concat(args));
  97. }
  98. }, {
  99. key: 'tag',
  100. get: function get() {
  101. return '[' + GM_info.script.name + ']';
  102. }
  103. }]);
  104.  
  105. return Logger;
  106. }();
  107. /* eslint-enable no-console */
  108.  
  109. var Hooker = function () {
  110. function Hooker() {
  111. _classCallCheck(this, Hooker);
  112. }
  113.  
  114. _createClass(Hooker, null, [{
  115. key: '_hookCall',
  116. value: function _hookCall(cb) {
  117. var call = Function.prototype.call;
  118. Function.prototype.call = function () {
  119. for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
  120. args[_key6] = arguments[_key6];
  121. }
  122.  
  123. var ret = call.apply(this, args);
  124. try {
  125. if (args && cb(args)) {
  126. Function.prototype.call = call;
  127. cb = function cb() {};
  128. Logger.log('restored call');
  129. }
  130. } catch (err) {
  131. Logger.error(err.stack);
  132. }
  133. return ret;
  134. };
  135. this._hookCall = null;
  136. }
  137. }, {
  138. key: '_isEsModule',
  139. value: function _isEsModule(obj) {
  140. return obj.__esModule;
  141. }
  142. }, {
  143. key: '_isFuction',
  144. value: function _isFuction(arg) {
  145. return 'function' === typeof arg;
  146. }
  147. }, {
  148. key: '_isModuleCall',
  149. value: function _isModuleCall(args) {
  150. // module.exports, module, module.exports, require
  151. return args.length === 4 && args[1] && Object.getPrototypeOf(args[1]) === Object.prototype && args[1].hasOwnProperty('exports');
  152. }
  153. }, {
  154. key: '_hookModuleCall',
  155. value: function _hookModuleCall(cb, pred) {
  156. var _this = this;
  157.  
  158. var callbacksMap = new Map([[pred, [cb]]]);
  159. this._hookCall(function (args) {
  160. if (!_this._isModuleCall(args)) return;
  161. var exports = args[1].exports;
  162. var _iteratorNormalCompletion = true;
  163. var _didIteratorError = false;
  164. var _iteratorError = undefined;
  165.  
  166. try {
  167. for (var _iterator = callbacksMap[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
  168. var _step$value = _slicedToArray(_step.value, 2),
  169. _pred = _step$value[0],
  170. callbacks = _step$value[1];
  171.  
  172. if (!_pred.apply(_this, [exports])) continue;
  173. callbacks.forEach(function (cb) {
  174. return cb(exports, args);
  175. });
  176. callbacksMap.delete(_pred);
  177. !callbacksMap.size && (_this._hookModuleCall = null);
  178. break;
  179. }
  180. } catch (err) {
  181. _didIteratorError = true;
  182. _iteratorError = err;
  183. } finally {
  184. try {
  185. if (!_iteratorNormalCompletion && _iterator.return) {
  186. _iterator.return();
  187. }
  188. } finally {
  189. if (_didIteratorError) {
  190. throw _iteratorError;
  191. }
  192. }
  193. }
  194.  
  195. return !callbacksMap.size;
  196. });
  197.  
  198. this._hookModuleCall = function (cb, pred) {
  199. if (callbacksMap.has(pred)) {
  200. callbacksMap.get(pred).push(cb);
  201. } else {
  202. callbacksMap.set(pred, [cb]);
  203. }
  204. };
  205. }
  206. }, {
  207. key: '_isUpsModuleCall',
  208. value: function _isUpsModuleCall(exports) {
  209. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('getServieceUrl') && /\.id\s*=\s*"ups"/.test(exports.default.toString());
  210. }
  211. }, {
  212. key: 'hookUps',
  213. value: function hookUps(cb) {
  214. this._hookModuleCall(cb, this._isUpsModuleCall);
  215. }
  216. }, {
  217. key: 'hookUpsOnComplete',
  218. value: function hookUpsOnComplete(cb) {
  219. this.hookUps(function (exports) {
  220. var onComplete = exports.default.prototype.onComplete;
  221. exports.default.prototype.onComplete = function (res) {
  222. cb(res);
  223. onComplete.apply(this, [res]);
  224. };
  225. });
  226. }
  227. }, {
  228. key: '_isLogoModuleCall',
  229. value: function _isLogoModuleCall(exports) {
  230. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('reset') && /logo\.style\.display/.test(exports.default.prototype.reset.toString());
  231. }
  232. }, {
  233. key: 'hookLogo',
  234. value: function hookLogo(cb) {
  235. this._hookModuleCall(cb, this._isLogoModuleCall);
  236. }
  237. }, {
  238. key: '_isQualityIconComponentModuleCall',
  239. value: function _isQualityIconComponentModuleCall(exports) {
  240. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('renderQuality');
  241. }
  242. }, {
  243. key: 'hookQualityIcon',
  244. value: function hookQualityIcon(cb) {
  245. this._hookModuleCall(cb, this._isQualityIconComponentModuleCall);
  246. }
  247. }, {
  248. key: 'hookRenderQuality',
  249. value: function hookRenderQuality(cb) {
  250. Hooker.hookQualityIcon(function (exports) {
  251. var renderQuality = exports.default.prototype.renderQuality;
  252. exports.default.prototype.renderQuality = function (langCode) {
  253. cb(langCode, this);
  254. renderQuality.apply(this, [langCode]);
  255. };
  256. });
  257. }
  258. }, {
  259. key: 'hookSetQuality',
  260. value: function hookSetQuality(cb) {
  261. Hooker.hookQualityIcon(function (exports) {
  262. var setQuality = exports.default.prototype.setQuality;
  263. exports.default.prototype.setQuality = function () {
  264. for (var _len7 = arguments.length, args = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
  265. args[_key7] = arguments[_key7];
  266. }
  267.  
  268. // quality, innerText
  269. cb(args, this);
  270. setQuality.apply(this, args);
  271. };
  272. });
  273. }
  274. }, {
  275. key: '_isManageModuleCall',
  276. value: function _isManageModuleCall(exports) {
  277. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('_resetPlayer');
  278. }
  279. }, {
  280. key: 'hookManage',
  281. value: function hookManage(cb) {
  282. this._hookModuleCall(cb, this._isManageModuleCall);
  283. }
  284. }, {
  285. key: 'hookInitPlayerEvent',
  286. value: function hookInitPlayerEvent(cb) {
  287. Hooker.hookManage(function (exports) {
  288. var _initPlayerEvent = exports.default.prototype._initPlayerEvent;
  289. exports.default.prototype._initPlayerEvent = function () {
  290. cb(this);
  291. _initPlayerEvent.apply(this);
  292. };
  293. });
  294. }
  295. }, {
  296. key: 'hookResetPlayerAfter',
  297. value: function hookResetPlayerAfter(cb) {
  298. Hooker.hookManage(function (exports) {
  299. var _resetPlayer = exports.default.prototype._resetPlayer;
  300. exports.default.prototype._resetPlayer = function () {
  301. try {
  302. _resetPlayer.apply(this);
  303. } catch (err) {
  304. // 忽略 ykSDK.destroyAd 异常
  305. if (!err.stack.includes('destroyAd')) throw err;
  306. }
  307. cb(this);
  308. };
  309. });
  310. }
  311. }, {
  312. key: '_isKeyShortcutsModuleCall',
  313. value: function _isKeyShortcutsModuleCall(exports) {
  314. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('registerEvents');
  315. }
  316. }, {
  317. key: 'hookKeyShortcuts',
  318. value: function hookKeyShortcuts(cb) {
  319. this._hookModuleCall(cb, this._isKeyShortcutsModuleCall);
  320. }
  321. }, {
  322. key: '_isTipsModuleCall',
  323. value: function _isTipsModuleCall(exports) {
  324. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('showHintTips');
  325. }
  326. }, {
  327. key: 'hookTips',
  328. value: function hookTips(cb) {
  329. this._hookModuleCall(cb, this._isTipsModuleCall);
  330. }
  331. }, {
  332. key: '_isAdServiceModuleCall',
  333. value: function _isAdServiceModuleCall(exports) {
  334. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('requestAdData');
  335. }
  336. }, {
  337. key: 'hookAdService',
  338. value: function hookAdService(cb) {
  339. this._hookModuleCall(cb, this._isAdServiceModuleCall);
  340. }
  341. }, {
  342. key: '_isTopAreaModuleCall',
  343. value: function _isTopAreaModuleCall(exports) {
  344. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('_timerHandler');
  345. }
  346. }, {
  347. key: 'hookTopArea',
  348. value: function hookTopArea(cb) {
  349. this._hookModuleCall(cb, this._isTopAreaModuleCall);
  350. }
  351. }, {
  352. key: 'hookTopAreaAddEvent',
  353. value: function hookTopAreaAddEvent(cb) {
  354. Hooker.hookTopArea(function (exports) {
  355. var _addEvent = exports.default.prototype._addEvent;
  356. exports.default.prototype._addEvent = function () {
  357. cb(this);
  358. _addEvent.apply(this);
  359. };
  360. });
  361. }
  362. }, {
  363. key: '_isPreviewLayerModuleCall',
  364. value: function _isPreviewLayerModuleCall(exports) {
  365. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('setPreviewShow');
  366. }
  367. }, {
  368. key: 'hookPreviewLayer',
  369. value: function hookPreviewLayer(cb) {
  370. this._hookModuleCall(cb, this._isPreviewLayerModuleCall);
  371. }
  372. }, {
  373. key: 'hookPreviewLayerBind',
  374. value: function hookPreviewLayerBind(cb) {
  375. Hooker.hookPreviewLayer(function (exports) {
  376. var bind = exports.default.prototype.bind;
  377. exports.default.prototype.bind = function () {
  378. cb(this);
  379. bind.apply(this);
  380. };
  381. });
  382. }
  383. }, {
  384. key: '_isSettingSeriesComponentModuleCall',
  385. value: function _isSettingSeriesComponentModuleCall(exports) {
  386. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('_addEvent') && exports.default.prototype._addEvent.toString().includes('seriesliseLayer');
  387. }
  388. }, {
  389. key: 'hookSettingSeries',
  390. value: function hookSettingSeries(cb) {
  391. this._hookModuleCall(cb, this._isSettingSeriesComponentModuleCall);
  392. }
  393. }, {
  394. key: '_isSettingsIconComponentModuleCall',
  395. value: function _isSettingsIconComponentModuleCall(exports) {
  396. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('setConfig');
  397. }
  398. }, {
  399. key: 'hookSettingsIcon',
  400. value: function hookSettingsIcon(cb) {
  401. this._hookModuleCall(cb, this._isSettingsIconComponentModuleCall);
  402. }
  403. }, {
  404. key: '_isUtilModuleCall',
  405. value: function _isUtilModuleCall(exports) {
  406. return exports.setLocalData && exports.getLocalData;
  407. }
  408. }, {
  409. key: 'hookUtil',
  410. value: function hookUtil(cb) {
  411. this._hookModuleCall(cb, this._isUtilModuleCall);
  412. }
  413. }, {
  414. key: '_isGlobalModuleCall',
  415. value: function _isGlobalModuleCall(exports) {
  416. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('resetConfig');
  417. }
  418. }, {
  419. key: 'hookGlobal',
  420. value: function hookGlobal(cb) {
  421. this._hookModuleCall(cb, this._isGlobalModuleCall);
  422. }
  423. }, {
  424. key: 'hookGlobalConstructorAfter',
  425. value: function hookGlobalConstructorAfter(cb) {
  426. Hooker.hookGlobal(function (exports) {
  427. var constructor = exports.default;
  428. exports.default = function () {
  429. for (var _len8 = arguments.length, args = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
  430. args[_key8] = arguments[_key8];
  431. }
  432.  
  433. constructor.apply(this, args);
  434. cb(this);
  435. };
  436. exports.default.prototype = constructor.prototype;
  437. });
  438. }
  439. }, {
  440. key: 'hookGlobalInit',
  441. value: function hookGlobalInit(cb) {
  442. Hooker.hookGlobal(function (exports) {
  443. var init = exports.default.prototype.init;
  444. exports.default.prototype.init = function (config) {
  445. cb(config, this);
  446. init.apply(this, [config]);
  447. };
  448. });
  449. }
  450. }, {
  451. key: 'hookGlobalDeal',
  452. value: function hookGlobalDeal(cb) {
  453. Hooker.hookGlobal(function (exports) {
  454. var deal = exports.default.prototype.deal;
  455. exports.default.prototype.deal = function () {
  456. cb(this);
  457. deal.apply(this);
  458. };
  459. });
  460. }
  461. }, {
  462. key: 'hookGlobalResetAfter',
  463. value: function hookGlobalResetAfter(cb) {
  464. Hooker.hookGlobal(function (exports) {
  465. var reset = exports.default.prototype.reset;
  466. exports.default.prototype.reset = function () {
  467. reset.apply(this);
  468. cb(this);
  469. };
  470. });
  471. }
  472. }, {
  473. key: '_extractArgsName',
  474. value: function _extractArgsName(code) {
  475. return code.slice(code.indexOf('(') + 1, code.indexOf(')')).split(/\s*,\s*/);
  476. }
  477. }, {
  478. key: '_extractFunctionBody',
  479. value: function _extractFunctionBody(code) {
  480. return code.slice(code.indexOf('{') + 1, code.lastIndexOf('}'));
  481. }
  482. }, {
  483. key: '_isBaseModuleCall',
  484. value: function _isBaseModuleCall(exports) {
  485. return exports.SingleVideoControl && exports.MultiVideoControl;
  486. }
  487. }, {
  488. key: 'hookBase',
  489. value: function hookBase(cb, mode) {
  490. var _this2 = this;
  491.  
  492. var callbacks = [];
  493. var codeCallbacks = [];
  494. (mode === 'code' ? codeCallbacks : callbacks).push(cb);
  495.  
  496. this._hookModuleCall(function (exports, args) {
  497. if (codeCallbacks.length > 0) {
  498. var code = args[3].m[args[1].i].toString();
  499. code = codeCallbacks.reduce(function (c, cb) {
  500. return cb(c);
  501. }, code);
  502. var fn = new (Function.prototype.bind.apply(Function, [null].concat(_toConsumableArray(_this2._extractArgsName(code)), [_this2._extractFunctionBody(code)])))();
  503. fn.apply(args[0], args.slice(1));
  504. }
  505. callbacks.forEach(function (cb) {
  506. return cb(args[1].exports);
  507. });
  508. _this2.hookBase = null;
  509. }, this._isBaseModuleCall);
  510.  
  511. this.hookBase = function (cb, mode) {
  512. return (mode === 'code' ? codeCallbacks : callbacks).push(cb);
  513. };
  514. }
  515. }, {
  516. key: 'hookOz',
  517. value: function hookOz(cb) {
  518. var callbacks = [cb];
  519. var window = unsafeWindow;
  520. var oz = window.oz; // oz 可能先于脚本执行
  521. Object.defineProperty(window, 'oz', {
  522. get: function get() {
  523. return oz;
  524. },
  525. set: function set(value) {
  526. oz = value;
  527. try {
  528. callbacks.forEach(function (cb) {
  529. return cb(oz);
  530. });
  531. } catch (err) {
  532. Logger.error(err.stack);
  533. }
  534. }
  535. });
  536. if (oz) window.oz = oz; // oz 先于脚本执行
  537.  
  538. this.hookOz = function (cb) {
  539. return callbacks.push(cb);
  540. };
  541. }
  542. }, {
  543. key: 'hookDefine',
  544. value: function hookDefine(name, cb) {
  545. var _this3 = this;
  546.  
  547. var callbacksMap = new Map([[name, [cb]]]);
  548. this.hookOz(function (oz) {
  549. var self = _this3;
  550. var define = oz.define;
  551. oz.define = function (name, deps, block) {
  552. if (callbacksMap.has(name)) {
  553. var code = block.toString();
  554. code = callbacksMap.get(name).reduce(function (c, cb) {
  555. return cb(c);
  556. }, code);
  557. block = new (Function.prototype.bind.apply(Function, [null].concat(_toConsumableArray(self._extractArgsName(code)), [self._extractFunctionBody(code)])))();
  558. }
  559. define(name, deps, block);
  560. };
  561. });
  562.  
  563. this.hookDefine = function (name, cb) {
  564. if (callbacksMap.has(name)) {
  565. callbacksMap.get(name).push(cb);
  566. } else {
  567. callbacksMap.set(name, [cb]);
  568. }
  569. };
  570. }
  571. }]);
  572.  
  573. return Hooker;
  574. }();
  575.  
  576. var Patch = function () {
  577. function Patch() {
  578. _classCallCheck(this, Patch);
  579.  
  580. this._installed = false;
  581. }
  582.  
  583. _createClass(Patch, [{
  584. key: 'install',
  585. value: function install() {
  586. if (!this._installed) {
  587. this._installed = true;
  588. this._apply();
  589. }
  590. }
  591. }, {
  592. key: '_apply',
  593. value: function _apply() {}
  594. }]);
  595.  
  596. return Patch;
  597. }();
  598.  
  599. var MockAdsPatch = function (_Patch) {
  600. _inherits(MockAdsPatch, _Patch);
  601.  
  602. function MockAdsPatch() {
  603. _classCallCheck(this, MockAdsPatch);
  604.  
  605. return _possibleConstructorReturn(this, (MockAdsPatch.__proto__ || Object.getPrototypeOf(MockAdsPatch)).call(this));
  606. }
  607.  
  608. _createClass(MockAdsPatch, [{
  609. key: '_apply',
  610. value: function _apply() {
  611. var self = this;
  612. Hooker.hookAdService(function (exports) {
  613. exports.default.prototype.requestAdData = function (obj /* , params */) {
  614. var _this5 = this;
  615.  
  616. setTimeout(function () {
  617. if ('frontad' === obj.adtype) {
  618. _this5.success(obj, self._fakeFrontAdData());
  619. } else {
  620. _this5.fail(obj, { code: '404', message: 'error' });
  621. }
  622. }, 0);
  623. };
  624. });
  625. }
  626. }, {
  627. key: '_fakeFrontAdData',
  628. value: function _fakeFrontAdData() {
  629. var data = {
  630. VAL: []
  631. };
  632. return data;
  633. }
  634. }]);
  635.  
  636. return MockAdsPatch;
  637. }(Patch);
  638.  
  639. var WatermarksPatch = function (_Patch2) {
  640. _inherits(WatermarksPatch, _Patch2);
  641.  
  642. function WatermarksPatch() {
  643. _classCallCheck(this, WatermarksPatch);
  644.  
  645. return _possibleConstructorReturn(this, (WatermarksPatch.__proto__ || Object.getPrototypeOf(WatermarksPatch)).call(this));
  646. }
  647.  
  648. _createClass(WatermarksPatch, [{
  649. key: '_apply',
  650. value: function _apply() {
  651. Hooker.hookLogo(function (exports) {
  652. exports.default.prototype.reset = function () {};
  653. });
  654. }
  655. }]);
  656.  
  657. return WatermarksPatch;
  658. }(Patch);
  659.  
  660. var VipPatch = function (_Patch3) {
  661. _inherits(VipPatch, _Patch3);
  662.  
  663. function VipPatch() {
  664. _classCallCheck(this, VipPatch);
  665.  
  666. return _possibleConstructorReturn(this, (VipPatch.__proto__ || Object.getPrototypeOf(VipPatch)).call(this));
  667. }
  668.  
  669. _createClass(VipPatch, [{
  670. key: '_apply',
  671. value: function _apply() {
  672. Hooker.hookUpsOnComplete(function (res) {
  673. var data = res.data;
  674. data.user = Object.assign(data.user || {}, { vip: true });
  675. data.vip = Object.assign(data.vip || {}, { hd3: true });
  676. });
  677. }
  678. }]);
  679.  
  680. return VipPatch;
  681. }(Patch);
  682.  
  683. var QualityPatch = function (_Patch4) {
  684. _inherits(QualityPatch, _Patch4);
  685.  
  686. function QualityPatch() {
  687. _classCallCheck(this, QualityPatch);
  688.  
  689. return _possibleConstructorReturn(this, (QualityPatch.__proto__ || Object.getPrototypeOf(QualityPatch)).call(this));
  690. }
  691.  
  692. _createClass(QualityPatch, [{
  693. key: '_apply',
  694. value: function _apply() {
  695. this._improveAdaptQuality();
  696. }
  697. }, {
  698. key: '_findBestQuality',
  699. value: function _findBestQuality(qualityList) {
  700. return ['1080p', '720p', '480p', '320p'].find(function (q) {
  701. return qualityList.some(function (v) {
  702. return v === q;
  703. });
  704. });
  705. }
  706. }, {
  707. key: '_improveAdaptQuality',
  708. value: function _improveAdaptQuality() {
  709. var self = this;
  710. Hooker.hookGlobal(function (exports) {
  711. var adaptQuality = exports.default.prototype.adaptQuality;
  712. exports.default.prototype.adaptQuality = function (lang) {
  713. var cfg = this._config;
  714. var quality = cfg.quality;
  715. adaptQuality.apply(this, [lang]);
  716. if (!this.qualityList.includes(quality)) {
  717. cfg.quality = self._findBestQuality(this.qualityList);
  718. }
  719. };
  720. });
  721. }
  722. }]);
  723.  
  724. return QualityPatch;
  725. }(Patch);
  726.  
  727. var DashboardPatch = function (_Patch5) {
  728. _inherits(DashboardPatch, _Patch5);
  729.  
  730. function DashboardPatch() {
  731. _classCallCheck(this, DashboardPatch);
  732.  
  733. return _possibleConstructorReturn(this, (DashboardPatch.__proto__ || Object.getPrototypeOf(DashboardPatch)).call(this));
  734. }
  735.  
  736. _createClass(DashboardPatch, [{
  737. key: '_apply',
  738. value: function _apply() {
  739. this._prepare();
  740. this._patch();
  741. }
  742. }, {
  743. key: '_prepare',
  744. value: function _prepare() {
  745. this._exposeDashboard();
  746. Hooker.hookPreviewLayerBind(function (that) {
  747. that._el.addEventListener('mouseover', function () {
  748. return that.emit('mouseoverpreview');
  749. });
  750. that._el.addEventListener('mouseleave', function () {
  751. return that.emit('mouseleavepreview');
  752. });
  753. });
  754. }
  755. }, {
  756. key: '_findVarName',
  757. value: function _findVarName(code) {
  758. return (/"dashboard"\s*,\s*(\w+)/.exec(code)[1]
  759. );
  760. }
  761. }, {
  762. key: '_exposeDashboard',
  763. value: function _exposeDashboard() {
  764. var _this10 = this;
  765.  
  766. Hooker.hookBase(function (code) {
  767. var varName = _this10._findVarName(code);
  768. return code.replace(/\.exports\s*=\s*(\w+)/, '$&;$1.__Dashboard=' + varName + ';');
  769. }, 'code');
  770. }
  771. }, {
  772. key: '_patch',
  773. value: function _patch() {
  774. Hooker.hookBase(function (exports) {
  775. var proto = exports.__Dashboard.prototype;
  776.  
  777. proto.bindAutoHide = function () {
  778. var _this11 = this;
  779.  
  780. this._args.show = 'function' === typeof this._args.show ? this._args.show : function () {};
  781. this._args.hide = 'function' === typeof this._args.hide ? this._args.show : function () {};
  782.  
  783. this._el.addEventListener('mouseover', function () {
  784. return _this11._mouseover = true;
  785. });
  786. this._el.addEventListener('mouseleave', function () {
  787. return _this11._mouseover = false;
  788. });
  789. this.on('mouseoverpreview', function () {
  790. return _this11._mouseoverpreview = true;
  791. });
  792. this.on('mouseleavepreview', function () {
  793. return _this11._mouseoverpreview = false;
  794. });
  795. this._video.on('play', function () {
  796. if (!_this11._mouseover && !_this11._mouseoverpreview) _this11._hideTimeout = setTimeout(_this11.hide.bind(_this11), _this11._args.autoHide);
  797. });
  798. this._video.on('pause', function () {
  799. _this11._hideTimeout && clearTimeout(_this11._hideTimeout);
  800. _this11.isShow() || _this11.show();
  801. });
  802. this._parent.addEventListener('mousemove', function () {
  803. _this11._hideTimeout && clearTimeout(_this11._hideTimeout);
  804. _this11.isShow() || _this11.show();
  805. if (!_this11._isPaused() && !_this11._mouseover && !_this11._mouseoverpreview) _this11._hideTimeout = setTimeout(_this11.hide.bind(_this11), _this11._args.autoHide);
  806. });
  807. this._parent.addEventListener('mouseleave', function () {
  808. _this11._hideTimeout && clearTimeout(_this11._hideTimeout);
  809. if (!_this11._isPaused()) _this11.hide();
  810. });
  811. };
  812.  
  813. proto._isPaused = function () {
  814. return this._video._videoCore.video.paused;
  815. };
  816.  
  817. proto.isShow = function () {
  818. return this._el.style.display !== 'none';
  819. };
  820.  
  821. proto.show = function () {
  822. this.emit('dashboardshow');
  823. this._parent.style.cursor = '';
  824. this._el.style.display = '';
  825. this._args.show();
  826. };
  827.  
  828. proto.hide = function () {
  829. this.emit('dashboardhide');
  830. this._parent.style.cursor = 'none'; // 隐藏鼠标
  831. this._el.style.display = 'none';
  832. this._args.show();
  833. };
  834. });
  835. }
  836. }]);
  837.  
  838. return DashboardPatch;
  839. }(Patch);
  840.  
  841. var TopAreaPatch = function (_Patch6) {
  842. _inherits(TopAreaPatch, _Patch6);
  843.  
  844. function TopAreaPatch() {
  845. _classCallCheck(this, TopAreaPatch);
  846.  
  847. return _possibleConstructorReturn(this, (TopAreaPatch.__proto__ || Object.getPrototypeOf(TopAreaPatch)).call(this));
  848. }
  849.  
  850. _createClass(TopAreaPatch, [{
  851. key: '_apply',
  852. value: function _apply() {
  853. Hooker.hookTopAreaAddEvent(function (that) {
  854. that.on('webfullscreen', function (isWebFullscreen) {
  855. isWebFullscreen ? that._showHideTop(true) : that._hideHideTop();
  856. });
  857. that.on('dashboardshow', function () {
  858. var playerState = that._video.global.playerState;
  859. if (playerState.fullscreen || playerState.webfullscreen) {
  860. that._showHideTop(true);
  861. }
  862. });
  863. that.on('dashboardhide', function () {
  864. var playerState = that._video.global.playerState;
  865. if (playerState.fullscreen || playerState.webfullscreen) {
  866. that._hideHideTop();
  867. }
  868. });
  869. });
  870. Hooker.hookResetPlayerAfter(function (that) {
  871. // 网页全屏播放上下集重置播放器后显示顶部控件
  872. if (!that.global.playerState.fullscreen) that._player.control.emit('webfullscreen', that.global.playerState.webfullscreen);
  873. });
  874. }
  875. }]);
  876.  
  877. return TopAreaPatch;
  878. }(Patch);
  879.  
  880. var SettingSeriesPatch = function (_Patch7) {
  881. _inherits(SettingSeriesPatch, _Patch7);
  882.  
  883. function SettingSeriesPatch() {
  884. _classCallCheck(this, SettingSeriesPatch);
  885.  
  886. return _possibleConstructorReturn(this, (SettingSeriesPatch.__proto__ || Object.getPrototypeOf(SettingSeriesPatch)).call(this));
  887. }
  888.  
  889. _createClass(SettingSeriesPatch, [{
  890. key: '_apply',
  891. value: function _apply() {
  892. Hooker.hookSettingSeries(function (exports) {
  893. // 网页全屏显示选集
  894. var _addEvent = exports.default.prototype._addEvent;
  895. exports.default.prototype._addEvent = function () {
  896. var _this14 = this;
  897.  
  898. _addEvent.apply(this);
  899. this.on('webfullscreen', function (isWebFullscreen) {
  900. if (isWebFullscreen) {
  901. if (_this14.seriesList.length > 1) _this14._el.style.display = 'inline-block';
  902. } else {
  903. _this14._el.style.display = 'none';
  904. _this14._el.classList.remove('cliced');
  905. _this14.emit('seriesliseLayer', false);
  906. }
  907. });
  908. };
  909. });
  910. }
  911. }]);
  912.  
  913. return SettingSeriesPatch;
  914. }(Patch);
  915.  
  916. var ContinuePlayPatch = function (_Patch8) {
  917. _inherits(ContinuePlayPatch, _Patch8);
  918.  
  919. function ContinuePlayPatch() {
  920. _classCallCheck(this, ContinuePlayPatch);
  921.  
  922. return _possibleConstructorReturn(this, (ContinuePlayPatch.__proto__ || Object.getPrototypeOf(ContinuePlayPatch)).call(this));
  923. }
  924.  
  925. _createClass(ContinuePlayPatch, [{
  926. key: '_apply',
  927. value: function _apply() {
  928. var _this16 = this;
  929.  
  930. Hooker.hookInitPlayerEvent(function (that) {
  931. // 视频播放结束处理
  932. that._player.control.on('ended', that._onEnd.bind(that));
  933. that._player.control.on('ended', function () {
  934. return _this16._onEnd(that);
  935. });
  936. });
  937. }
  938. }, {
  939. key: '_onEnd',
  940. value: function _onEnd(that) {
  941. var config = that.global.config;
  942. var playerState = that.global.playerState;
  943. if (config.continuePlay && config.nextVid && !playerState.fullscreen) {
  944. if (playerState.webfullscreen) {
  945. that.playByVid({ vid: that.global.config.nextVid });
  946. } else {
  947. that.gotoVideo(that.global.config.nextVid);
  948. }
  949. }
  950. }
  951. }]);
  952.  
  953. return ContinuePlayPatch;
  954. }(Patch);
  955.  
  956. var FullscreenPatch = function (_Patch9) {
  957. _inherits(FullscreenPatch, _Patch9);
  958.  
  959. function FullscreenPatch() {
  960. _classCallCheck(this, FullscreenPatch);
  961.  
  962. return _possibleConstructorReturn(this, (FullscreenPatch.__proto__ || Object.getPrototypeOf(FullscreenPatch)).call(this));
  963. }
  964.  
  965. _createClass(FullscreenPatch, [{
  966. key: '_apply',
  967. value: function _apply() {
  968. Object.defineProperty(document, 'fullscreen', {});
  969. }
  970. }]);
  971.  
  972. return FullscreenPatch;
  973. }(Patch);
  974.  
  975. var WebFullscreen = function () {
  976. function WebFullscreen(elem) {
  977. _classCallCheck(this, WebFullscreen);
  978.  
  979. this._elem = elem;
  980. }
  981.  
  982. _createClass(WebFullscreen, [{
  983. key: 'isWebFullscreen',
  984. value: function isWebFullscreen() {
  985. return this._elem.classList.contains('webfullscreen');
  986. }
  987. }, {
  988. key: 'enter',
  989. value: function enter() {
  990. this._elem.classList.add('webfullscreen');
  991. document.body.style.overflow = 'hidden';
  992.  
  993. var parentNode = this._elem.parentNode;
  994. while (parentNode.nodeName !== 'BODY') {
  995. if (parentNode.nodeType === Node.ELEMENT_NODE) {
  996. parentNode.classList.add('z-top');
  997. }
  998. parentNode = parentNode.parentNode;
  999. }
  1000. }
  1001. }, {
  1002. key: 'exit',
  1003. value: function exit() {
  1004. this._elem.classList.remove('webfullscreen');
  1005. document.body.style.overflow = '';
  1006.  
  1007. var parentNode = this._elem.parentNode;
  1008. while (parentNode.nodeName !== 'BODY') {
  1009. if (parentNode.nodeType === Node.ELEMENT_NODE) {
  1010. parentNode.classList.remove('z-top');
  1011. }
  1012. parentNode = parentNode.parentNode;
  1013. }
  1014. }
  1015. }, {
  1016. key: 'toggle',
  1017. value: function toggle() {
  1018. this.isWebFullscreen() ? this.exit() : this.enter();
  1019. }
  1020. }], [{
  1021. key: 'addStyle',
  1022. value: function addStyle() {
  1023. GM_addStyle('\n .z-top {\n position: relative !important;\n z-index: 23333333 !important;\n }\n .webfullscreen {\n display: block !important;\n position: fixed !important;\n width: 100% !important;\n height: 100% !important;\n top: 0 !important;\n left: 0 !important;\n background: #000 !important;\n z-index: 23333333 !important;\n }\n ');
  1024. }
  1025. }]);
  1026.  
  1027. return WebFullscreen;
  1028. }();
  1029.  
  1030. var ManagePatch = function (_Patch10) {
  1031. _inherits(ManagePatch, _Patch10);
  1032.  
  1033. function ManagePatch() {
  1034. _classCallCheck(this, ManagePatch);
  1035.  
  1036. return _possibleConstructorReturn(this, (ManagePatch.__proto__ || Object.getPrototypeOf(ManagePatch)).call(this));
  1037. }
  1038.  
  1039. _createClass(ManagePatch, [{
  1040. key: '_apply',
  1041. value: function _apply() {
  1042. this._prepare();
  1043. this._hookManage();
  1044. }
  1045. }, {
  1046. key: '_prepare',
  1047. value: function _prepare() {
  1048. this._customTip();
  1049. this._disablePlayAfterSeek();
  1050. this._addPrevInfo();
  1051. this._playAfterPlayerReset();
  1052. this._keepPlaybackRate();
  1053. this._playbackRatePersistence();
  1054. new ContinuePlayPatch().install();
  1055. new FullscreenPatch().install();
  1056. }
  1057. }, {
  1058. key: '_customTip',
  1059. value: function _customTip() {
  1060. Hooker.hookTips(function (exports) {
  1061. var showHintTips = exports.default.prototype.showHintTips;
  1062. exports.default.prototype.showHintTips = function (code, info) {
  1063. if (info.msg) {
  1064. this._hintLayer.setHintShow(info.msg);
  1065. } else {
  1066. showHintTips.apply(this, [code, info]);
  1067. }
  1068. };
  1069. });
  1070. }
  1071. }, {
  1072. key: '_disablePlayAfterSeek',
  1073. value: function _disablePlayAfterSeek() {
  1074. // SingleVideoControl seek 后不自动播放
  1075. Hooker.hookBase(function (exports) {
  1076. var _setCurrentTime = exports.SingleVideoControl.prototype._setCurrentTime;
  1077. exports.SingleVideoControl.prototype._setCurrentTime = function (time) {
  1078. var play = this.video.play;
  1079. this.video.play = function () {};
  1080. _setCurrentTime.apply(this, [time]);
  1081. this.video.play = play;
  1082. };
  1083. });
  1084. }
  1085. }, {
  1086. key: '_keepPlaybackRate',
  1087. value: function _keepPlaybackRate() {
  1088. Hooker.hookBase(function (exports) {
  1089. var proto = exports.MultiVideoControl.prototype;
  1090. var _setVideo = proto._setVideo;
  1091. proto._setVideo = function () {
  1092. var rate = this.video.playbackRate;
  1093.  
  1094. for (var _len9 = arguments.length, args = Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
  1095. args[_key9] = arguments[_key9];
  1096. }
  1097.  
  1098. _setVideo.apply(this, args);
  1099. this.video.playbackRate = rate;
  1100. };
  1101. });
  1102. }
  1103. }, {
  1104. key: '_playbackRatePersistence',
  1105. value: function _playbackRatePersistence() {
  1106. var util = void 0;
  1107. Hooker.hookUtil(function (exports) {
  1108. return util = exports;
  1109. });
  1110. Hooker.hookSettingsIcon(function (exports) {
  1111. var proto = exports.default.prototype;
  1112. var setDataUI = proto.setDataUI;
  1113. proto.setDataUI = function (data) {
  1114. var _this19 = this;
  1115.  
  1116. setDataUI.apply(this, [data]);
  1117. this._video.global.playerState = {
  1118. playbackRate: data.playbackRate || 1,
  1119. normalPlaybackRate: true
  1120. };
  1121. this.on('playbackratechange', function (rate) {
  1122. _this19.data.playbackRate = rate;
  1123. util.setLocalData('YK_PSL_SETTINGS', _this19.data);
  1124. });
  1125. };
  1126. });
  1127. }
  1128. }, {
  1129. key: '_addPrevInfo',
  1130. value: function _addPrevInfo() {
  1131. Hooker.hookGlobalDeal(function (that) {
  1132. if (that.ups && that.ups.videoData && that.ups.programList && that.ups.programList.videoList) {
  1133. var list = that.ups.programList.videoList;
  1134. var currVid = that.ups.videoData.id;
  1135. var currIdx = list.findIndex(function (item) {
  1136. return parseInt(item.vid) === currVid;
  1137. });
  1138. if (currIdx > 0) {
  1139. var prevVideo = list[currIdx - 1];
  1140. that.ups.programList.prevVideo = prevVideo;
  1141. prevVideo && (that._config.prevVid = prevVideo.encodevid);
  1142. }
  1143. }
  1144. });
  1145. }
  1146. }, {
  1147. key: '_playAfterPlayerReset',
  1148. value: function _playAfterPlayerReset() {
  1149. Hooker.hookResetPlayerAfter(function (that) {
  1150. if (that.global.playerState.state === 'playerreset') that.play();
  1151. });
  1152. }
  1153. }, {
  1154. key: '_hookManage',
  1155. value: function _hookManage() {
  1156. Hooker.hookManage(this._hookManageCallback.bind(this));
  1157. }
  1158. }, {
  1159. key: '_hookManageCallback',
  1160. value: function _hookManageCallback(exports) {
  1161. var proto = exports.default.prototype;
  1162.  
  1163. var _init = proto._init;
  1164. proto._init = function () {
  1165. _init.apply(this);
  1166. WebFullscreen.addStyle();
  1167. this._webfullscreen = new WebFullscreen(this.container);
  1168. };
  1169.  
  1170. proto._showTip = function (msg) {
  1171. this._emitter.emit('player.showinfo', { type: 'hint', msg: msg });
  1172. };
  1173.  
  1174. proto.play = function () {
  1175. this._player && this._player.control.play();
  1176. this._showTip('播放');
  1177. };
  1178.  
  1179. proto._pause = proto.pause;
  1180. proto.pause = function () {
  1181. this._pause();
  1182. this._showTip('暂停');
  1183. };
  1184.  
  1185. proto.adjustVolume = function (value) {
  1186. var volume = this.global.playerState.volume + value;
  1187. volume = Math.max(0, Math.min(1, volume.toFixed(2)));
  1188. this._player.control.setVolume(volume);
  1189. if (volume === 0) {
  1190. this._emitter.emit('player.showinfo', { type: 'hint', code: 'H0003', volume: volume + '%' });
  1191. }
  1192. };
  1193.  
  1194. proto.toggleMute = function () {
  1195. if (this.global.playerState.muted) this._showTip('取消静音');
  1196. this.setMuted(!this.global.playerState.muted);
  1197. };
  1198.  
  1199. proto.stepSeek = function (stepTime) {
  1200. var duration = this._player.control.getDuration();
  1201. var currentTime = this.global.currentTime;
  1202. var seekTime = Math.max(0, Math.min(duration, currentTime + stepTime));
  1203. this.seek(seekTime);
  1204.  
  1205. var msg = void 0;
  1206. if (Math.abs(stepTime) < 60) {
  1207. msg = stepTime > 0 ? '\u6B65\u8FDB\uFF1A' + stepTime + '\u79D2' : '\u6B65\u9000\uFF1A' + Math.abs(stepTime) + '\u79D2';
  1208. } else {
  1209. msg = stepTime > 0 ? '\u6B65\u8FDB\uFF1A' + stepTime / 60 + '\u5206\u949F' : '\u6B65\u9000\uFF1A' + Math.abs(stepTime) / 60 + '\u5206\u949F';
  1210. }
  1211. this._showTip(msg);
  1212. };
  1213.  
  1214. proto.rangeSeek = function (range) {
  1215. var duration = this._player.control.getDuration();
  1216. var seekTime = Math.max(0, Math.min(duration, duration * range));
  1217. this.seek(seekTime);
  1218. this._showTip('定位:' + (range * 100).toFixed(0) + '%');
  1219. };
  1220.  
  1221. proto.isFullscreen = function () {
  1222. return this.global.playerState.fullscreen;
  1223. };
  1224.  
  1225. proto.toggleFullscreen = function () {
  1226. if (this.isFullscreen()) {
  1227. this.exitFullscreen();
  1228. } else {
  1229. this.fullScreen();
  1230. }
  1231. };
  1232.  
  1233. proto.isWebFullscreen = function () {
  1234. return this._webfullscreen.isWebFullscreen();
  1235. };
  1236.  
  1237. proto.enterWebFullscreen = function () {
  1238. this._webfullscreen.enter();
  1239. this.global.playerState = { webfullscreen: true };
  1240. this._player.control.emit('webfullscreen', true);
  1241. };
  1242.  
  1243. proto.exitWebFullscreen = function () {
  1244. this._webfullscreen.exit();
  1245. this.global.playerState = { webfullscreen: false };
  1246. this._player.control.emit('webfullscreen', false);
  1247. };
  1248.  
  1249. proto.toggleWebFullscreen = function () {
  1250. this.isWebFullscreen() ? this.exitWebFullscreen() : this.enterWebFullscreen();
  1251. };
  1252.  
  1253. proto.adjustPlaybackRate = function (value) {
  1254. var player = this._player;
  1255. var control = player.control;
  1256. var videoCore = control._videoCore;
  1257. var video = videoCore.video;
  1258. var rate = Math.max(0.2, Math.min(5, parseFloat((video.playbackRate + value).toFixed(1))));
  1259. if (player.config.controlType === 'multi') {
  1260. videoCore._videoElments.forEach(function (v) {
  1261. return v.playbackRate = rate;
  1262. });
  1263. } else {
  1264. video.playbackRate = rate;
  1265. }
  1266. this.global.playerState = { playbackRate: rate };
  1267. control.emit('playbackratechange', rate);
  1268. this._showTip('\u64AD\u653E\u901F\u7387\uFF1A' + rate);
  1269. };
  1270.  
  1271. proto.turnPlaybackRate = function () {
  1272. var state = this.global.playerState;
  1273. var rate = state.normalPlaybackRate ? state.playbackRate : 1;
  1274. state.normalPlaybackRate = !state.normalPlaybackRate;
  1275. this._player.control.setRate(rate);
  1276. this._showTip('\u64AD\u653E\u901F\u7387\uFF1A' + rate);
  1277. };
  1278.  
  1279. proto.getFps = function () {
  1280. return 25; // 标清fps为15,标清以上fps为25。
  1281. };
  1282.  
  1283. proto.prevFrame = function () {
  1284. var state = this.global.playerState.state;
  1285. if (state === 'playing') this.pause();
  1286. var duration = this._player.control.getDuration();
  1287. var currentTime = this.global.currentTime;
  1288. var seekTime = Math.max(0, Math.min(duration, currentTime - 1 / this.getFps()));
  1289. this.seek(seekTime);
  1290. this._showTip('上一帧');
  1291. };
  1292.  
  1293. proto.nextFrame = function () {
  1294. var state = this.global.playerState.state;
  1295. if (state === 'playing') this.pause();
  1296. var duration = this._player.control.getDuration();
  1297. var currentTime = this.global.currentTime;
  1298. var seekTime = Math.max(0, Math.min(duration, currentTime + 1 / this.getFps()));
  1299. this.seek(seekTime);
  1300. this._showTip('下一帧');
  1301. };
  1302.  
  1303. proto.playPrev = function () {
  1304. var prevVid = this.global.config.prevVid;
  1305. if (prevVid) {
  1306. if (this.isFullscreen() || this.isWebFullscreen()) {
  1307. this.playByVid({ vid: prevVid });
  1308. } else {
  1309. this.gotoVideo(prevVid);
  1310. }
  1311. this._showTip('播放上一集');
  1312. } else {
  1313. this._showTip('没有上一集哦');
  1314. }
  1315. };
  1316.  
  1317. var playNext = proto.playNext;
  1318. proto.playNext = function (data) {
  1319. if (data) return playNext.apply(this, [data]);
  1320. var nextVid = this.global.config.nextVid;
  1321. if (nextVid) {
  1322. if (this.isFullscreen() || this.isWebFullscreen()) {
  1323. this.playByVid({ vid: nextVid });
  1324. } else {
  1325. this.gotoVideo(nextVid);
  1326. }
  1327. this._showTip('播放下一集');
  1328. } else {
  1329. this._showTip('没有下一集哦');
  1330. }
  1331. };
  1332.  
  1333. proto.gotoVideo = function (vid) {
  1334. location.href = '//v.youku.com/v_show/id_' + vid + '.html';
  1335. };
  1336. }
  1337. }]);
  1338.  
  1339. return ManagePatch;
  1340. }(Patch);
  1341.  
  1342. var managePatch = new ManagePatch();
  1343.  
  1344. var KeyShortcutsPatch = function (_Patch11) {
  1345. _inherits(KeyShortcutsPatch, _Patch11);
  1346.  
  1347. function KeyShortcutsPatch() {
  1348. _classCallCheck(this, KeyShortcutsPatch);
  1349.  
  1350. return _possibleConstructorReturn(this, (KeyShortcutsPatch.__proto__ || Object.getPrototypeOf(KeyShortcutsPatch)).call(this));
  1351. }
  1352.  
  1353. _createClass(KeyShortcutsPatch, [{
  1354. key: '_apply',
  1355. value: function _apply() {
  1356. this._prepare();
  1357. this._addListener();
  1358. }
  1359. }, {
  1360. key: '_prepare',
  1361. value: function _prepare() {
  1362. managePatch.install();
  1363. this._obtainPlayer();
  1364. }
  1365. }, {
  1366. key: '_obtainPlayer',
  1367. value: function _obtainPlayer() {
  1368. var self = this;
  1369. Hooker.hookKeyShortcuts(function (exports) {
  1370. exports.default.prototype.registerEvents = function () {
  1371. self._player = this._player;
  1372. };
  1373. });
  1374. }
  1375. }, {
  1376. key: '_addListener',
  1377. value: function _addListener() {
  1378. document.addEventListener('keydown', this._handler.bind(this));
  1379. }
  1380. }, {
  1381. key: '_handler',
  1382. value: function _handler(event) {
  1383. if (event.target.nodeName !== 'BODY') return;
  1384.  
  1385. switch (event.keyCode) {
  1386. case 32:
  1387. // Spacebar
  1388. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1389. var state = this._player.global.playerState.state;
  1390. if (state === 'paused') {
  1391. this._player.play();
  1392. } else if (state === 'ended') {
  1393. this._player.replay();
  1394. } else {
  1395. this._player.pause();
  1396. }
  1397. } else {
  1398. return;
  1399. }
  1400. break;
  1401. case 39: // → Arrow Right
  1402. case 37:
  1403. {
  1404. // ← Arrow Left
  1405. var stepTime = void 0;
  1406. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1407. stepTime = 39 === event.keyCode ? 5 : -5;
  1408. } else if (event.ctrlKey && !event.shiftKey && !event.altKey) {
  1409. stepTime = 39 === event.keyCode ? 30 : -30;
  1410. } else if (!event.ctrlKey && event.shiftKey && !event.altKey) {
  1411. stepTime = 39 === event.keyCode ? 60 : -60;
  1412. } else if (event.ctrlKey && !event.shiftKey && event.altKey) {
  1413. stepTime = 39 === event.keyCode ? 3e2 : -3e2; // 5分钟
  1414. } else {
  1415. return;
  1416. }
  1417. this._player.stepSeek(stepTime);
  1418. break;
  1419. }
  1420. case 38: // ↑ Arrow Up
  1421. case 40:
  1422. // ↓ Arrow Down
  1423. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1424. this._player.adjustVolume(38 === event.keyCode ? 0.05 : -0.05);
  1425. } else {
  1426. return;
  1427. }
  1428. break;
  1429. case 77:
  1430. // M
  1431. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1432. this._player.toggleMute();
  1433. } else {
  1434. return;
  1435. }
  1436. break;
  1437. case 13:
  1438. // Enter
  1439. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1440. this._player.toggleFullscreen();
  1441. } else if (event.ctrlKey && !event.shiftKey && !event.altKey) {
  1442. this._player.toggleWebFullscreen();
  1443. } else {
  1444. return;
  1445. }
  1446. break;
  1447. case 67: // C
  1448. case 88:
  1449. // X
  1450. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1451. this._player.adjustPlaybackRate(67 === event.keyCode ? 0.1 : -0.1);
  1452. } else {
  1453. return;
  1454. }
  1455. break;
  1456. case 90:
  1457. // Z
  1458. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1459. this._player.turnPlaybackRate();
  1460. } else {
  1461. return;
  1462. }
  1463. break;
  1464. case 68: // D
  1465. case 70:
  1466. // F
  1467. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1468. if (event.keyCode === 68) {
  1469. this._player.prevFrame();
  1470. } else {
  1471. this._player.nextFrame();
  1472. }
  1473. } else {
  1474. return;
  1475. }
  1476. break;
  1477. case 80: // P
  1478. case 78:
  1479. // N
  1480. if (!event.ctrlKey && event.shiftKey && !event.altKey) {
  1481. if (event.keyCode === 78) {
  1482. this._player.playNext();
  1483. } else {
  1484. this._player.playPrev();
  1485. }
  1486. } else {
  1487. return;
  1488. }
  1489. break;
  1490. case 27:
  1491. // ESC
  1492. if (!event.ctrlKey && !event.shiftKey && !event.altKey) this._player.isWebFullscreen() && this._player.exitWebFullscreen();
  1493. return;
  1494. default:
  1495. if (event.keyCode >= 48 && event.keyCode <= 57) {
  1496. // 0 ~ 9
  1497. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1498. this._player.rangeSeek((event.keyCode - 48) * 0.1);
  1499. } else {
  1500. return;
  1501. }
  1502. } else {
  1503. return;
  1504. }
  1505. }
  1506.  
  1507. event.preventDefault();
  1508. event.stopPropagation();
  1509. }
  1510. }]);
  1511.  
  1512. return KeyShortcutsPatch;
  1513. }(Patch);
  1514.  
  1515. var MouseShortcutsPatch = function (_Patch12) {
  1516. _inherits(MouseShortcutsPatch, _Patch12);
  1517.  
  1518. function MouseShortcutsPatch() {
  1519. _classCallCheck(this, MouseShortcutsPatch);
  1520.  
  1521. return _possibleConstructorReturn(this, (MouseShortcutsPatch.__proto__ || Object.getPrototypeOf(MouseShortcutsPatch)).call(this));
  1522. }
  1523.  
  1524. _createClass(MouseShortcutsPatch, [{
  1525. key: '_apply',
  1526. value: function _apply() {
  1527. this._prepare();
  1528. this._addListener();
  1529. }
  1530. }, {
  1531. key: '_prepare',
  1532. value: function _prepare() {
  1533. managePatch.install();
  1534. this._addStyle();
  1535. }
  1536. }, {
  1537. key: '_addStyle',
  1538. value: function _addStyle() {
  1539. GM_addStyle('\n .h5-layer-conatiner {\n -webkit-user-select: none !important;\n -moz-user-select: none !important;\n -ms-user-select: none !important;\n user-select: none !important;\n }\n .h5-ext-layer-adsdk {\n display: none !important;\n }\n ');
  1540. }
  1541. }, {
  1542. key: '_addListener',
  1543. value: function _addListener() {
  1544. Hooker.hookInitPlayerEvent(function (that) {
  1545. var timer = void 0;
  1546. var container = that.container.querySelector('.h5-layer-conatiner');
  1547. container.addEventListener('click', function (event) {
  1548. if (this !== event.target) return;
  1549. if (timer) {
  1550. clearTimeout(timer);
  1551. timer = null;
  1552. return;
  1553. }
  1554. timer = setTimeout(function () {
  1555. var state = that.global.playerState.state;
  1556. if (state === 'paused') {
  1557. that.play();
  1558. } else if (state === 'ended') {
  1559. that.replay();
  1560. } else {
  1561. that.pause();
  1562. }
  1563. timer = null;
  1564. }, 200);
  1565. });
  1566. container.addEventListener('dblclick', function (event) {
  1567. if (this !== event.target) return;
  1568. event.ctrlKey ? that.toggleWebFullscreen() : that.toggleFullscreen();
  1569. });
  1570. container.addEventListener('wheel', function (event) {
  1571. if (this === event.target && (that.isFullscreen() || that.isWebFullscreen())) {
  1572. var delta = event.wheelDelta || event.detail || event.deltaY && -event.deltaY;
  1573. that.adjustVolume(delta > 0 ? 0.05 : -0.05);
  1574. }
  1575. });
  1576. container = null;
  1577. });
  1578. }
  1579. }]);
  1580.  
  1581. return MouseShortcutsPatch;
  1582. }(Patch);
  1583.  
  1584. var ShortcutsPatch = function (_Patch13) {
  1585. _inherits(ShortcutsPatch, _Patch13);
  1586.  
  1587. function ShortcutsPatch() {
  1588. _classCallCheck(this, ShortcutsPatch);
  1589.  
  1590. return _possibleConstructorReturn(this, (ShortcutsPatch.__proto__ || Object.getPrototypeOf(ShortcutsPatch)).call(this));
  1591. }
  1592.  
  1593. _createClass(ShortcutsPatch, [{
  1594. key: '_apply',
  1595. value: function _apply() {
  1596. new KeyShortcutsPatch().install();
  1597. Logger.log('添加键盘快捷键');
  1598. new MouseShortcutsPatch().install();
  1599. Logger.log('添加鼠标快捷键');
  1600. }
  1601. }]);
  1602.  
  1603. return ShortcutsPatch;
  1604. }(Patch);
  1605.  
  1606. // class H5Patch extends Patch {
  1607.  
  1608. // constructor() {
  1609. // super();
  1610. // }
  1611.  
  1612. // _apply() {
  1613. // Hooker.hookDefine('page/find/play/player/load', this._forceH5.bind(this));
  1614. // }
  1615.  
  1616. // _forceH5(code) {
  1617. // return code.replace(/(if\s*\().*?(\)\s*\{)/, '$1true$2').replace('window.sessionStorage', 'null');
  1618. // }
  1619.  
  1620. // }
  1621.  
  1622. function ensureH5PlayerEnabled() {
  1623. // (new H5Patch()).install();
  1624. Object.defineProperty(unsafeWindow.navigator, 'plugins', { get: function get() {
  1625. return {};
  1626. } });
  1627. Logger.log('启用html5播放器');
  1628. }
  1629.  
  1630. function mockAds() {
  1631. new MockAdsPatch().install();
  1632. Logger.log('和谐广告');
  1633. }
  1634.  
  1635. function invalidateWatermarks() {
  1636. new WatermarksPatch().install();
  1637. Logger.log('和谐水印');
  1638. }
  1639.  
  1640. function invalidateQualityLimitation() {
  1641. new VipPatch().install();
  1642. Logger.log('解除会员画质限制');
  1643. }
  1644.  
  1645. function improveQualityLogic() {
  1646. new QualityPatch().install();
  1647. Logger.log('改善画质逻辑');
  1648. }
  1649.  
  1650. function improveAutoHide() {
  1651. new DashboardPatch().install();
  1652. new TopAreaPatch().install();
  1653. new SettingSeriesPatch().install();
  1654. Logger.log('改善控件与光标自动隐藏');
  1655. }
  1656.  
  1657. function improveShortcuts() {
  1658. new ShortcutsPatch().install();
  1659. }
  1660.  
  1661. //=============================================================================
  1662.  
  1663. ensureH5PlayerEnabled();
  1664. mockAds();
  1665. invalidateWatermarks();
  1666. invalidateQualityLimitation();
  1667. improveQualityLogic();
  1668. improveAutoHide();
  1669. improveShortcuts();
  1670. })();