Add files via upload
This commit is contained in:
106
index.html
Normal file
106
index.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<html>
|
||||
<title>Fast and Dirty Captioner</title>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script src="p5.min.js"></script>
|
||||
<script src="p5.sound.min.js"></script>
|
||||
<script src="sketch.js"></script>
|
||||
<script>
|
||||
(function(a, b) {
|
||||
if ("function" == typeof define && define.amd) define([], b);
|
||||
else if ("undefined" != typeof exports) b();
|
||||
else {
|
||||
b(), a.FileSaver = {
|
||||
exports: {}
|
||||
}.exports
|
||||
}
|
||||
})(this, function() {
|
||||
"use strict";
|
||||
|
||||
function b(a, b) {
|
||||
return "undefined" == typeof b ? b = {
|
||||
autoBom: !1
|
||||
} : "object" != typeof b && (console.warn("Deprecated: Expected third argument to be a object"), b = {
|
||||
autoBom: !b
|
||||
}), b.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type) ? new Blob(["\uFEFF", a], {
|
||||
type: a.type
|
||||
}) : a
|
||||
}
|
||||
|
||||
function c(b, c, d) {
|
||||
var e = new XMLHttpRequest;
|
||||
e.open("GET", b), e.responseType = "blob", e.onload = function() {
|
||||
a(e.response, c, d)
|
||||
}, e.onerror = function() {
|
||||
console.error("could not download file")
|
||||
}, e.send()
|
||||
}
|
||||
|
||||
function d(a) {
|
||||
var b = new XMLHttpRequest;
|
||||
b.open("HEAD", a, !1);
|
||||
try {
|
||||
b.send()
|
||||
} catch (a) {}
|
||||
return 200 <= b.status && 299 >= b.status
|
||||
}
|
||||
|
||||
function e(a) {
|
||||
try {
|
||||
a.dispatchEvent(new MouseEvent("click"))
|
||||
} catch (c) {
|
||||
var b = document.createEvent("MouseEvents");
|
||||
b.initMouseEvent("click", !0, !0, window, 0, 0, 0, 80, 20, !1, !1, !1, !1, 0, null), a.dispatchEvent(b)
|
||||
}
|
||||
}
|
||||
var f = "object" == typeof window && window.window === window ? window : "object" == typeof self && self.self === self ? self : "object" == typeof global && global.global === global ? global : void 0,
|
||||
a = f.saveAs || ("object" != typeof window || window !== f ? function() {} : "download" in HTMLAnchorElement.prototype ? function(b, g, h) {
|
||||
var i = f.URL || f.webkitURL,
|
||||
j = document.createElement("a");
|
||||
g = g || b.name || "download", j.download = g, j.rel = "noopener", "string" == typeof b ? (j.href = b, j.origin === location.origin ? e(j) : d(j.href) ? c(b, g, h) : e(j, j.target = "_blank")) : (j.href = i.createObjectURL(b),
|
||||
setTimeout(function() {
|
||||
i.revokeObjectURL(j.href)
|
||||
}, 4E4), setTimeout(function() {
|
||||
e(j)
|
||||
}, 0))
|
||||
} : "msSaveOrOpenBlob" in navigator ? function(f, g, h) {
|
||||
if (g = g || f.name || "download", "string" != typeof f) navigator.msSaveOrOpenBlob(b(f, h), g);
|
||||
else if (d(f)) c(f, g, h);
|
||||
else {
|
||||
var i = document.createElement("a");
|
||||
i.href = f, i.target = "_blank", setTimeout(function() {
|
||||
e(i)
|
||||
})
|
||||
}
|
||||
} : function(a, b, d, e) {
|
||||
if (e = e || open("", "_blank"), e && (e.document.title = e.document.body.innerText = "downloading..."), "string" == typeof a) return c(a, b, d);
|
||||
var g = "application/octet-stream" === a.type,
|
||||
h = /constructor/i.test(f.HTMLElement) || f.safari,
|
||||
i = /CriOS\/[\d]+/.test(navigator.userAgent);
|
||||
if ((i || g && h) && "undefined" != typeof FileReader) {
|
||||
var j = new FileReader;
|
||||
j.onloadend = function() {
|
||||
var a = j.result;
|
||||
a = i ? a : a.replace(/^data:[^;]*;/, "data:attachment/file;"), e ? e.location.href = a : location = a, e = null
|
||||
}, j.readAsDataURL(a)
|
||||
} else {
|
||||
var k = f.URL || f.webkitURL,
|
||||
l = k.createObjectURL(a);
|
||||
e ? e.location = l : location.href = l, e = null, setTimeout(function() {
|
||||
k.revokeObjectURL(l)
|
||||
}, 4E4)
|
||||
}
|
||||
});
|
||||
f.saveAs = a.saveAs = a, "undefined" != typeof module && (module.exports = a)
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>K: 下一行開始 | L: 這一行提前結束 | I: 前捲一行 | O: 後捲一行 </p>
|
||||
<p id="status">Test Text.</p>
|
||||
<textarea id="textArea" rows="10" cols="80">預設的字。</textarea>
|
||||
</body>
|
||||
|
||||
</html>
|
3
p5.min.js
vendored
Normal file
3
p5.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
28
p5.sound.min.js
vendored
Normal file
28
p5.sound.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
105
sketch.js
Normal file
105
sketch.js
Normal file
@@ -0,0 +1,105 @@
|
||||
let curr; // current time
|
||||
let sta; // status text
|
||||
let status; // = select("#status");
|
||||
let tAreaText; //
|
||||
let tArea;
|
||||
let vidFile = "./video.mp4";
|
||||
let subFile = "./subs.txt";
|
||||
let subText; // load from text file
|
||||
let lineStartTime = [];
|
||||
let lineEndTime = [];
|
||||
let reactTime = 0.4;
|
||||
|
||||
let currentStamping = 0;
|
||||
let srt = "";
|
||||
|
||||
function preload() {
|
||||
vid = createVideo(vidFile);
|
||||
vid.size(640, 320);
|
||||
subText = loadStrings(subFile);
|
||||
}
|
||||
|
||||
function setup() {
|
||||
noCanvas();
|
||||
status = select("#status");
|
||||
tArea = select("#textArea");
|
||||
|
||||
for (let i = 0; i < subText.length; i++) {
|
||||
lineStartTime[i] = null;
|
||||
lineEndTime[i] = null;
|
||||
|
||||
//init all timestamps to 0
|
||||
}
|
||||
lineStartTime[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
function draw() {
|
||||
curr = vid.elt.currentTime;
|
||||
sta = `Stamping Line ${currentStamping} | Playhead: ${curr}`;
|
||||
tAreaText = "";
|
||||
for (let i = -2; i < 5; i++) {
|
||||
if (i == 0) {
|
||||
tAreaText += "** 目前 ---> "
|
||||
}
|
||||
tAreaText += `${subText[currentStamping+i]} | ${lineStartTime[currentStamping+i]} --> ${lineEndTime[currentStamping+i]}` + String.fromCharCode(13, 10);
|
||||
}
|
||||
status.html(sta);
|
||||
tArea.html(tAreaText);
|
||||
}
|
||||
|
||||
function keyPressed() {
|
||||
if (keyCode === 75) { // K
|
||||
// 按左鍵
|
||||
// set line start time to current time
|
||||
lineStartTime[currentStamping + 1] = vid.elt.currentTime - reactTime;
|
||||
if (lineStartTime[currentStamping + 1] < 0){
|
||||
lineStartTime[currentStamping + 1] = 0;
|
||||
}
|
||||
// set prev line's end time, if prev end time > currentTime;
|
||||
if (lineEndTime[currentStamping] > vid.elt.currentTime - reactTime || lineEndTime[currentStamping] == null) {
|
||||
lineEndTime[currentStamping] = vid.elt.currentTime - 0.03 - reactTime;
|
||||
if (lineEndTime[currentStamping] < 0){
|
||||
lineEndTime[currentStamping] = 0;
|
||||
}
|
||||
}
|
||||
currentStamping++;
|
||||
} else if (keyCode === 76) { // L
|
||||
lineEndTime[currentStamping] = vid.elt.currentTime - reactTime;
|
||||
} else if (keyCode === 73) { // I
|
||||
currentStamping--;
|
||||
} else if (keyCode === 79) { // O
|
||||
currentStamping++;
|
||||
} else if (keyCode === 81) {
|
||||
// Q : Make SRT
|
||||
makeSRT();
|
||||
}
|
||||
}
|
||||
|
||||
function makeSRT() {
|
||||
srt = "";
|
||||
for (let i = 0; i < subText.length; i++) {
|
||||
// line number
|
||||
srt += (i + 1) + "\n";
|
||||
// line time
|
||||
let sh, sm, ss, sms;
|
||||
let eh, em, es, ems;
|
||||
sh = floor(lineStartTime[i] / 3600);
|
||||
sm = floor((lineStartTime[i] % 3600) / 60);
|
||||
ss = floor(lineStartTime[i] % 60);
|
||||
sms = floor((lineStartTime[i] * 1000) % 1000);
|
||||
eh = floor(lineEndTime[i] / 3600);
|
||||
em = floor((lineEndTime[i] % 3600) / 60);
|
||||
es = floor(lineEndTime[i] % 60);
|
||||
ems = floor((lineEndTime[i] * 1000) % 1000);
|
||||
|
||||
srt += `${sh}:${sm}:${ss},${sms} --> ${eh}:${em}:${es},${ems}\n`
|
||||
srt += subText[i];
|
||||
srt += "\n\n"
|
||||
}
|
||||
console.log(srt);
|
||||
let blob = new Blob([srt], {
|
||||
type: "text/plain;charset=utf-8"
|
||||
});
|
||||
saveAs(blob, 'srt.txt');
|
||||
}
|
Reference in New Issue
Block a user