lrcReader[typing-tube.net]

Add buttons to load the .lrc format file on the edit screen on typing-tube.net.

目前为 2019-11-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name lrcReader[typing-tube.net]
  3. // @namespace http://tampermonkey.net/lrcReader
  4. // @version 0.42
  5. // @description Add buttons to load the .lrc format file on the edit screen on typing-tube.net.
  6. // @author Spacia
  7. // @match https://typing-tube.net/movie/edit?videoid=*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. //Greasy Fork https://greasyfork.org/ja/scripts/391474-realtimecombatting-typing-tube
  12.  
  13. //This is the Entry point.
  14. (function() {
  15. 'use strict';
  16.  
  17. AddLrcReaderElements();
  18.  
  19. })();
  20.  
  21.  
  22. function AddLrcReaderElements(){
  23.  
  24. // Add a div element to be container to the bottom of the navigation menu "edit".
  25. var elDiv = document.createElement("div");
  26. elDiv.classList.add('row');
  27. elDiv.classList.add('ml-2');
  28. elDiv.classList.add('w-100');
  29. elDiv.id = "ContainerOflrcReader";
  30. var elEdit = document.getElementById("edit");
  31. elEdit.appendChild(elDiv);
  32. var elDevId = document.getElementById("ContainerOflrcReader");
  33.  
  34. // Add a button for uploading .lrc format file in container created by former code.
  35. var elTextDiv = document.createElement("div");
  36. elTextDiv.classList.add("col-4");
  37. elTextDiv.innerHTML = "lrcファイルを参照";
  38. elDevId.appendChild(elTextDiv);
  39.  
  40. var elForm = document.createElement("form");
  41. elForm.classList.add("col-6");
  42. elForm.innerHTML = "<div><input name='lrcFile' type='file' accept='.lrc'></div>";
  43. elForm.addEventListener('change', onLoadLrc);
  44. elDevId.appendChild(elForm);
  45.  
  46.  
  47. // Add a div element to be container to the bottom of the navigation menu "edit".
  48. var elDiv2 = document.createElement("div");
  49. elDiv2.classList.add('row');
  50. elDiv2.classList.add('ml-2');
  51. elDiv2.classList.add('w-100');
  52. elDiv2.id = "ContainerOflrcReader2";
  53. var elEdit = document.getElementById("edit");
  54. elEdit.appendChild(elDiv2);
  55.  
  56. // Add a button for uploading .lrc format file in container created by former code.
  57. var elTextDiv2 = document.createElement("div");
  58. elTextDiv2.classList.add("col-4");
  59. elTextDiv2.innerHTML = "replファイルを参照";
  60. elDiv2.appendChild(elTextDiv2);
  61.  
  62. var elForm2 = document.createElement("form");
  63. elForm2.classList.add("col-6");
  64. elForm2.innerHTML = "<div><input name='replFile' type='file' accept='.repl.txt'></div>";
  65. elForm2.addEventListener('change', onLoadRepl);
  66. elDiv2.appendChild(elForm2);
  67.  
  68. // Add a div element to be container to the bottom of the navigation menu "edit".
  69. var elDiv3 = document.createElement("div");
  70. elDiv3.classList.add('row');
  71. elDiv3.classList.add('ml-2');
  72. elDiv3.classList.add('w-100');
  73. elDiv3.id = "ContainerOflrcReader2";
  74. elEdit.appendChild(elDiv3);
  75.  
  76. // Add radio buttons to select English or Kana.
  77. var elForm3 = document.createElement("form");
  78. elForm3.classList.add("col-4");
  79. elForm3.innerHTML = "<span style='padding-right:20px;'><label><input id='lrcConverTypeKana' name='lrcConvertType' type='radio' value='kana' checked>かな </label></span><span><label><input name='lrcConvertType' type='radio' value='eng'>英語</label></span>";
  80. elDiv3.appendChild(elForm3);
  81.  
  82. var elDiv4 = document.createElement("div");
  83. elDiv4.classList.add('row');
  84. elDiv4.classList.add('ml-2');
  85. elDiv4.classList.add('w-100');
  86. elDiv4.id = "ContainerOflrcReader2";
  87. elEdit.appendChild(elDiv4);
  88.  
  89. var btStart = document.createElement("input");
  90. btStart.id = "LRstart";
  91. btStart.setAttribute("type","button");
  92. btStart.setAttribute("value","lrcファイルの読み込みを開始!");
  93. btStart.setAttribute("style","margin:4px 4px");
  94. btStart.disabled = true;
  95. btStart.addEventListener("click", start);
  96. elDiv4.appendChild(btStart);
  97.  
  98.  
  99. }
  100. var _file;
  101. var fr;
  102.  
  103. function onLoadLrc(event){
  104. _file = event.target.files[0];
  105.  
  106. document.getElementById("LRstart").disabled = (_file == null);
  107.  
  108. if(_file != null){
  109.  
  110. fr = new FileReader();
  111. fr.onload = function(e) {
  112. // A file was loaded.
  113. SetLinesOfLyricsToTimelineTable(fr.result.split('\n'));
  114. }
  115. }
  116. }
  117.  
  118. var mapOfRuby = {};
  119. function onLoadRepl(event){
  120. var _file = event.target.files[0];
  121.  
  122. if(_file != null){
  123. var fr = new FileReader();
  124. fr.onload = function(e) {
  125. // A file was loaded.
  126. var listOfRuby = fr.result.split('\n');
  127. mapOfRuby = {};
  128. listOfRuby.forEach((ruby) => {
  129. var val = ruby.match(/,[^,]*$/)[0].replace(",", "").replace("\"", "");
  130. var key = ruby.match(/^[^,]*,/)[0].replace(",", "").replace("\"", "");
  131. // console.log(key);
  132. // console.log(val);
  133. mapOfRuby[key] = val;
  134. });
  135. }
  136. fr.readAsText(_file);
  137. }
  138. }
  139.  
  140. function start(){
  141. SetTimeEvent();
  142. if(fr){
  143. fr.readAsText(_file);
  144. }else{
  145. alert("Failed to load file formated .lrc");
  146. }
  147. }
  148.  
  149. var isKanaMode; //load mode of kana or english
  150. var lineidx = 0;
  151. var time;
  152. var editedLine;
  153. var lines;
  154. var timeEventFlag;
  155.  
  156. function SetTimeEvent(){
  157.  
  158. setTimeout(() => {
  159. if(document.getElementById("kana").value.length != 0){
  160. Clock_AddTimeTable();
  161. }
  162. if(timeEventFlag){
  163. SetTimeEvent();
  164. }
  165. }, 20);
  166.  
  167. }
  168.  
  169. function SetLinesOfLyricsToTimelineTable(_lines) {
  170.  
  171. isKanaMode = document.getElementById('lrcConverTypeKana').checked;
  172. lineidx = 0;
  173. lines = _lines;
  174. timeEventFlag = true;
  175.  
  176. retriveLineInfo();
  177. }
  178.  
  179.  
  180. function retriveLineInfo(){
  181.  
  182. var line = lines[lineidx++];
  183.  
  184. var ptnsOfTimeTag = [
  185.  /\[\d\d:\d\d:\d\d\]/g,
  186. /\[\d\d:\d\d.\d\d\]/g,
  187. /\[\d\d:\d\d]/g
  188. ];
  189.  
  190. //if empty line then check next line.
  191. var isEmpty = true;
  192. var isCsOmitted = false;
  193. ptnsOfTimeTag.forEach(function(ptn, idx){
  194. if(ptn.test(line) == true){
  195. isEmpty = false;
  196. if(idx == 2){
  197. isCsOmitted = true;
  198. }
  199. }
  200. });
  201. if(isEmpty){
  202. if(lineidx < lines.length){
  203. retriveLineInfo();
  204. }else{
  205. timeEventFlag = false;
  206. addRuby();
  207. }
  208. return;
  209. }
  210.  
  211.  
  212. //get time for this line.
  213. var ptnOfTwoDigidTime = /\d\d/g;
  214. var timesStr = line.match(ptnOfTwoDigidTime);
  215. var minute = parseFloat(timesStr[0]);
  216. var second = parseFloat(timesStr[1]);
  217. var centiSec = 0;
  218. if(!isCsOmitted){
  219. centiSec = parseFloat(timesStr[2]);
  220. }
  221. time = minute * 60 + second + centiSec * 0.01;
  222. //console.log(time);
  223.  
  224. //get line of text.
  225. editedLine = line;
  226. ptnsOfTimeTag.forEach(function(ptn, idx){
  227. editedLine = editedLine.replace(ptn,"").trim();
  228. });
  229. //console.log(editedLine);
  230.  
  231. //Add time and lineLyrics to the timeline Table in the navigation menu "edit".
  232. document.getElementById("time").value = time;
  233. document.getElementById("words").value = editedLine;
  234.  
  235. //空行なら変換の必要なし。タイムテーブルにそのまま追加
  236. if(editedLine.length == 0){
  237. Clock_AddTimeTable(true);
  238. return;
  239. }
  240.  
  241. if(isKanaMode){
  242. command_kakasi();
  243. }else{
  244. command_kakasi_en();
  245. }
  246. }
  247.  
  248.  
  249. function Clock_AddTimeTable(isEmptyLine = false){
  250. if(isEmptyLine || document.getElementById("kana").value.length != 0){
  251. command_add();
  252. if(lineidx < lines.length){
  253. retriveLineInfo();
  254. }else{
  255. timeEventFlag = false;
  256. addRuby();
  257. }
  258. }
  259. }
  260.  
  261.  
  262. function addRuby(){
  263.  
  264. // console.log(mapOfRuby);
  265.  
  266. var DOMTbody = document.querySelector("#subtitles_table > tbody");
  267. var DOMlines = DOMTbody.children;
  268. console.log(DOMlines);
  269. for (var i = 0; i < DOMlines.length; i++) {
  270. //<ruby>タグを追加
  271. DOMlines[i].children[1].innerHTML = replaceRuby(DOMlines[i].children[1].innerHTML);
  272. }
  273.  
  274. }
  275.  
  276. function replaceRuby(str){
  277. Object.keys(mapOfRuby).forEach(function(key){
  278. var val = this[key];
  279. str = str.replace(key, "<ruby>" + key + "<rt>" + val + "</rt></ruby>");
  280. }, mapOfRuby);
  281. return str;
  282. }