Add buttons to load the .lrc format file on the edit screen on typing-tube.net.
目前為
// ==UserScript==
// @name lrcReader[typing-tube.net]
// @namespace http://tampermonkey.net/lrcReader
// @version 0.43
// @description Add buttons to load the .lrc format file on the edit screen on typing-tube.net.
// @author Spacia
// @match https://typing-tube.net/movie/edit?videoid=*
// @grant none
// ==/UserScript==
//Greasy Fork https://greasyfork.org/ja/scripts/391474-realtimecombatting-typing-tube
//This is the Entry point.
(function() {
'use strict';
AddLrcReaderElements();
})();
function AddLrcReaderElements(){
// Add a div element to be container to the bottom of the navigation menu "edit".
var elDiv = document.createElement("div");
elDiv.classList.add('row');
elDiv.classList.add('ml-2');
elDiv.classList.add('w-100');
elDiv.id = "ContainerOflrcReader";
var elEdit = document.getElementById("edit");
elEdit.appendChild(elDiv);
var elDevId = document.getElementById("ContainerOflrcReader");
// Add a button for uploading .lrc format file in container created by former code.
var elTextDiv = document.createElement("div");
elTextDiv.classList.add("col-4");
elTextDiv.innerHTML = "lrcファイルを参照";
elDevId.appendChild(elTextDiv);
var elForm = document.createElement("form");
elForm.classList.add("col-6");
elForm.innerHTML = "<div><input name='lrcFile' type='file' accept='.lrc'></div>";
elForm.addEventListener('change', onLoadLrc);
elDevId.appendChild(elForm);
// Add a div element to be container to the bottom of the navigation menu "edit".
var elDiv2 = document.createElement("div");
elDiv2.classList.add('row');
elDiv2.classList.add('ml-2');
elDiv2.classList.add('w-100');
elDiv2.id = "ContainerOflrcReader2";
var elEdit = document.getElementById("edit");
elEdit.appendChild(elDiv2);
// Add a button for uploading .lrc format file in container created by former code.
var elTextDiv2 = document.createElement("div");
elTextDiv2.classList.add("col-4");
elTextDiv2.innerHTML = "replファイルを参照";
elDiv2.appendChild(elTextDiv2);
var elForm2 = document.createElement("form");
elForm2.classList.add("col-6");
elForm2.innerHTML = "<div><input name='replFile' type='file' accept='.repl.txt'></div>";
elForm2.addEventListener('change', onLoadRepl);
elDiv2.appendChild(elForm2);
// Add a div element to be container to the bottom of the navigation menu "edit".
var elDiv3 = document.createElement("div");
elDiv3.classList.add('row');
elDiv3.classList.add('ml-2');
elDiv3.classList.add('w-100');
elDiv3.id = "ContainerOflrcReader2";
elEdit.appendChild(elDiv3);
// Add radio buttons to select English or Kana.
var elForm3 = document.createElement("form");
elForm3.classList.add("col-4");
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>";
elDiv3.appendChild(elForm3);
var elDiv4 = document.createElement("div");
elDiv4.classList.add('row');
elDiv4.classList.add('ml-2');
elDiv4.classList.add('w-100');
elDiv4.id = "ContainerOflrcReader2";
elEdit.appendChild(elDiv4);
var btStart = document.createElement("input");
btStart.id = "LRstart";
btStart.setAttribute("type","button");
btStart.setAttribute("value","lrcファイルの読み込みを開始!");
btStart.setAttribute("style","margin:4px 4px");
btStart.disabled = true;
btStart.addEventListener("click", start);
elDiv4.appendChild(btStart);
}
var _file;
var fr;
function onLoadLrc(event){
_file = event.target.files[0];
document.getElementById("LRstart").disabled = (_file == null);
if(_file != null){
fr = new FileReader();
fr.onload = function(e) {
// A file was loaded.
SetLinesOfLyricsToTimelineTable(fr.result.split('\n'));
}
}
}
var mapOfRuby = {};
function onLoadRepl(event){
var _file = event.target.files[0];
if(_file != null){
var fr = new FileReader();
fr.onload = function(e) {
// A file was loaded.
var listOfRuby = fr.result.split('\n');
mapOfRuby = {};
listOfRuby.forEach((ruby) => {
var val = ruby.match(/,[^,]*$/)[0].replace(",", "").replace("\"", "");
var key = ruby.match(/^[^,]*,/)[0].replace(",", "").replace("\"", "");
// console.log(key);
// console.log(val);
mapOfRuby[key] = val;
});
}
fr.readAsText(_file);
}
}
function start(){
SetTimeEvent();
if(fr){
fr.readAsText(_file);
}else{
alert("Failed to load file formated .lrc");
}
}
var isKanaMode; //load mode of kana or english
var lineidx = 0;
var time;
var editedLine;
var lines;
var timeEventFlag;
function SetTimeEvent(){
setTimeout(() => {
if(document.getElementById("kana").value.length != 0){
Clock_AddTimeTable();
}
if(timeEventFlag){
SetTimeEvent();
}
}, 20);
}
function SetLinesOfLyricsToTimelineTable(_lines) {
isKanaMode = document.getElementById('lrcConverTypeKana').checked;
lineidx = 0;
lines = _lines;
timeEventFlag = true;
retriveLineInfo();
}
function retriveLineInfo(){
var line = lines[lineidx++];
var ptnsOfTimeTag = [
/\[\d\d:\d\d:\d\d\]/g,
/\[\d\d:\d\d.\d\d\]/g,
/\[\d\d:\d\d]/g
];
//if empty line then check next line.
var isEmpty = true;
var isCsOmitted = false;
ptnsOfTimeTag.forEach(function(ptn, idx){
if(ptn.test(line) == true){
isEmpty = false;
if(idx == 2){
isCsOmitted = true;
}
}
});
if(isEmpty){
if(lineidx < lines.length){
retriveLineInfo();
}else{
timeEventFlag = false;
addRuby();
}
return;
}
//get time for this line.
var ptnOfTwoDigidTime = /\d\d/g;
var timesStr = line.match(ptnOfTwoDigidTime);
var minute = parseFloat(timesStr[0]);
var second = parseFloat(timesStr[1]);
var centiSec = 0;
if(!isCsOmitted){
centiSec = parseFloat(timesStr[2]);
}
time = minute * 60 + second + centiSec * 0.01;
//console.log(time);
//get line of text.
editedLine = line;
ptnsOfTimeTag.forEach(function(ptn, idx){
editedLine = editedLine.replace(ptn,"").trim();
});
//console.log(editedLine);
//Add time and lineLyrics to the timeline Table in the navigation menu "edit".
document.getElementById("time").value = time;
document.getElementById("words").value = editedLine;
//空行なら変換の必要なし。タイムテーブルにそのまま追加
if(editedLine.length == 0){
Clock_AddTimeTable(true);
return;
}
if(isKanaMode){
command_kakasi();
}else{
command_kakasi_en();
}
}
function Clock_AddTimeTable(isEmptyLine = false){
if(isEmptyLine || document.getElementById("kana").value.length != 0){
command_add();
if(lineidx < lines.length){
retriveLineInfo();
}else{
timeEventFlag = false;
addRuby();
}
}
}
function addRuby(){
// console.log(mapOfRuby);
var DOMTbody = document.querySelector("#subtitles_table > tbody");
var DOMlines = DOMTbody.children;
console.log(DOMlines);
for (var i = 0; i < DOMlines.length; i++) {
//<ruby>タグを追加
DOMlines[i].children[1].innerHTML = replaceRuby(DOMlines[i].children[1].innerHTML);
}
}
function replaceRuby(str){
//二重に追加されてしまうのを防止するため、文字数が多い順に追加。
for(var i = 20;i > 0;--i){
Object.keys(mapOfRuby).forEach(function(key){
if(key.length == i){
var val = this[key];
// if(new RegExp("<ruby>?!<\/ruby\/>*" + key + "?!<ruby>*<\/ruby>").test(val)){
str = str.replace(key, "<ruby>" + key + "<rt>" + val + "</rt></ruby>");
}
}, mapOfRuby);
}
return str;
}