Sleazy Fork is available in English.

(DMM PLAYER/ FANZA)日語謎片,實時翻譯, 彈屏

日語謎片實時翻譯學習(本腳本要註冊騰訊ai開放平台賬號(https://ai.qq.com) , 並需接入相關AI功能, 參考詳閱油猴頁面)

  1. // ==UserScript==
  2. // @name (DMM PLAYER/ FANZA)日語謎片,實時翻譯, 彈屏
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description 日語謎片實時翻譯學習(本腳本要註冊騰訊ai開放平台賬號(https://ai.qq.com) , 並需接入相關AI功能, 參考詳閱油猴頁面)
  6. // @author pulamu
  7. // @match https://www.dmm.co.jp/digital/-/player/=/player=html5/act=playlist/*
  8. // @match https://www.dmm.co.jp/monthly/prime/*
  9. // @require https://greasyfork.org/scripts/398373-jquery-pin/code/jquery%20pin.js?version=782863
  10. // @require https://unpkg.com/@khs1994/tencent-ai@19.6.0-alpha.5/dist/tencent-ai.min.js
  11. // @require https://greasyfork.org/scripts/397958-jquery-barrager-js/code/jquerybarragerjs.js?version=780892
  12.  
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. let addStyle = function (aCss) {
  18. let head = document.getElementsByTagName('head')[0];
  19. if (head) {
  20. let style = document.createElement('style');
  21. style.setAttribute('type', 'text/css');
  22. style.textContent = aCss;
  23. head.appendChild(style);
  24. return style;
  25. }
  26. return null;
  27. }
  28. addStyle(`
  29. *.barrage{position: fixed;bottom:70px;right:-500px;display: inline-block;width: 500px;z-index: 99999;}
  30. *.barrage_box{background-color: rgba(0,0,0,.5);padding-right: 8px; height: 40px;display: inline-block;border-radius: 25px;transition: all .3s;}
  31. *.barrage_box .portrait{ display: inline-block;margin-top: 4px; margin-left: 4px; width: 32px;height: 32px;border-radius: 50%;overflow: hidden;}
  32. *.barrage_box .portrait img{width: 100%;height: 100%;}
  33. *.barrage_box div.p a{ margin-right: 2px; font-size: 14px;color: #fff;line-height: 40px;margin-left: 18px; }
  34. *.barrage_box div.p a:hover{text-decoration: underline;}
  35. *.barrage_box .close{visibility: hidden;opacity: 0; text-align: center; width:25px;height: 25px;margin-left: 20px;border-radius: 50%;background:rgba(255,255,255,.1);margin-top:8px; background-image: url(close.png);}
  36. *.barrage_box:hover .close{visibility:visible;opacity: 1;}
  37. *.barrage_box .close a{display:block;}
  38. *.barrage_box .close .icon-close{font-size: 14px;color:rgba(255,255,255,.5);display: inline-block;margin-top: 5px; }
  39. *.barrage .z {float: left !important;}
  40. *.barrage a{text-decoration:none;}
  41. `)
  42. addStyle('ul li{list-style-type:none;}');
  43.  
  44. 'use strict';
  45. let header = $('<meta http-equiv="Access-Control-Allow-Origin" content="*" />');
  46. $("head").append(header)
  47.  
  48. /*
  49. 本腳本要註冊騰訊ai開放平台賬號(https://ai.qq.com)
  50. 並需接入相關AI功能, 參考詳閱油猴頁面
  51. */
  52. let ai = new TencentAI.TencentAI(
  53. "YYYY", // app_sercert 自行後修改
  54. "XXXX", // app_id 自行註冊後修改
  55. "https://www.groupies.online/ai"
  56.  
  57.  
  58. );
  59.  
  60.  
  61. $("html").prepend('<div class="container2" id="pinBoxContainer" style="font-size: 16px;z-index: 9999;position: relative; color:#666666;background-color: #f9f9f9;height: 120px;width: 300px;border: 1px solid #D0D0D0; !important;"><button id = "close" style = "float:right; !important;" >X</button><div >油猴:識別語言</div><select id = "source" style = " !important;"><option value="jp">日本語</option><option value="en">英語</option><option value="kr">韓語</option></select><br><div id="text_info" style=" style = " !important;">商務合作(VX:1909684853)</div><br><div id="text_info2" style=" style = " !important;"><a target="_blank" href="https://greasyfork.org/zh-CN/scripts/398441-d%E7%B3%9F%E6%97%A5%E8%AA%9E%E8%AC%8E%E7%89%87-%E5%AF%A6%E6%99%82%E7%BF%BB%E8%AD%AF-%E5%BD%88%E5%B1%8F">D糟日語謎片翻譯</a></div></div>');
  62. $('#close').click( function(){
  63. $('#pinBoxContainer').hide();
  64.  
  65. });
  66.  
  67. $('html,body').animate({
  68. scrollTop: 0
  69. }, 100);
  70.  
  71.  
  72. /**
  73. * 语音翻译
  74. *
  75. * 识别出音频中的文字,并进行翻译
  76. *
  77. * @see https://ai.qq.com/doc/speechtranslate.shtml
  78. * @param {int} format 默认MP3-8 AMR 3/SILK 4/PCM 6/MP3 8/AAC 9
  79. * @param {int} seq 默认0 语音分片所在语音流的偏移量(字节)
  80. * @param {int} end 默认1 0 中间分片/1 结束分片
  81. * @param {string} session_id 非空且长度上限64B
  82. * @param {string} speech_chunk 语音分片数据的Base64编码,非空且长度上限8MB
  83. * @param {string} source 默认auto 中文 zh / 英文 en/ 日文 jp /韩文 kr / 自动识别(中英互译) auto
  84. * @param {string} target 默认auto en=> zh / zh=> en, jp, kr / jp=>zh / kr=> zh
  85. *
  86. * @return {Promise} A Promise Object
  87. */
  88.  
  89. var max = 0
  90. if (navigator.mediaDevices.getDisplayMedia) {
  91. var chunks = [];
  92. const constraints = { video: true ,audio: true };
  93. navigator.mediaDevices.getDisplayMedia(constraints).then(
  94. stream => {
  95.  
  96.  
  97.  
  98. var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  99. var analyser = audioCtx.createAnalyser();
  100. source = audioCtx.createMediaStreamSource(stream);
  101. source.connect(analyser);
  102.  
  103. analyser.fftSize = 2048;
  104. var bufferLength = analyser.frequencyBinCount;
  105. var dataArray = new Uint8Array(bufferLength);
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113. console.log("授权成功!");
  114. stream.getVideoTracks()[0].stop();
  115. stream.removeTrack(stream.getVideoTracks()[0]);
  116. const mediaRecorder = new MediaRecorder(stream);
  117.  
  118.  
  119.  
  120. setTimeout(() => {
  121. mediaRecorder.start();
  122.  
  123.  
  124. console.log("录音中...");
  125.  
  126. console.log("录音器状态:", mediaRecorder.state);
  127. $("#text_info").html("運行中...")
  128. },6000);
  129.  
  130. setInterval(() => {
  131. max = max + 1
  132. analyser.getByteTimeDomainData(dataArray);
  133. //console.log(dataArray);
  134. //analyser.getByteFrequencyData(dataArray);
  135. console.log(dataArray);
  136.  
  137. var s = 0
  138. for (var i = 0; i < bufferLength; i++) {
  139. barHeight = dataArray[i]
  140. if (barHeight >= 127 - 127 *5/100 && barHeight <= 128 + 128 *5/100 ){
  141. s = s+ 1
  142. }
  143.  
  144.  
  145. }
  146. console.log(s / bufferLength);
  147. console.log(max)
  148.  
  149. if(s / bufferLength >= 0.8 || max > 3){
  150. mediaRecorder.stop();
  151. console.log("停止录音...");
  152.  
  153. console.log("录音器状态:", mediaRecorder.state);
  154.  
  155. max = 0;
  156. }
  157.  
  158. },5000);
  159.  
  160.  
  161. chunks = []
  162. mediaRecorder.ondataavailable = function(e) {
  163. chunks.push(e.data);
  164.  
  165. };
  166.  
  167.  
  168.  
  169. mediaRecorder.onstop = e => {
  170. var blob = new Blob(chunks,{type : 'audio/mp3'});
  171. chunks = [];
  172. mediaRecorder.start();
  173. var audioURL = URL.createObjectURL(blob);
  174. console.log(audioURL);
  175. let reader = new FileReader();
  176. reader.readAsDataURL(blob); // converts the blob to base64 and calls onload
  177. reader.onloadend = function() {
  178.  
  179. var base64data = reader.result;
  180. var b64 = reader.result.replace(/^data:.+;base64,/, '');
  181.  
  182. var source = $("#source").val();
  183. $("#text_info").html(source + "翻譯中...")
  184.  
  185. ai.translate.speech(b64,audioURL.replace('blob:' + location.protocol + '//' + location.hostname + '/',''),8,0,1,source,'zh').then(res => {
  186. console.log("FOO33");
  187. console.log(res);
  188. //console.log(res.data.source_text);
  189. //console.log(res.data.target_text);
  190. if (res.data.source_text !== "")
  191. {
  192. var word = res.data.source_text + "(" + res.data.target_text + ")"
  193. var item={
  194. img:'', //图片
  195. info: res.data.source_text + "(" + res.data.target_text + ")" , //文字
  196. href:'javascript:void(0)', //链接
  197. close:true, //显示关闭按钮
  198. speed:16, //延迟,单位秒,默认6
  199. color:'#fff', //颜色,默认白色
  200. old_ie_color:'#000000', //ie低版兼容色,不能与网页背景相同,默认黑色
  201. }
  202. $('body').barrager(item);
  203. $("#text_info").html(res.data.target_text)
  204. $('.z a').removeAttr('target');
  205. if (word.length >=40){
  206. $('.barrage_box').css("height","100px");
  207. }
  208. $('.barrage_box').setAttribute('class', 'player full-screen');
  209. }
  210.  
  211. });
  212. //console.log(b64);
  213. }
  214.  
  215.  
  216. };
  217. },
  218. () => {
  219. console.error("授权失败!");
  220. $("#text_info").html("授权失败!")
  221. }
  222. );
  223. } else {
  224. console.error("浏览器不支持 getUserMedia");
  225. $("#text_info").html("浏览器不支持 getUserMedia")
  226. }
  227. // Your code here...
  228. })();