ykh5p

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

  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.5
  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: '_isTriggerLayerComponentModuleCall',
  405. value: function _isTriggerLayerComponentModuleCall(exports) {
  406. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('showMenu');
  407. }
  408. }, {
  409. key: 'hookTriggerLayer',
  410. value: function hookTriggerLayer(cb) {
  411. this._hookModuleCall(cb, this._isTriggerLayerComponentModuleCall);
  412. }
  413. }, {
  414. key: '_isUtilModuleCall',
  415. value: function _isUtilModuleCall(exports) {
  416. return exports.setLocalData && exports.getLocalData;
  417. }
  418. }, {
  419. key: 'hookUtil',
  420. value: function hookUtil(cb) {
  421. this._hookModuleCall(cb, this._isUtilModuleCall);
  422. }
  423. }, {
  424. key: '_isGlobalModuleCall',
  425. value: function _isGlobalModuleCall(exports) {
  426. return this._isEsModule(exports) && this._isFuction(exports.default) && exports.default.prototype && exports.default.prototype.hasOwnProperty('resetConfig');
  427. }
  428. }, {
  429. key: 'hookGlobal',
  430. value: function hookGlobal(cb) {
  431. this._hookModuleCall(cb, this._isGlobalModuleCall);
  432. }
  433. }, {
  434. key: 'hookGlobalConstructorAfter',
  435. value: function hookGlobalConstructorAfter(cb) {
  436. Hooker.hookGlobal(function (exports) {
  437. var constructor = exports.default;
  438. exports.default = function () {
  439. for (var _len8 = arguments.length, args = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
  440. args[_key8] = arguments[_key8];
  441. }
  442.  
  443. constructor.apply(this, args);
  444. cb(this);
  445. };
  446. exports.default.prototype = constructor.prototype;
  447. });
  448. }
  449. }, {
  450. key: 'hookGlobalInit',
  451. value: function hookGlobalInit(cb) {
  452. Hooker.hookGlobal(function (exports) {
  453. var init = exports.default.prototype.init;
  454. exports.default.prototype.init = function (config) {
  455. cb(config, this);
  456. init.apply(this, [config]);
  457. };
  458. });
  459. }
  460. }, {
  461. key: 'hookGlobalDeal',
  462. value: function hookGlobalDeal(cb) {
  463. Hooker.hookGlobal(function (exports) {
  464. var deal = exports.default.prototype.deal;
  465. exports.default.prototype.deal = function () {
  466. cb(this);
  467. deal.apply(this);
  468. };
  469. });
  470. }
  471. }, {
  472. key: 'hookGlobalResetAfter',
  473. value: function hookGlobalResetAfter(cb) {
  474. Hooker.hookGlobal(function (exports) {
  475. var reset = exports.default.prototype.reset;
  476. exports.default.prototype.reset = function () {
  477. reset.apply(this);
  478. cb(this);
  479. };
  480. });
  481. }
  482. }, {
  483. key: '_extractArgsName',
  484. value: function _extractArgsName(code) {
  485. return code.slice(code.indexOf('(') + 1, code.indexOf(')')).split(/\s*,\s*/);
  486. }
  487. }, {
  488. key: '_extractFunctionBody',
  489. value: function _extractFunctionBody(code) {
  490. return code.slice(code.indexOf('{') + 1, code.lastIndexOf('}'));
  491. }
  492. }, {
  493. key: '_isBaseModuleCall',
  494. value: function _isBaseModuleCall(exports) {
  495. return exports.SingleVideoControl && exports.MultiVideoControl;
  496. }
  497. }, {
  498. key: 'hookBase',
  499. value: function hookBase(cb, mode) {
  500. var _this2 = this;
  501.  
  502. var callbacks = [];
  503. var codeCallbacks = [];
  504. (mode === 'code' ? codeCallbacks : callbacks).push(cb);
  505.  
  506. this._hookModuleCall(function (exports, args) {
  507. if (codeCallbacks.length > 0) {
  508. var code = args[3].m[args[1].i].toString();
  509. code = codeCallbacks.reduce(function (c, cb) {
  510. return cb(c);
  511. }, code);
  512. var fn = new (Function.prototype.bind.apply(Function, [null].concat(_toConsumableArray(_this2._extractArgsName(code)), [_this2._extractFunctionBody(code)])))();
  513. fn.apply(args[0], args.slice(1));
  514. }
  515. callbacks.forEach(function (cb) {
  516. return cb(args[1].exports);
  517. });
  518. _this2.hookBase = null;
  519. }, this._isBaseModuleCall);
  520.  
  521. this.hookBase = function (cb, mode) {
  522. return (mode === 'code' ? codeCallbacks : callbacks).push(cb);
  523. };
  524. }
  525. }, {
  526. key: 'hookGlobalVariable',
  527. value: function hookGlobalVariable(name, cb) {
  528. var window = unsafeWindow;
  529.  
  530. var value = window[name];
  531. Object.defineProperty(window, name, {
  532. get: function get() {
  533. return value;
  534. },
  535. set: function set(v) {
  536. try {
  537. var ret = cb(v);
  538. value = ret === undefined ? v : ret;
  539. } catch (err) {
  540. Logger.error(err.stack);
  541. }
  542. }
  543. });
  544. if (value) window[name] = value;
  545. }
  546. }, {
  547. key: 'hookOz',
  548. value: function hookOz(cb) {
  549. var callbacks = [cb];
  550. this.hookGlobalVariable('oz', function (oz) {
  551. callbacks.forEach(function (cb) {
  552. return cb(oz);
  553. });
  554. });
  555. this.hookOz = function (cb) {
  556. return callbacks.push(cb);
  557. };
  558. }
  559. }, {
  560. key: 'hookDefine',
  561. value: function hookDefine(name, cb) {
  562. var _this3 = this;
  563.  
  564. var callbacksMap = new Map([[name, [cb]]]);
  565. this.hookOz(function (oz) {
  566. var self = _this3;
  567. var define = oz.define;
  568. oz.define = function (name, deps, block) {
  569. if (callbacksMap.has(name)) {
  570. var code = block.toString();
  571. code = callbacksMap.get(name).reduce(function (c, cb) {
  572. return cb(c);
  573. }, code);
  574. block = new (Function.prototype.bind.apply(Function, [null].concat(_toConsumableArray(self._extractArgsName(code)), [self._extractFunctionBody(code)])))();
  575. }
  576. define(name, deps, block);
  577. };
  578. });
  579.  
  580. this.hookDefine = function (name, cb) {
  581. if (callbacksMap.has(name)) {
  582. callbacksMap.get(name).push(cb);
  583. } else {
  584. callbacksMap.set(name, [cb]);
  585. }
  586. };
  587. }
  588. }]);
  589.  
  590. return Hooker;
  591. }();
  592.  
  593. var Patch = function () {
  594. function Patch() {
  595. _classCallCheck(this, Patch);
  596.  
  597. this._installed = false;
  598. }
  599.  
  600. _createClass(Patch, [{
  601. key: 'install',
  602. value: function install() {
  603. if (!this._installed) {
  604. this._installed = true;
  605. this._apply();
  606. }
  607. }
  608. }, {
  609. key: '_apply',
  610. value: function _apply() {}
  611. }]);
  612.  
  613. return Patch;
  614. }();
  615.  
  616. var MockAdsPatch = function (_Patch) {
  617. _inherits(MockAdsPatch, _Patch);
  618.  
  619. function MockAdsPatch() {
  620. _classCallCheck(this, MockAdsPatch);
  621.  
  622. return _possibleConstructorReturn(this, (MockAdsPatch.__proto__ || Object.getPrototypeOf(MockAdsPatch)).call(this));
  623. }
  624.  
  625. _createClass(MockAdsPatch, [{
  626. key: '_apply',
  627. value: function _apply() {
  628. var self = this;
  629. Hooker.hookAdService(function (exports) {
  630. exports.default.prototype.requestAdData = function (obj /* , params */) {
  631. var _this5 = this;
  632.  
  633. setTimeout(function () {
  634. if ('frontad' === obj.adtype) {
  635. _this5.success(obj, self._fakeFrontAdData());
  636. } else {
  637. _this5.fail(obj, { code: '404', message: 'error' });
  638. }
  639. }, 0);
  640. };
  641. });
  642. this._hideOppoAds();
  643. }
  644. }, {
  645. key: '_fakeFrontAdData',
  646. value: function _fakeFrontAdData() {
  647. var data = {
  648. VAL: []
  649. };
  650. return data;
  651. }
  652. }, {
  653. key: '_hideOppoAds',
  654. value: function _hideOppoAds() {
  655. GM_addStyle('\n .oppo-ads, .oppinfo {\n display: none !important;\n }\n ');
  656. }
  657. }]);
  658.  
  659. return MockAdsPatch;
  660. }(Patch);
  661.  
  662. var WatermarksPatch = function (_Patch2) {
  663. _inherits(WatermarksPatch, _Patch2);
  664.  
  665. function WatermarksPatch() {
  666. _classCallCheck(this, WatermarksPatch);
  667.  
  668. return _possibleConstructorReturn(this, (WatermarksPatch.__proto__ || Object.getPrototypeOf(WatermarksPatch)).call(this));
  669. }
  670.  
  671. _createClass(WatermarksPatch, [{
  672. key: '_apply',
  673. value: function _apply() {
  674. Hooker.hookLogo(function (exports) {
  675. exports.default.prototype.reset = function () {};
  676. });
  677. }
  678. }]);
  679.  
  680. return WatermarksPatch;
  681. }(Patch);
  682.  
  683. var VipPatch = function (_Patch3) {
  684. _inherits(VipPatch, _Patch3);
  685.  
  686. function VipPatch() {
  687. _classCallCheck(this, VipPatch);
  688.  
  689. return _possibleConstructorReturn(this, (VipPatch.__proto__ || Object.getPrototypeOf(VipPatch)).call(this));
  690. }
  691.  
  692. _createClass(VipPatch, [{
  693. key: '_apply',
  694. value: function _apply() {
  695. Hooker.hookUpsOnComplete(function (res) {
  696. var data = res.data;
  697. data.user = Object.assign(data.user || {}, { vip: true });
  698. data.vip = Object.assign(data.vip || {}, { hd3: true });
  699. });
  700. }
  701. }]);
  702.  
  703. return VipPatch;
  704. }(Patch);
  705.  
  706. var QualityPatch = function (_Patch4) {
  707. _inherits(QualityPatch, _Patch4);
  708.  
  709. function QualityPatch() {
  710. _classCallCheck(this, QualityPatch);
  711.  
  712. return _possibleConstructorReturn(this, (QualityPatch.__proto__ || Object.getPrototypeOf(QualityPatch)).call(this));
  713. }
  714.  
  715. _createClass(QualityPatch, [{
  716. key: '_apply',
  717. value: function _apply() {
  718. this._improveAdaptQuality();
  719. }
  720. }, {
  721. key: '_findBestQuality',
  722. value: function _findBestQuality(qualityList) {
  723. return ['1080p', '720p', '480p', '320p'].find(function (q) {
  724. return qualityList.some(function (v) {
  725. return v === q;
  726. });
  727. });
  728. }
  729. }, {
  730. key: '_improveAdaptQuality',
  731. value: function _improveAdaptQuality() {
  732. var self = this;
  733. Hooker.hookGlobal(function (exports) {
  734. var adaptQuality = exports.default.prototype.adaptQuality;
  735. exports.default.prototype.adaptQuality = function (lang) {
  736. var cfg = this._config;
  737. var quality = cfg.quality;
  738. adaptQuality.apply(this, [lang]);
  739. if (!this.qualityList.includes(quality)) {
  740. cfg.quality = self._findBestQuality(this.qualityList);
  741. }
  742. };
  743. });
  744. }
  745. }]);
  746.  
  747. return QualityPatch;
  748. }(Patch);
  749.  
  750. var DashboardPatch = function (_Patch5) {
  751. _inherits(DashboardPatch, _Patch5);
  752.  
  753. function DashboardPatch() {
  754. _classCallCheck(this, DashboardPatch);
  755.  
  756. return _possibleConstructorReturn(this, (DashboardPatch.__proto__ || Object.getPrototypeOf(DashboardPatch)).call(this));
  757. }
  758.  
  759. _createClass(DashboardPatch, [{
  760. key: '_apply',
  761. value: function _apply() {
  762. this._prepare();
  763. this._patch();
  764. }
  765. }, {
  766. key: '_prepare',
  767. value: function _prepare() {
  768. this._exposeDashboard();
  769. Hooker.hookPreviewLayerBind(function (that) {
  770. that._el.addEventListener('mouseover', function () {
  771. return that.emit('mouseoverpreview');
  772. });
  773. that._el.addEventListener('mouseleave', function () {
  774. return that.emit('mouseleavepreview');
  775. });
  776. });
  777. }
  778. }, {
  779. key: '_findVarName',
  780. value: function _findVarName(code) {
  781. return (/"dashboard"\s*,\s*(\w+)/.exec(code)[1]
  782. );
  783. }
  784. }, {
  785. key: '_exposeDashboard',
  786. value: function _exposeDashboard() {
  787. var _this10 = this;
  788.  
  789. Hooker.hookBase(function (code) {
  790. var varName = _this10._findVarName(code);
  791. return code.replace(/\.exports\s*=\s*(\w+)/, '$&;$1.__Dashboard=' + varName + ';');
  792. }, 'code');
  793. }
  794. }, {
  795. key: '_patch',
  796. value: function _patch() {
  797. Hooker.hookBase(function (exports) {
  798. var proto = exports.__Dashboard.prototype;
  799.  
  800. proto.bindAutoHide = function () {
  801. var _this11 = this;
  802.  
  803. this._args.show = 'function' === typeof this._args.show ? this._args.show : function () {};
  804. this._args.hide = 'function' === typeof this._args.hide ? this._args.show : function () {};
  805.  
  806. this._el.addEventListener('mouseover', function () {
  807. return _this11._mouseover = true;
  808. });
  809. this._el.addEventListener('mouseleave', function () {
  810. return _this11._mouseover = false;
  811. });
  812. this.on('mouseoverpreview', function () {
  813. return _this11._mouseoverpreview = true;
  814. });
  815. this.on('mouseleavepreview', function () {
  816. return _this11._mouseoverpreview = false;
  817. });
  818. this._video.on('play', function () {
  819. if (!_this11._mouseover && !_this11._mouseoverpreview) _this11._hideTimeout = setTimeout(_this11.hide.bind(_this11), _this11._args.autoHide);
  820. });
  821. this._video.on('pause', function () {
  822. _this11._hideTimeout && clearTimeout(_this11._hideTimeout);
  823. _this11.isShow() || _this11.show();
  824. });
  825. this._parent.addEventListener('mousemove', function () {
  826. _this11._hideTimeout && clearTimeout(_this11._hideTimeout);
  827. _this11.isShow() || _this11.show();
  828. if (!_this11._isPaused() && !_this11._mouseover && !_this11._mouseoverpreview) _this11._hideTimeout = setTimeout(_this11.hide.bind(_this11), _this11._args.autoHide);
  829. });
  830. this._parent.addEventListener('mouseleave', function () {
  831. _this11._hideTimeout && clearTimeout(_this11._hideTimeout);
  832. if (!_this11._isPaused()) _this11.hide();
  833. });
  834. };
  835.  
  836. proto._isPaused = function () {
  837. return this._video._videoCore.video.paused;
  838. };
  839.  
  840. proto.isShow = function () {
  841. return this._el.style.display !== 'none';
  842. };
  843.  
  844. proto.show = function () {
  845. this.emit('dashboardshow');
  846. this._parent.style.cursor = '';
  847. this._el.style.display = '';
  848. this._args.show();
  849. };
  850.  
  851. proto.hide = function () {
  852. this.emit('dashboardhide');
  853. this._parent.style.cursor = 'none'; // 隐藏鼠标
  854. this._el.style.display = 'none';
  855. this._args.show();
  856. };
  857. });
  858. }
  859. }]);
  860.  
  861. return DashboardPatch;
  862. }(Patch);
  863.  
  864. var TopAreaPatch = function (_Patch6) {
  865. _inherits(TopAreaPatch, _Patch6);
  866.  
  867. function TopAreaPatch() {
  868. _classCallCheck(this, TopAreaPatch);
  869.  
  870. return _possibleConstructorReturn(this, (TopAreaPatch.__proto__ || Object.getPrototypeOf(TopAreaPatch)).call(this));
  871. }
  872.  
  873. _createClass(TopAreaPatch, [{
  874. key: '_apply',
  875. value: function _apply() {
  876. Hooker.hookTopAreaAddEvent(function (that) {
  877. that.on('webfullscreen', function (isWebFullscreen) {
  878. isWebFullscreen ? that._showHideTop(true) : that._hideHideTop();
  879. });
  880. that.on('dashboardshow', function () {
  881. var playerState = that._video.global.playerState;
  882. if (playerState.fullscreen || playerState.webfullscreen) {
  883. that._showHideTop(true);
  884. }
  885. });
  886. that.on('dashboardhide', function () {
  887. var playerState = that._video.global.playerState;
  888. if (playerState.fullscreen || playerState.webfullscreen) {
  889. that._hideHideTop();
  890. }
  891. });
  892. });
  893. Hooker.hookResetPlayerAfter(function (that) {
  894. // 网页全屏播放上下集重置播放器后显示顶部控件
  895. if (!that.global.playerState.fullscreen) that._player.control.emit('webfullscreen', that.global.playerState.webfullscreen);
  896. });
  897. }
  898. }]);
  899.  
  900. return TopAreaPatch;
  901. }(Patch);
  902.  
  903. var SettingSeriesPatch = function (_Patch7) {
  904. _inherits(SettingSeriesPatch, _Patch7);
  905.  
  906. function SettingSeriesPatch() {
  907. _classCallCheck(this, SettingSeriesPatch);
  908.  
  909. return _possibleConstructorReturn(this, (SettingSeriesPatch.__proto__ || Object.getPrototypeOf(SettingSeriesPatch)).call(this));
  910. }
  911.  
  912. _createClass(SettingSeriesPatch, [{
  913. key: '_apply',
  914. value: function _apply() {
  915. Hooker.hookSettingSeries(function (exports) {
  916. // 网页全屏显示选集
  917. var _addEvent = exports.default.prototype._addEvent;
  918. exports.default.prototype._addEvent = function () {
  919. var _this14 = this;
  920.  
  921. _addEvent.apply(this);
  922. this.on('webfullscreen', function (isWebFullscreen) {
  923. if (isWebFullscreen) {
  924. if (_this14.seriesList.length > 1) _this14._el.style.display = 'inline-block';
  925. } else {
  926. _this14._el.style.display = 'none';
  927. _this14._el.classList.remove('cliced');
  928. _this14.emit('seriesliseLayer', false);
  929. }
  930. });
  931. };
  932. });
  933. }
  934. }]);
  935.  
  936. return SettingSeriesPatch;
  937. }(Patch);
  938.  
  939. var ContinuePlayPatch = function (_Patch8) {
  940. _inherits(ContinuePlayPatch, _Patch8);
  941.  
  942. function ContinuePlayPatch() {
  943. _classCallCheck(this, ContinuePlayPatch);
  944.  
  945. return _possibleConstructorReturn(this, (ContinuePlayPatch.__proto__ || Object.getPrototypeOf(ContinuePlayPatch)).call(this));
  946. }
  947.  
  948. _createClass(ContinuePlayPatch, [{
  949. key: '_apply',
  950. value: function _apply() {
  951. var _this16 = this;
  952.  
  953. Hooker.hookInitPlayerEvent(function (that) {
  954. // 视频播放结束处理
  955. that._player.control.on('ended', that._onEnd.bind(that));
  956. that._player.control.on('ended', function () {
  957. return _this16._onEnd(that);
  958. });
  959. });
  960. }
  961. }, {
  962. key: '_onEnd',
  963. value: function _onEnd(that) {
  964. var config = that.global.config;
  965. var playerState = that.global.playerState;
  966. if (config.continuePlay && config.nextVid && !playerState.fullscreen) {
  967. if (playerState.webfullscreen) {
  968. that.playByVid({ vid: that.global.config.nextVid });
  969. } else {
  970. that.gotoVideo(that.global.config.nextVid);
  971. }
  972. }
  973. }
  974. }]);
  975.  
  976. return ContinuePlayPatch;
  977. }(Patch);
  978.  
  979. var FullscreenPatch = function (_Patch9) {
  980. _inherits(FullscreenPatch, _Patch9);
  981.  
  982. function FullscreenPatch() {
  983. _classCallCheck(this, FullscreenPatch);
  984.  
  985. return _possibleConstructorReturn(this, (FullscreenPatch.__proto__ || Object.getPrototypeOf(FullscreenPatch)).call(this));
  986. }
  987.  
  988. _createClass(FullscreenPatch, [{
  989. key: '_apply',
  990. value: function _apply() {
  991. Object.defineProperty(document, 'fullscreen', {});
  992. }
  993. }]);
  994.  
  995. return FullscreenPatch;
  996. }(Patch);
  997.  
  998. var WebFullscreen = function () {
  999. function WebFullscreen(elem) {
  1000. _classCallCheck(this, WebFullscreen);
  1001.  
  1002. this._elem = elem;
  1003. }
  1004.  
  1005. _createClass(WebFullscreen, [{
  1006. key: 'isWebFullscreen',
  1007. value: function isWebFullscreen() {
  1008. return this._elem.classList.contains('webfullscreen');
  1009. }
  1010. }, {
  1011. key: 'enter',
  1012. value: function enter() {
  1013. this._elem.classList.add('webfullscreen');
  1014. var body = document.body;
  1015. body.style.overflow = 'hidden';
  1016.  
  1017. var parentElement = this._elem.parentElement;
  1018. while (parentElement && parentElement !== body) {
  1019. parentElement.classList.add('z-top');
  1020. parentElement = parentElement.parentElement;
  1021. }
  1022. }
  1023. }, {
  1024. key: 'exit',
  1025. value: function exit() {
  1026. this._elem.classList.remove('webfullscreen');
  1027. var body = document.body;
  1028. body.style.overflow = '';
  1029.  
  1030. var parentElement = this._elem.parentElement;
  1031. while (parentElement && parentElement !== body) {
  1032. parentElement.classList.remove('z-top');
  1033. parentElement = parentElement.parentElement;
  1034. }
  1035. }
  1036. }, {
  1037. key: 'toggle',
  1038. value: function toggle() {
  1039. this.isWebFullscreen() ? this.exit() : this.enter();
  1040. }
  1041. }], [{
  1042. key: 'addStyle',
  1043. value: function addStyle() {
  1044. 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 ');
  1045. }
  1046. }]);
  1047.  
  1048. return WebFullscreen;
  1049. }();
  1050.  
  1051. var ManagePatch = function (_Patch10) {
  1052. _inherits(ManagePatch, _Patch10);
  1053.  
  1054. function ManagePatch() {
  1055. _classCallCheck(this, ManagePatch);
  1056.  
  1057. return _possibleConstructorReturn(this, (ManagePatch.__proto__ || Object.getPrototypeOf(ManagePatch)).call(this));
  1058. }
  1059.  
  1060. _createClass(ManagePatch, [{
  1061. key: '_apply',
  1062. value: function _apply() {
  1063. this._prepare();
  1064. this._hookManage();
  1065. }
  1066. }, {
  1067. key: '_prepare',
  1068. value: function _prepare() {
  1069. this._customTip();
  1070. this._disablePlayAfterSeek();
  1071. this._addPrevInfo();
  1072. this._playAfterPlayerReset();
  1073. this._keepPlaybackRate();
  1074. this._playbackRatePersistence();
  1075. new ContinuePlayPatch().install();
  1076. new FullscreenPatch().install();
  1077. }
  1078. }, {
  1079. key: '_customTip',
  1080. value: function _customTip() {
  1081. Hooker.hookTips(function (exports) {
  1082. var showHintTips = exports.default.prototype.showHintTips;
  1083. exports.default.prototype.showHintTips = function (code, info) {
  1084. if (info.msg) {
  1085. this._hintLayer.setHintShow(info.msg);
  1086. } else {
  1087. showHintTips.apply(this, [code, info]);
  1088. }
  1089. };
  1090. });
  1091. }
  1092. }, {
  1093. key: '_disablePlayAfterSeek',
  1094. value: function _disablePlayAfterSeek() {
  1095. // SingleVideoControl seek 后不自动播放
  1096. Hooker.hookBase(function (exports) {
  1097. var _setCurrentTime = exports.SingleVideoControl.prototype._setCurrentTime;
  1098. exports.SingleVideoControl.prototype._setCurrentTime = function (time) {
  1099. var play = this.video.play;
  1100. this.video.play = function () {};
  1101. _setCurrentTime.apply(this, [time]);
  1102. this.video.play = play;
  1103. };
  1104. });
  1105. }
  1106. }, {
  1107. key: '_keepPlaybackRate',
  1108. value: function _keepPlaybackRate() {
  1109. Hooker.hookBase(function (exports) {
  1110. var proto = exports.MultiVideoControl.prototype;
  1111. var _setVideo = proto._setVideo;
  1112. proto._setVideo = function () {
  1113. var rate = this.video.playbackRate;
  1114.  
  1115. for (var _len9 = arguments.length, args = Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
  1116. args[_key9] = arguments[_key9];
  1117. }
  1118.  
  1119. _setVideo.apply(this, args);
  1120. this.video.playbackRate = rate;
  1121. };
  1122. });
  1123. }
  1124. }, {
  1125. key: '_playbackRatePersistence',
  1126. value: function _playbackRatePersistence() {
  1127. var util = void 0;
  1128. Hooker.hookUtil(function (exports) {
  1129. return util = exports;
  1130. });
  1131. Hooker.hookSettingsIcon(function (exports) {
  1132. var proto = exports.default.prototype;
  1133. var setDataUI = proto.setDataUI;
  1134. proto.setDataUI = function (data) {
  1135. var _this19 = this;
  1136.  
  1137. setDataUI.apply(this, [data]);
  1138. this._video.global.playerState = { playbackRate: data.playbackRate || 1 };
  1139. this.on('playbackratechange', function (rate) {
  1140. _this19.data.playbackRate = rate;
  1141. util.setLocalData('YK_PSL_SETTINGS', _this19.data);
  1142. });
  1143. };
  1144. });
  1145. }
  1146. }, {
  1147. key: '_addPrevInfo',
  1148. value: function _addPrevInfo() {
  1149. Hooker.hookGlobalDeal(function (that) {
  1150. if (that.ups && that.ups.videoData && that.ups.programList && that.ups.programList.videoList) {
  1151. var list = that.ups.programList.videoList;
  1152. var currVid = that.ups.videoData.id;
  1153. var currIdx = list.findIndex(function (item) {
  1154. return parseInt(item.vid) === currVid;
  1155. });
  1156. if (currIdx > 0) {
  1157. var prevVideo = list[currIdx - 1];
  1158. that.ups.programList.prevVideo = prevVideo;
  1159. prevVideo && (that._config.prevVid = prevVideo.encodevid);
  1160. }
  1161. }
  1162. });
  1163. }
  1164. }, {
  1165. key: '_playAfterPlayerReset',
  1166. value: function _playAfterPlayerReset() {
  1167. Hooker.hookResetPlayerAfter(function (that) {
  1168. if (that.global.playerState.state === 'playerreset') that.play();
  1169. });
  1170. }
  1171. }, {
  1172. key: '_hookManage',
  1173. value: function _hookManage() {
  1174. Hooker.hookManage(this._hookManageCallback.bind(this));
  1175. }
  1176. }, {
  1177. key: '_hookManageCallback',
  1178. value: function _hookManageCallback(exports) {
  1179. var proto = exports.default.prototype;
  1180.  
  1181. var _init = proto._init;
  1182. proto._init = function () {
  1183. _init.apply(this);
  1184. WebFullscreen.addStyle();
  1185. this._webfullscreen = new WebFullscreen(this.container);
  1186. };
  1187.  
  1188. proto._showTip = function (msg) {
  1189. this._emitter.emit('player.showinfo', { type: 'hint', msg: msg });
  1190. };
  1191.  
  1192. proto.play = function () {
  1193. this._player && this._player.control.play();
  1194. this._showTip('播放');
  1195. };
  1196.  
  1197. proto._pause = proto.pause;
  1198. proto.pause = function () {
  1199. this._pause();
  1200. this._showTip('暂停');
  1201. };
  1202.  
  1203. proto.adjustVolume = function (value) {
  1204. var volume = this.global.playerState.volume + value;
  1205. volume = Math.max(0, Math.min(1, volume.toFixed(2)));
  1206. this._player.control.setVolume(volume);
  1207. if (volume === 0) {
  1208. this._emitter.emit('player.showinfo', { type: 'hint', code: 'H0003', volume: volume + '%' });
  1209. }
  1210. };
  1211.  
  1212. proto.toggleMute = function () {
  1213. if (this.global.playerState.muted) this._showTip('取消静音');
  1214. this.setMuted(!this.global.playerState.muted);
  1215. };
  1216.  
  1217. proto.stepSeek = function (stepTime) {
  1218. var duration = this._player.control.getDuration();
  1219. var currentTime = this.global.currentTime;
  1220. var seekTime = Math.max(0, Math.min(duration, currentTime + stepTime));
  1221. this.seek(seekTime);
  1222.  
  1223. var msg = void 0;
  1224. if (Math.abs(stepTime) < 60) {
  1225. msg = stepTime > 0 ? '\u6B65\u8FDB\uFF1A' + stepTime + '\u79D2' : '\u6B65\u9000\uFF1A' + Math.abs(stepTime) + '\u79D2';
  1226. } else {
  1227. msg = stepTime > 0 ? '\u6B65\u8FDB\uFF1A' + stepTime / 60 + '\u5206\u949F' : '\u6B65\u9000\uFF1A' + Math.abs(stepTime) / 60 + '\u5206\u949F';
  1228. }
  1229. this._showTip(msg);
  1230. };
  1231.  
  1232. proto.rangeSeek = function (range) {
  1233. var duration = this._player.control.getDuration();
  1234. var seekTime = Math.max(0, Math.min(duration, duration * range));
  1235. this.seek(seekTime);
  1236. this._showTip('定位:' + (range * 100).toFixed(0) + '%');
  1237. };
  1238.  
  1239. proto.isFullscreen = function () {
  1240. return this.global.playerState.fullscreen;
  1241. };
  1242.  
  1243. proto.toggleFullscreen = function () {
  1244. if (this.isFullscreen()) {
  1245. this.exitFullscreen();
  1246. } else {
  1247. this.fullScreen();
  1248. }
  1249. };
  1250.  
  1251. proto.isWebFullscreen = function () {
  1252. return this._webfullscreen.isWebFullscreen();
  1253. };
  1254.  
  1255. proto.enterWebFullscreen = function () {
  1256. this._webfullscreen.enter();
  1257. this.global.playerState = { webfullscreen: true };
  1258. this._player.control.emit('webfullscreen', true);
  1259. };
  1260.  
  1261. proto.exitWebFullscreen = function () {
  1262. this._webfullscreen.exit();
  1263. this.global.playerState = { webfullscreen: false };
  1264. this._player.control.emit('webfullscreen', false);
  1265. };
  1266.  
  1267. proto.toggleWebFullscreen = function () {
  1268. this.isWebFullscreen() ? this.exitWebFullscreen() : this.enterWebFullscreen();
  1269. };
  1270.  
  1271. proto.setRate = function (rate) {
  1272. var videoCore = this._player.control._videoCore;
  1273. var video = videoCore.video;
  1274. if (this._player.config.controlType === 'multi') {
  1275. videoCore._videoElments.forEach(function (v) {
  1276. return v.playbackRate = rate;
  1277. });
  1278. } else {
  1279. video.playbackRate = rate;
  1280. }
  1281. };
  1282.  
  1283. proto.adjustPlaybackRate = function (value) {
  1284. var video = this._player.control._videoCore.video;
  1285. var rate = Math.max(0.2, Math.min(5, parseFloat((video.playbackRate + value).toFixed(1))));
  1286. this.setRate(rate);
  1287. this.global.playerState = { playbackRate: rate };
  1288. this._player.control.emit('playbackratechange', rate);
  1289. this._showTip('\u64AD\u653E\u901F\u7387\uFF1A' + rate);
  1290. };
  1291.  
  1292. proto.turnPlaybackRate = function () {
  1293. var video = this._player.control._videoCore.video;
  1294. var rate = video.playbackRate !== 1 ? 1 : this.global.playerState.playbackRate;
  1295. this.setRate(rate);
  1296. this._showTip('\u64AD\u653E\u901F\u7387\uFF1A' + rate);
  1297. };
  1298.  
  1299. proto.getFps = function () {
  1300. return 25; // 标清fps为15,标清以上fps为25。
  1301. };
  1302.  
  1303. proto.prevFrame = function () {
  1304. var state = this.global.playerState.state;
  1305. if (state === 'playing') this.pause();
  1306. var duration = this._player.control.getDuration();
  1307. var currentTime = this.global.currentTime;
  1308. var seekTime = Math.max(0, Math.min(duration, currentTime - 1 / this.getFps()));
  1309. this.seek(seekTime);
  1310. this._showTip('上一帧');
  1311. };
  1312.  
  1313. proto.nextFrame = function () {
  1314. var state = this.global.playerState.state;
  1315. if (state === 'playing') this.pause();
  1316. var duration = this._player.control.getDuration();
  1317. var currentTime = this.global.currentTime;
  1318. var seekTime = Math.max(0, Math.min(duration, currentTime + 1 / this.getFps()));
  1319. this.seek(seekTime);
  1320. this._showTip('下一帧');
  1321. };
  1322.  
  1323. proto.playPrev = function () {
  1324. var prevVid = this.global.config.prevVid;
  1325. if (prevVid) {
  1326. if (this.isFullscreen() || this.isWebFullscreen()) {
  1327. this.playByVid({ vid: prevVid });
  1328. } else {
  1329. this.gotoVideo(prevVid);
  1330. }
  1331. this._showTip('播放上一集');
  1332. } else {
  1333. this._showTip('没有上一集哦');
  1334. }
  1335. };
  1336.  
  1337. var playNext = proto.playNext;
  1338. proto.playNext = function (data) {
  1339. if (data) return playNext.apply(this, [data]);
  1340. var nextVid = this.global.config.nextVid;
  1341. if (nextVid) {
  1342. if (this.isFullscreen() || this.isWebFullscreen()) {
  1343. this.playByVid({ vid: nextVid });
  1344. } else {
  1345. this.gotoVideo(nextVid);
  1346. }
  1347. this._showTip('播放下一集');
  1348. } else {
  1349. this._showTip('没有下一集哦');
  1350. }
  1351. };
  1352.  
  1353. proto.gotoVideo = function (vid) {
  1354. location.href = '//v.youku.com/v_show/id_' + vid + '.html';
  1355. };
  1356. }
  1357. }]);
  1358.  
  1359. return ManagePatch;
  1360. }(Patch);
  1361.  
  1362. var managePatch = new ManagePatch();
  1363.  
  1364. var KeyShortcutsPatch = function (_Patch11) {
  1365. _inherits(KeyShortcutsPatch, _Patch11);
  1366.  
  1367. function KeyShortcutsPatch() {
  1368. _classCallCheck(this, KeyShortcutsPatch);
  1369.  
  1370. return _possibleConstructorReturn(this, (KeyShortcutsPatch.__proto__ || Object.getPrototypeOf(KeyShortcutsPatch)).call(this));
  1371. }
  1372.  
  1373. _createClass(KeyShortcutsPatch, [{
  1374. key: '_apply',
  1375. value: function _apply() {
  1376. this._prepare();
  1377. this._addListener();
  1378. }
  1379. }, {
  1380. key: '_prepare',
  1381. value: function _prepare() {
  1382. managePatch.install();
  1383. this._obtainPlayer();
  1384. }
  1385. }, {
  1386. key: '_obtainPlayer',
  1387. value: function _obtainPlayer() {
  1388. var self = this;
  1389. Hooker.hookKeyShortcuts(function (exports) {
  1390. exports.default.prototype.registerEvents = function () {
  1391. self._player = this._player;
  1392. };
  1393. });
  1394. }
  1395. }, {
  1396. key: '_addListener',
  1397. value: function _addListener() {
  1398. document.addEventListener('keydown', this._handler.bind(this));
  1399. }
  1400. }, {
  1401. key: '_handler',
  1402. value: function _handler(event) {
  1403. if (event.target.nodeName !== 'BODY') return;
  1404.  
  1405. switch (event.keyCode) {
  1406. case 32:
  1407. // Spacebar
  1408. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1409. var state = this._player.global.playerState.state;
  1410. if (state === 'paused') {
  1411. this._player.play();
  1412. } else if (state === 'ended') {
  1413. this._player.replay();
  1414. } else {
  1415. this._player.pause();
  1416. }
  1417. } else {
  1418. return;
  1419. }
  1420. break;
  1421. case 39: // → Arrow Right
  1422. case 37:
  1423. {
  1424. // ← Arrow Left
  1425. var stepTime = void 0;
  1426. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1427. stepTime = 39 === event.keyCode ? 5 : -5;
  1428. } else if (event.ctrlKey && !event.shiftKey && !event.altKey) {
  1429. stepTime = 39 === event.keyCode ? 30 : -30;
  1430. } else if (!event.ctrlKey && event.shiftKey && !event.altKey) {
  1431. stepTime = 39 === event.keyCode ? 60 : -60;
  1432. } else if (event.ctrlKey && !event.shiftKey && event.altKey) {
  1433. stepTime = 39 === event.keyCode ? 3e2 : -3e2; // 5分钟
  1434. } else {
  1435. return;
  1436. }
  1437. this._player.stepSeek(stepTime);
  1438. break;
  1439. }
  1440. case 38: // ↑ Arrow Up
  1441. case 40:
  1442. // ↓ Arrow Down
  1443. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1444. this._player.adjustVolume(38 === event.keyCode ? 0.05 : -0.05);
  1445. } else {
  1446. return;
  1447. }
  1448. break;
  1449. case 77:
  1450. // M
  1451. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1452. this._player.toggleMute();
  1453. } else {
  1454. return;
  1455. }
  1456. break;
  1457. case 13:
  1458. // Enter
  1459. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1460. this._player.toggleFullscreen();
  1461. } else if (event.ctrlKey && !event.shiftKey && !event.altKey) {
  1462. this._player.toggleWebFullscreen();
  1463. } else {
  1464. return;
  1465. }
  1466. break;
  1467. case 67: // C
  1468. case 88:
  1469. // X
  1470. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1471. this._player.adjustPlaybackRate(67 === event.keyCode ? 0.1 : -0.1);
  1472. } else {
  1473. return;
  1474. }
  1475. break;
  1476. case 90:
  1477. // Z
  1478. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1479. this._player.turnPlaybackRate();
  1480. } else {
  1481. return;
  1482. }
  1483. break;
  1484. case 68: // D
  1485. case 70:
  1486. // F
  1487. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1488. if (event.keyCode === 68) {
  1489. this._player.prevFrame();
  1490. } else {
  1491. this._player.nextFrame();
  1492. }
  1493. } else {
  1494. return;
  1495. }
  1496. break;
  1497. case 80: // P
  1498. case 78:
  1499. // N
  1500. if (!event.ctrlKey && event.shiftKey && !event.altKey) {
  1501. if (event.keyCode === 78) {
  1502. this._player.playNext();
  1503. } else {
  1504. this._player.playPrev();
  1505. }
  1506. } else {
  1507. return;
  1508. }
  1509. break;
  1510. case 27:
  1511. // ESC
  1512. if (!event.ctrlKey && !event.shiftKey && !event.altKey) this._player.isWebFullscreen() && this._player.exitWebFullscreen();
  1513. return;
  1514. default:
  1515. if (event.keyCode >= 48 && event.keyCode <= 57) {
  1516. // 0 ~ 9
  1517. if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
  1518. this._player.rangeSeek((event.keyCode - 48) * 0.1);
  1519. } else {
  1520. return;
  1521. }
  1522. } else {
  1523. return;
  1524. }
  1525. }
  1526.  
  1527. event.preventDefault();
  1528. event.stopPropagation();
  1529. }
  1530. }]);
  1531.  
  1532. return KeyShortcutsPatch;
  1533. }(Patch);
  1534.  
  1535. var MouseShortcutsPatch = function (_Patch12) {
  1536. _inherits(MouseShortcutsPatch, _Patch12);
  1537.  
  1538. function MouseShortcutsPatch() {
  1539. _classCallCheck(this, MouseShortcutsPatch);
  1540.  
  1541. return _possibleConstructorReturn(this, (MouseShortcutsPatch.__proto__ || Object.getPrototypeOf(MouseShortcutsPatch)).call(this));
  1542. }
  1543.  
  1544. _createClass(MouseShortcutsPatch, [{
  1545. key: '_apply',
  1546. value: function _apply() {
  1547. this._prepare();
  1548. this._initEvents();
  1549. }
  1550. }, {
  1551. key: '_prepare',
  1552. value: function _prepare() {
  1553. managePatch.install();
  1554. }
  1555. }, {
  1556. key: '_initEvents',
  1557. value: function _initEvents() {
  1558. Hooker.hookTriggerLayer(function (exports) {
  1559. var proto = exports.default.prototype;
  1560. var initEvents = proto.initEvents;
  1561. proto.initEvents = function () {
  1562. var _this22 = this;
  1563.  
  1564. var player = this._video.ykplayer;
  1565.  
  1566. this._el.addEventListener('dblclick', function (event) {
  1567. if (event.ctrlKey) {
  1568. player.toggleWebFullscreen();
  1569. event.stopImmediatePropagation();
  1570. _this22._clickTimer.clear();
  1571. }
  1572. });
  1573. this._el.addEventListener('wheel', function (event) {
  1574. if (player.isFullscreen() || player.isWebFullscreen()) {
  1575. var delta = event.wheelDelta || event.detail || event.deltaY && -event.deltaY;
  1576. player.adjustVolume(delta > 0 ? 0.05 : -0.05);
  1577. }
  1578. });
  1579.  
  1580. initEvents.apply(this);
  1581. };
  1582. });
  1583. }
  1584. }]);
  1585.  
  1586. return MouseShortcutsPatch;
  1587. }(Patch);
  1588.  
  1589. var ShortcutsPatch = function (_Patch13) {
  1590. _inherits(ShortcutsPatch, _Patch13);
  1591.  
  1592. function ShortcutsPatch() {
  1593. _classCallCheck(this, ShortcutsPatch);
  1594.  
  1595. return _possibleConstructorReturn(this, (ShortcutsPatch.__proto__ || Object.getPrototypeOf(ShortcutsPatch)).call(this));
  1596. }
  1597.  
  1598. _createClass(ShortcutsPatch, [{
  1599. key: '_apply',
  1600. value: function _apply() {
  1601. new KeyShortcutsPatch().install();
  1602. Logger.log('添加键盘快捷键');
  1603. new MouseShortcutsPatch().install();
  1604. Logger.log('添加鼠标快捷键');
  1605. }
  1606. }]);
  1607.  
  1608. return ShortcutsPatch;
  1609. }(Patch);
  1610.  
  1611. var TVBH5Patch = function (_Patch14) {
  1612. _inherits(TVBH5Patch, _Patch14);
  1613.  
  1614. function TVBH5Patch() {
  1615. _classCallCheck(this, TVBH5Patch);
  1616.  
  1617. return _possibleConstructorReturn(this, (TVBH5Patch.__proto__ || Object.getPrototypeOf(TVBH5Patch)).call(this));
  1618. }
  1619.  
  1620. _createClass(TVBH5Patch, [{
  1621. key: '_apply',
  1622. value: function _apply() {
  1623. Hooker.hookGlobalVariable('PageConfig', function (cfg) {
  1624. Object.defineProperty(cfg, 'production', { get: function get() {
  1625. return '';
  1626. } });
  1627. });
  1628. Logger.log('H5-player has been enabled at TVB\'s videos.');
  1629. }
  1630. }]);
  1631.  
  1632. return TVBH5Patch;
  1633. }(Patch);
  1634.  
  1635. // class H5Patch extends Patch {
  1636.  
  1637. // constructor() {
  1638. // super();
  1639. // }
  1640.  
  1641. // _apply() {
  1642. // Hooker.hookDefine('page/find/play/player/load', this._forceH5.bind(this));
  1643. // }
  1644.  
  1645. // _forceH5(code) {
  1646. // return code.replace(/(if\s*\().*?(\)\s*\{)/, '$1true$2').replace('window.sessionStorage', 'null');
  1647. // }
  1648.  
  1649. // }
  1650.  
  1651. function ensureH5PlayerEnabled() {
  1652. // (new H5Patch()).install();
  1653. Object.defineProperty(unsafeWindow.navigator, 'plugins', { get: function get() {
  1654. return {};
  1655. } });
  1656. Logger.log('启用html5播放器');
  1657. }
  1658.  
  1659. function mockAds() {
  1660. new MockAdsPatch().install();
  1661. Logger.log('和谐广告');
  1662. }
  1663.  
  1664. function invalidateWatermarks() {
  1665. new WatermarksPatch().install();
  1666. Logger.log('和谐水印');
  1667. }
  1668.  
  1669. function invalidateQualityLimitation() {
  1670. new VipPatch().install();
  1671. Logger.log('解除会员画质限制');
  1672. }
  1673.  
  1674. function improveQualityLogic() {
  1675. new QualityPatch().install();
  1676. Logger.log('改善画质逻辑');
  1677. }
  1678.  
  1679. function improveAutoHide() {
  1680. new DashboardPatch().install();
  1681. new TopAreaPatch().install();
  1682. new SettingSeriesPatch().install();
  1683. Logger.log('改善控件与光标自动隐藏');
  1684. }
  1685.  
  1686. function improveShortcuts() {
  1687. new ShortcutsPatch().install();
  1688. }
  1689.  
  1690. function enableH5ForTVB() {
  1691. new TVBH5Patch().install();
  1692. }
  1693.  
  1694. //=============================================================================
  1695.  
  1696. ensureH5PlayerEnabled();
  1697. mockAds();
  1698. invalidateWatermarks();
  1699. invalidateQualityLimitation();
  1700. improveQualityLogic();
  1701. improveAutoHide();
  1702. improveShortcuts();
  1703. enableH5ForTVB();
  1704. })();