-
Notifications
You must be signed in to change notification settings - Fork 112
/
main.js
151 lines (131 loc) · 3.93 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
const SRT_ID = 'srtFile';
const VIDEO_ID = 'videoFile';
const srtInput = document.querySelector('#srtFile');
const videoInput = document.querySelector('#videoFile');
const video = document.querySelector('#video');
const textArea = document.querySelector('#textArea');
const status = document.querySelector('#status');
const reactTime = 0.4;
let subTexts = [];
let currentStamping = 0;
let lines = [];
function clamp(num) {
return Math.max(num, 0);
}
const keyMap = {
'k': video => {
if (currentStamping >= lines.length) {
return;
}
lines[currentStamping + 1][0] = clamp(video.currentTime - reactTime);
if (lines[currentStamping][1] > video.currentTime - reactTime || lines[currentStamping][1] === null){
lines[currentStamping][1] = clamp(video.currentTime - 0.03 - reactTime);
}
currentStamping += 1;
},
'l': video => {
lines[currentStamping] = [
lines[currentStamping][0],
video.currentTime - reactTime
];
},
'i': () => {
currentStamping -= 1;
},
'o': () => {
currentStamping += 1;
},
'u': () => (video.currentTime -= 2),
'p': () => (video.currentTime += 2),
'q': () => makeSRT()
};
function getCurrentStatus() {
return `Stamping Line ${currentStamping} | Playhead: ${video.currentTime}`;
}
function execHotkey(keyMap) {
document.addEventListener('keypress', function(e) {
const execFn = keyMap[e.key.toLowerCase()];
if (typeof execFn === 'function') {
execFn(video);
updateContent();
}
});
}
function updateContent() {
const head = '** 目前 ---> ';
const content = subTexts
.slice(currentStamping, currentStamping + 5)
.map((text, i) => {
const [timeStart, timeEnd] = lines[currentStamping + i];
return `${i === 0 ? head : ''}${text} | ${timeStart} --> ${timeEnd}`;
})
.join('\n');
textArea.value = content;
}
function handleFileUpload(e) {
if (e.target.files !== null) {
const reader = new FileReader();
const file = e.target.files[0];
/*
if it's srt file, fill text area with srt content
if it's video, load it into video tag
*/
reader.onload = function() {
if (e.target.id === SRT_ID) {
subTexts = reader.result.split('\n');
subTexts.forEach((_, i) => (lines[i] = [null, null]));
lines[0][0] = 0;
updateContent();
execHotkey(keyMap);
}
};
reader.onerror = function() {
alert('無法讀取檔案!');
};
if (e.target.id === SRT_ID) {
reader.readAsText(file);
} else {
video.src = URL.createObjectURL(file);
}
}
}
videoInput.addEventListener('change', handleFileUpload);
srtInput.addEventListener('change', handleFileUpload);
video.addEventListener('timeupdate', function(e) {
status.textContent = getCurrentStatus();
});
function makeSRT() {
srt = '';
for (let i = 0; i < subTexts.length; i++) {
// line number
srt += i + 1 + '\n';
// line time
let sh, sm, ss, sms;
let eh, em, es, ems;
const [timeStart, timeEnd] = lines[i];
const leftPad = str => `${str}`.padStart(2, '0');
const leftPad3 = str => `${str}`.padStart(3, '0');
sh = leftPad(Math.floor(timeStart / 3600));
sm = leftPad(Math.floor((timeStart % 3600) / 60));
ss = leftPad(Math.floor(timeStart % 60));
sms = leftPad3(Math.floor((timeStart * 1000) % 1000));
eh = leftPad(Math.floor(timeEnd / 3600));
em = leftPad(Math.floor((timeEnd % 3600) / 60));
es = leftPad(Math.floor(timeEnd % 60));
ems = leftPad3(Math.floor((timeEnd * 1000) % 1000));
srt += `${sh}:${sm}:${ss},${sms} --> ${eh}:${em}:${es},${ems}\n`;
srt += subTexts[i];
srt += '\n\n';
}
console.log(srt);
let blob = new Blob([srt], {
type: 'text/plain;charset=utf-8'
});
const a = document.createElement('a');
const file = new Blob([srt], { type: 'text/plain;charset=utf-8' });
a.href = URL.createObjectURL(file);
a.download = 'srt.txt';
a.click();
URL.revokeObjectURL(a.href);
a.remove();
}