HTML5 on CCTV

Replace Flash Player with HTML5 Player on tv.cctv.com

目前為 2020-03-14 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name HTML5 on CCTV
  3. // @namespace https://github.com/sffxzzp
  4. // @version 0.06
  5. // @description Replace Flash Player with HTML5 Player on tv.cctv.com
  6. // @author sffxzzp
  7. // @include /^https?://tv.cctv.com/\d*/\d*/\d*/VIDE.*.shtml*/
  8. // @require https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.js
  9. // @require https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js
  10. // @icon https://tv.cctv.com/favicon.ico
  11. // @connect vdn.apps.cntv.cn
  12. // @connect hls.cntv.baishancdnx.cn
  13. // @grant GM_xmlhttpRequest
  14. // @grant GM_addStyle
  15. // @grant unsafeWindow
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. var util = (function () {
  20. function util() {}
  21. util.xhr = function (xhrData) {
  22. return new Promise(function(resolve, reject) {
  23. if (!xhrData.xhr) {
  24. GM_xmlhttpRequest({
  25. method: xhrData.method || "get",
  26. url: xhrData.url,
  27. data: xhrData.data,
  28. headers: xhrData.headers || {},
  29. responseType: xhrData.type || "",
  30. timeout: 3e4,
  31. onload: function onload(res) {
  32. return resolve({ response: res, body: res.response });
  33. },
  34. onerror: reject,
  35. ontimeout: reject
  36. });
  37. } else {
  38. var xhr = new XMLHttpRequest();
  39. xhr.open(xhrData.method || "get", xhrData.url, true);
  40. if (xhrData.method === "post") {xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded; charset=utf-8");}
  41. if (xhrData.cookie) {xhr.withCredentials = true;}
  42. xhr.responseType = xhrData.responseType || "";
  43. xhr.timeout = 3e4;
  44. if (xhrData.headers) {for (var k in xhrData.headers) {xhr.setRequestHeader(k, xhrData.headers[k]);}}
  45. xhr.onload = function(ev) {
  46. var evt = ev.target;
  47. resolve({ response: evt, body: evt.response });
  48. };
  49. xhr.onerror = reject;
  50. xhr.ontimeout = reject;
  51. xhr.send(xhrData.data);
  52. }
  53. });
  54. };
  55. util.createElement = function (data) {
  56. var node;
  57. if (data.node) {
  58. node = document.createElement(data.node);
  59. if (data.content) {this.setElement({node: node, content: data.content});}
  60. if (data.html) {node.innerHTML = data.html;}
  61. }
  62. return node;
  63. };
  64. util.setElement = function (data) {
  65. if (data.node) {
  66. for (let name in data.content) {data.node.setAttribute(name, data.content[name]);}
  67. if (data.html!=undefined) {data.node.innerHTML = data.html;}
  68. }
  69. };
  70. return util;
  71. })();
  72. var h5onCCTV = (function () {
  73. function h5onCCTV() {};
  74. h5onCCTV.prototype.addPlayer = function (m3u8) {
  75. var h5css = util.createElement({node: 'link', content: {rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.css'}});
  76. document.head.appendChild(h5css);
  77. var container = document.querySelector('.video_left');
  78. GM_addStyle('.gwA151201_ind01, .retrieve {z-index: 0 !important;}');
  79. util.setElement({node: container, content: {style: 'height: 100%'}, html: '<div id="dplayer" style="width: 100%; height: 100%;"></div>'});
  80. var dp = new DPlayer({
  81. container: container.children[0],
  82. video: {
  83. quality: m3u8,
  84. defaultQuality: m3u8.length-1
  85. }
  86. });
  87. var curTime = localStorage.getItem(unsafeWindow.guid);
  88. if (curTime) {
  89. dp.seek(curTime);
  90. dp.notice('已跳转到上次观看进度 '+Math.floor(curTime)+' 秒', 2000);
  91. }
  92. dp.on('timeupdate', function () {
  93. if (dp.video.duration-dp.video.currentTime > 30) {
  94. localStorage.setItem(unsafeWindow.guid, dp.video.currentTime);
  95. }
  96. else {
  97. localStorage.removeItem(unsafeWindow.guid);
  98. }
  99. });
  100. }
  101. h5onCCTV.prototype.run = function () {
  102. var _this = this;
  103. util.xhr({
  104. url: `https://vdn.apps.cntv.cn/api/getHttpVideoInfo.do?pid=${unsafeWindow.guid}`,
  105. type: 'json'
  106. }).then(function (res) {
  107. util.xhr({
  108. url: res.body.hls_url
  109. }).then(function (res) {
  110. var vlist = res.body.split('\n');
  111. var m3u8s = [];
  112. vlist.forEach(function (v) {
  113. if (v.indexOf('m3u8')>-1) {
  114. m3u8s.push('https://hls.cntv.baishancdnx.cn'+v);
  115. }
  116. });
  117. m3u8s.reverse();
  118. var m3u8 = [{name: '超清', url: '', type: 'hls'}, {name: '高清', url: '', type: 'hls'}, {name: '标清', url: '', type: 'hls'}, {name: '流畅', url: '', type: 'hls'}];
  119. for (let i=0;i<m3u8s.length;i++) {
  120. m3u8[i].url = m3u8s[i];
  121. }
  122. m3u8.reverse();
  123. _this.addPlayer(m3u8);
  124. });
  125. });
  126. };
  127. return h5onCCTV;
  128. })();
  129. var program = new h5onCCTV();
  130. program.run();
  131. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址