iqiyi player switch

iqiyi player switch between flash and html5

目前为 2017-03-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name iqiyi player switch
  3. // @namespace undefined
  4. // @version 0.0.1
  5. // @description iqiyi player switch between flash and html5
  6. // @author gooyie
  7. //
  8. // @include *://www.iqiyi.com/v_*
  9. // @include *://www.iqiyi.com/dongman/*/*
  10. // @grant GM_registerMenuCommand
  11. // @grant GM_unregisterMenuCommand
  12. // @grant GM_log
  13. // @run-at document-start
  14.  
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. // ua
  21. const UA_CHROME = 'chrome';
  22. const UA_SAFARY = 'safari';
  23. // platform
  24. const PLAFORM_MAC = 'mac';
  25.  
  26. const PLAYER_TYPE = {
  27. Html5VOD: "h5_VOD",
  28. FlashVOD: "flash_VOD"
  29. };
  30.  
  31. class DocCookies {
  32. static get(key) {
  33. let value;
  34. if (new RegExp('^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+$').test(key)) {
  35. let re = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
  36. let rs = re.exec(document.cookie);
  37. value = rs ? rs[2] : '';
  38. }
  39. return value ? decodeURIComponent(value) : '';
  40. }
  41.  
  42. static set(k, v, o={}) {
  43. let n = o.expires;
  44. if ("number" == typeof o.expires) {
  45. n = new Date();
  46. n.setTime(n.getTime() + o.expires);
  47. }
  48. let key = k;
  49. let value = encodeURIComponent(v);
  50. let path = o.path ? '; path=' + o.path : '';
  51. let expires = n ? '; expires=' + n.toGMTString() : '';
  52. let domain = o.domain ? '; domain=' + o.domain : '';
  53. document.cookie = `${key}=${value}${path}${expires}${domain}`;
  54. }
  55.  
  56. static remove(k, o={}) {
  57. o.expires = new Date(0);
  58. this.set(k, '', o);
  59. }
  60. }
  61.  
  62. class Switcher {
  63. static switch() {
  64. let currType = DocCookies.get('player_forcedType');
  65. let toType = currType === PLAYER_TYPE.Html5VOD ? PLAYER_TYPE.FlashVOD : PLAYER_TYPE.Html5VOD;
  66.  
  67. GM_log('switching to %s ...', toType);
  68. if (!confirm(`刷新页面切换到${toType}播放器?`)) return;
  69.  
  70. if (toType === PLAYER_TYPE.Html5VOD && !this._canPlayback()) {
  71. alert('╮(╯▽╰)╭ 你的浏览器播放不了html5视频~~~~');
  72. return;
  73. }
  74. // cookie 有效时间为一年
  75. let date = new Date();
  76. date.setFullYear(date.getFullYear() + 1);
  77.  
  78. DocCookies.set('player_forcedType', toType, {expires: date});
  79. document.location.reload();
  80. }
  81.  
  82. static _canPlayback() {
  83. let v = document.createElement('video');
  84. return !!(
  85. v.canPlayType('audio/mp4; codecs="mp4a.40.2"') &&
  86. v.canPlayType('video/mp4; codecs="avc1.640029"') &&
  87. v.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"')
  88. );
  89. }
  90.  
  91. }
  92. // TODO: polyfill使不同的浏览器都能使用vms
  93. class Mocker {
  94. static mock() {
  95. let currType = DocCookies.get('player_forcedType');
  96. if (currType !== PLAYER_TYPE.Html5VOD) return;
  97.  
  98. if (this._canUseVms()) {
  99. // 使用 vms
  100. this._fakeMacPlatform();
  101. this._fakeChrome();
  102. } else if (this._canUseM3u8()) {
  103. // 使用 tmts m3u8
  104. this._fakeMacPlatform();
  105. this._fakeSafary();
  106. }
  107. // 默认使用 tmts mp4 ...
  108. }
  109.  
  110. static _fakeMacPlatform() {
  111. Object.defineProperty(navigator, 'platform', {get: () => PLAFORM_MAC});
  112. }
  113.  
  114. static _fakeSafary() {
  115. Object.defineProperty(navigator, 'userAgent', {get: () => UA_SAFARY});
  116. }
  117.  
  118. static _fakeChrome() {
  119. Object.defineProperty(navigator, 'userAgent', {get: () => UA_CHROME});
  120. }
  121.  
  122. static _canUseVms() {
  123. return !!(
  124. window.MediaSource && window.URL && window.WebSocket && window.ReadableStream &&
  125. (window.RTCSessionDescription || window.webkitRTCSessionDescription) &&
  126. (window.RTCPeerConnection || window.webkitRTCPeerConnection) &&
  127. (window.RTCIceCandidate || window.webkitRTCIceCandidate)
  128. );
  129. }
  130.  
  131. static _canUseM3u8() {
  132. let v = document.createElement('video');
  133. return !!(
  134. v.canPlayType('application/x-mpegurl') &&
  135. v.canPlayType('application/vnd.apple.mpegurl')
  136. );
  137. }
  138. }
  139.  
  140.  
  141. GM_registerMenuCommand('Switch Player', () => Switcher.switch(), null);
  142.  
  143. Mocker.mock();
  144.  
  145. })();