動畫瘋工具箱

取得動畫的 m3u8 網址,下載彈幕為 json,去除擋廣告的警告訊息

安装此脚本?
作者推荐脚本

您可能也喜欢跳過動畫瘋廣告

安装此脚本
  1. // ==UserScript==
  2. // @name 動畫瘋工具箱
  3. // @namespace https://blog.maple3142.net/
  4. // @description 取得動畫的 m3u8 網址,下載彈幕為 json,去除擋廣告的警告訊息
  5. // @version 0.9.8
  6. // @author maple3142
  7. // @match https://ani.gamer.com.tw/animeVideo.php?sn=*
  8. // @connect api.gamer.com.tw
  9. // @require https://cdn.jsdelivr.net/npm/m3u8-parser@4.2.0/dist/m3u8-parser.min.js
  10. // @require https://unpkg.com/xfetch-js@0.3.4/xfetch.min.js
  11. // @require https://unpkg.com/gmxhr-fetch@0.1.0/gmxhr-fetch.min.js
  12. // @grant GM_xmlhttpRequest
  13. // @grant unsafeWindow
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // ==/UserScript==
  17.  
  18. (function () {
  19. 'use strict';
  20.  
  21. var $ = jQuery;
  22. function hookSetter(obj, prop, cb) {
  23. var value,
  24. canceled = false;
  25. Object.defineProperty(obj, prop, {
  26. set: function set(v) {
  27. value = v;
  28. if (!canceled) cb(v);
  29. },
  30. get: function get() {
  31. return value;
  32. }
  33. });
  34. return function () {
  35. return canceled = true;
  36. };
  37. }
  38. function cvtM3U8_to_playlist(baseurl) {
  39. return function (m3u8) {
  40. var parser = new m3u8Parser.Parser();
  41. parser.push(m3u8);
  42. parser.end();
  43. var pls = parser.manifest.playlists.map(function (pl) {
  44. return {
  45. url: new URL(pl.uri, baseurl).href,
  46. res: pl.attributes.RESOLUTION
  47. };
  48. });
  49. return pls;
  50. };
  51. }
  52. function triggerDownload(url, fname) {
  53. var a = document.createElement('a');
  54. a.href = url;
  55. a.download = fname;
  56. document.body.appendChild(a);
  57. a.click();
  58. a.remove();
  59. }
  60. function saveTextAsFile(text, fname) {
  61. var blob = new Blob([text]);
  62. var url = URL.createObjectURL(blob);
  63. triggerDownload(url, fname);
  64. URL.revokeObjectURL(url);
  65. }
  66. var gxf = xf.extend({
  67. fetch: gmfetch
  68. });
  69. function getTodayAnswer() {
  70. return gxf.get('https://api.gamer.com.tw/mobile_app/bahamut/v1/home.php', {
  71. qs: {
  72. owner: 'blackXblue',
  73. page: 1
  74. }
  75. }).json(function (_ref) {
  76. var creation = _ref.creation;
  77. return creation.find(function (x) {
  78. return x.title.includes('動漫通');
  79. }).sn;
  80. }).then(function (sn) {
  81. return gxf.get('https://api.gamer.com.tw/mobile_app/bahamut/v1/home_creation_detail.php', {
  82. qs: {
  83. sn: sn
  84. }
  85. });
  86. }).json(function (_ref2) {
  87. var content = _ref2.content;
  88. var body = /<body[\s\w"-=]*>([\s\S]*)<\/body>/.exec(content)[1];
  89. var ans = /A[::](\d)/.exec(body)[1];
  90. return parseInt(ans);
  91. });
  92. }
  93. function getQuestion() {
  94. return xf.get('/ajax/animeGetQuestion.php', {
  95. qs: {
  96. t: Date.now()
  97. }
  98. }).json();
  99. }
  100. function answerQuestion(t) {
  101. return getQuestion().then(function (obj) {
  102. return xf.post('/ajax/animeAnsQuestion.php', {
  103. urlencoded: {
  104. token: obj.token,
  105. ans: t,
  106. t: Date.now()
  107. }
  108. }).json();
  109. }).then(function (o) {
  110. if (o.error || o.msg === '答題錯誤') throw o;
  111. return o;
  112. });
  113. }
  114.  
  115. var m3u8container = $('<div>').addClass('anig-ct');
  116. var it = setInterval(function () {
  117. if (typeof videojs !== 'undefined' && videojs.getPlayer('ani_video')) {
  118. clearInterval(it);
  119. var vid = videojs.getPlayer('ani_video');
  120. unsafeWindow.ani_video = vid;
  121. var fn = vid.src.bind(vid);
  122.  
  123. vid.src = function (src) {
  124. if (!src) {
  125. return fn();
  126. }
  127.  
  128. onPlaylistUrl(typeof src === 'string' ? src : src.src);
  129. fn(src);
  130. };
  131. }
  132. }, 100);
  133.  
  134. function render(pls) {
  135. pls.map(function (pl) {
  136. return $('<a>').addClass('anig-tb').addClass('tdn').text(pl.res.height + 'p').attr('href', pl.url).attr('target', '_blank');
  137. }).forEach(function (el) {
  138. return m3u8container.append(el);
  139. });
  140. }
  141.  
  142. function onPlaylistUrl(playlisturl) {
  143. if (playlisturl.indexOf('gamer_ad') !== -1) {
  144. //is ad
  145. return;
  146. }
  147.  
  148. var baseurl = playlisturl.replace(/playlist\.m3u8.*/, '');
  149. fetch(playlisturl).then(function (r) {
  150. return r.text();
  151. }).then(cvtM3U8_to_playlist(baseurl)).then(function (pls) {
  152. return window.unsafeWindow = pls;
  153. }) //EXPOSE
  154. .then(render);
  155. }
  156.  
  157. //extra: block anti adblock alert
  158. var orig_alert = alert;
  159.  
  160. unsafeWindow.alert = function (t) {
  161. if (t.includes('由於擋廣告插件會影響播放器運作')) return;
  162. orig_alert(t);
  163. };
  164.  
  165. var text, title;
  166. var exportdanmu = $('<a>').on('click', function (e) {
  167. e.preventDefault();
  168. saveTextAsFile(text, "".concat(title, "_\u5F48\u5E55.json"));
  169. }).text('把彈幕存成檔案').addClass('anig-tb'); //extra: add a button to download danmu as json file
  170.  
  171. var restore = hookSetter(animefun, 'danmu', function (danmu) {
  172. text = JSON.stringify(danmu);
  173. title = $('.anime_name h1').text();
  174. restore();
  175. });
  176.  
  177. var showans = $('<a>').on('click', function (e) {
  178. e.preventDefault();
  179. ani_video.total_time = 1000;
  180. ani_video.currentTime(ani_video.duration());
  181. }).text('直接顯示動漫通問題').addClass('anig-tb');
  182. var fetchans = $('<a>').on('click', function (e) {
  183. getTodayAnswer().then(function (ans) {
  184. alert('答案可能是 ' + ans);
  185. }).catch(function (err) {
  186. console.error(err);
  187. alert('抓取答案失敗,建議去官方粉絲團尋找答案');
  188. });
  189. }).text('試著從 blackxblue 小屋中抓取答案(實驗性)').addClass('anig-tb');
  190. var answerans = $('<a>').on('click', function (e) {
  191. getTodayAnswer().then(answerQuestion).then(function (result) {
  192. alert("\u7B54\u984C\u6210\u529F: ".concat(result.gift));
  193. }).catch(function (err) {
  194. console.error(err);
  195. alert("\u56DE\u7B54\u554F\u984C\u5931\u6557: ".concat(err.msg));
  196. });
  197. }).text('直接回答問題(實驗性)').addClass('anig-tb');
  198.  
  199. var URL$1 = 'https://gf.qytechs.cn/zh-TW/scripts/370155-%E8%B7%B3%E9%81%8E%E5%8B%95%E7%95%AB%E7%98%8B%E5%BB%A3%E5%91%8A';
  200. var adskip = $('<a>').on('click', function (e) {
  201. if (confirm('這需要下載另一個腳本,請問要打開連結嗎?')) {
  202. window.open(URL$1, '_blank');
  203. GM_setValue('hideadskip', true);
  204. adskip.hide();
  205. } else {
  206. if (confirm('隱藏此按鈕? 重新安裝腳本可以重新顯示此按鈕')) {
  207. GM_setValue('hideadskip', true);
  208. adskip.hide();
  209. }
  210. }
  211. }).text('跳過動畫瘋廣告 ( 宣傳 )').addClass('anig-tb');
  212.  
  213. if (GM_getValue('hideadskip')) {
  214. adskip.hide();
  215. }
  216.  
  217. var $ct = $('<div>').addClass('anig-ct');
  218. $ct.append(exportdanmu).append(showans).append(fetchans).append(answerans).append(adskip);
  219. $('.anime_name').append($ct).append(m3u8container);
  220.  
  221. function styleInject(css, ref) {
  222. if ( ref === void 0 ) ref = {};
  223. var insertAt = ref.insertAt;
  224.  
  225. if (!css || typeof document === 'undefined') { return; }
  226.  
  227. var head = document.head || document.getElementsByTagName('head')[0];
  228. var style = document.createElement('style');
  229. style.type = 'text/css';
  230.  
  231. if (insertAt === 'top') {
  232. if (head.firstChild) {
  233. head.insertBefore(style, head.firstChild);
  234. } else {
  235. head.appendChild(style);
  236. }
  237. } else {
  238. head.appendChild(style);
  239. }
  240.  
  241. if (style.styleSheet) {
  242. style.styleSheet.cssText = css;
  243. } else {
  244. style.appendChild(document.createTextNode(css));
  245. }
  246. }
  247.  
  248. var css = ".anig-ct {\r\n\tdisplay: flex;\r\n\twidth: 100%;\r\n\tmargin: 5px;\r\n}\r\n\r\n.anig-tb {\r\n\tdisplay: inline-block;\r\n\tpadding: 5px;\r\n\tbackground: #00B4D8;\r\n\tcolor: #FFF;\r\n\tmargin-right: 5px;\r\n\tborder: 1px solid #BBB;\r\n}\r\n\r\n.tdn{\r\n\ttext-decoration: none;\r\n}\r\n";
  249. styleInject(css);
  250.  
  251. }());

QingJ © 2025

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