308 lines
7.3 KiB
JavaScript
308 lines
7.3 KiB
JavaScript
|
//elem = string (elementId to make TextArea)
|
||
|
var TextArea = function(elem) {
|
||
|
this.elem = $('#' + elem);
|
||
|
this.hasFocus = false;
|
||
|
this.width = this.elem.width();
|
||
|
this.init()
|
||
|
}
|
||
|
|
||
|
TextArea.prototype.init = function() {
|
||
|
var that = this;
|
||
|
var e = this.elem;
|
||
|
var tc;
|
||
|
e.focus(function() {
|
||
|
that.hasFocus = true;
|
||
|
}).blur(function() {
|
||
|
that.hasFocus = false;
|
||
|
});
|
||
|
e.dblclick(function() {
|
||
|
if (tc = that.isTc()) {
|
||
|
Video.set(tc);
|
||
|
} else {
|
||
|
that.insertTc();
|
||
|
}
|
||
|
Video.togglePause();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
//returns tc in ms if cursor is at a time-code, else returns false
|
||
|
TextArea.prototype.isTc = function() {
|
||
|
var that = this;
|
||
|
var e = this.elem;
|
||
|
var eDom = e.get(0);
|
||
|
var val = e.val();
|
||
|
var pos = eDom.selectionStart;
|
||
|
var word = this.getWord(pos);
|
||
|
if (isValidTimecode(word)) {
|
||
|
return npt2ms(word);
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//inserts current timecode at cursor position
|
||
|
TextArea.prototype.insertTc = function() {
|
||
|
var that = this;
|
||
|
var e = that.elem;
|
||
|
var eDom = e.get(0);
|
||
|
var scrollTop = eDom.scrollTop;
|
||
|
var val = this.elem.val();
|
||
|
var pos = eDom.selectionStart;
|
||
|
var tcNpt = ms2npt(Video.get());
|
||
|
var newVal = val.substring(0,pos) + "\n" + tcNpt + "\n" + val.substring(pos, val.length);
|
||
|
e.val(newVal);
|
||
|
e.focus();
|
||
|
eDom.selectionStart = pos + tcNpt.length + 1;
|
||
|
eDom.selectionEnd = pos + tcNpt.length + 1;
|
||
|
eDom.scrollTop = scrollTop + 15;
|
||
|
}
|
||
|
|
||
|
//gets the word at character pos (int) [in val (str)]
|
||
|
TextArea.prototype.getWord = function(pos, val) {
|
||
|
if (!val) {
|
||
|
val = this.elem.val();
|
||
|
}
|
||
|
var c;
|
||
|
var i = pos;
|
||
|
var j = pos;
|
||
|
while (c != " " && c != "\n") {
|
||
|
if (i==0) {
|
||
|
i = -1;
|
||
|
break;
|
||
|
}
|
||
|
i--;
|
||
|
c = val.substring(i,i+1);
|
||
|
}
|
||
|
var firstLetter = i+1;
|
||
|
var d;
|
||
|
while (d != " " && d != "\n") {
|
||
|
if (j >= val.length) {
|
||
|
break;
|
||
|
}
|
||
|
j++;
|
||
|
d = val.substring(j,j+1);
|
||
|
}
|
||
|
var lastLetter = j;
|
||
|
var word = val.substring(firstLetter, lastLetter);
|
||
|
return word;
|
||
|
}
|
||
|
|
||
|
//takes an srt as param, loads into txtarea
|
||
|
TextArea.prototype.fromSrt = function(srt) {
|
||
|
var spans = [];
|
||
|
srt = srt.replace('\r\n|\r|\n', '\n')
|
||
|
srt = strip(srt);
|
||
|
var srt_ = srt.split('\n\n');
|
||
|
for(s in srt_) {
|
||
|
st = srt_[s].split('\n');
|
||
|
if(st.length >=2) {
|
||
|
var n = st[0];
|
||
|
var i = strip(st[1].split(' --> ')[0]);
|
||
|
var o = strip(st[1].split(' --> ')[1]);
|
||
|
var t = st[2];
|
||
|
if(st.length > 2) {
|
||
|
for(j=3; j<st.length;j++) {
|
||
|
t += '\n'+st[j];
|
||
|
}
|
||
|
}
|
||
|
var is = toSeconds(i);
|
||
|
var os = toSeconds(o);
|
||
|
spans[spans.length] = new Span(is, os, t, spans.length);
|
||
|
}
|
||
|
}
|
||
|
var out = '';
|
||
|
for (span in spans) {
|
||
|
if (spans.hasOwnProperty(span)) {
|
||
|
var sp = spans[span];
|
||
|
out += ms2npt(sp.tcInMs) + "\n";
|
||
|
out += sp.text;
|
||
|
out += "\n";
|
||
|
//If the outpoint of current span is equal to inpoint of next span, dont print out timecode, and just add the extra \n to go to next span.
|
||
|
if (span < spans.length - 1) {
|
||
|
var p = parseInt(span) + 1;
|
||
|
if (spans[p].tcInMs != sp.tcOutMs) {
|
||
|
out += ms2npt(sp.tcOutMs) + "\n\n";
|
||
|
} else {
|
||
|
out += "\n";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
this.elem.val(out);
|
||
|
}
|
||
|
|
||
|
function strip(s) {
|
||
|
return s.replace(/^\s+|\s+$/g,"");
|
||
|
}
|
||
|
|
||
|
function toSeconds(t) {
|
||
|
var s = 0.0;
|
||
|
if(t) {
|
||
|
var p = t.split(':');
|
||
|
for(i=0;i<p.length;i++) {
|
||
|
s = s * 60 + parseFloat(p[i].replace(',', '.'))
|
||
|
}
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
function spansToSrt(arr, fmt, start_no) {
|
||
|
if (typeof start_no == 'undefined') {
|
||
|
start_no = 1;
|
||
|
}
|
||
|
var srt = '';
|
||
|
var srtNo = start_no;
|
||
|
for (var k=0; k < arr.length; k++) {
|
||
|
var s = arr[k];
|
||
|
if (s.text.trim() == '') {
|
||
|
} else {
|
||
|
var text = s.text.trim();
|
||
|
linebreaksRegex = new RegExp('\n+', "g")
|
||
|
text = text.replace(linebreaksRegex, "\n");
|
||
|
if (!s.tcOutMs) {
|
||
|
s.tcOutMs = parseInt(Video.player.duration * 1000);
|
||
|
}
|
||
|
if (fmt == 'srt') {
|
||
|
srt += srtNo + " ";
|
||
|
srt += "\n";
|
||
|
srt += "0" + ms2npt(s.tcInMs).replace(".", ",") + " --> " + "0" + ms2npt(s.tcOutMs).replace(".", ",");
|
||
|
srt += "\n";
|
||
|
srt += text;
|
||
|
srt += "\n\n";
|
||
|
}
|
||
|
else if (fmt == 'enc') {
|
||
|
srt += srtNo + ms2frames(s.tcInMs) + " " + ms2frames(s.tcOutMs) + " " + text;
|
||
|
srt += "\n\n";
|
||
|
}
|
||
|
srtNo++;
|
||
|
}
|
||
|
}
|
||
|
return srt;
|
||
|
}
|
||
|
|
||
|
//returns textarea formatted to .srt
|
||
|
TextArea.prototype.toSrt = function(fmt) {
|
||
|
if (!fmt) var fmt = 'srt';
|
||
|
var text = this.elem.val();
|
||
|
var lines = [];
|
||
|
lines = text.split("\n");
|
||
|
var i=0;
|
||
|
var j=0;
|
||
|
spans = [];
|
||
|
while (i < lines.length) {
|
||
|
var l = lines[i];
|
||
|
if (isValidTimecode(l.trim())) {
|
||
|
var tcIn = l.trim();
|
||
|
var t = "";
|
||
|
var thisLine = '';
|
||
|
while (!isValidTimecode(thisLine.trim())) {
|
||
|
i++;
|
||
|
if (i >= lines.length) {
|
||
|
break;
|
||
|
}
|
||
|
thisLine = lines[i];
|
||
|
if (!isValidTimecode(thisLine.trim())) {
|
||
|
t += thisLine + "\n";
|
||
|
}
|
||
|
}
|
||
|
spans[j] = new Span(tcIn, thisLine, t, j);
|
||
|
j++;
|
||
|
} else {
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
var srt = spansToSrt(spans, fmt);
|
||
|
// console.log(srt);
|
||
|
return srt;
|
||
|
}
|
||
|
|
||
|
//Using spans as GLOBAL is ridiculous - please fix.
|
||
|
TextArea.prototype.addTime = function(ms, start_no) {
|
||
|
// console.log(ms);
|
||
|
if (typeof spans == 'undefined') {
|
||
|
this.toSrt();
|
||
|
}
|
||
|
var s = [];
|
||
|
for (var i=0; i<spans.length;i++) {
|
||
|
s[i] = {
|
||
|
index: i,
|
||
|
tcOutMs: spans[i].tcOutMs + ms,
|
||
|
text: spans[i].text,
|
||
|
tcInMs: spans[i].tcInMs + ms
|
||
|
}
|
||
|
}
|
||
|
return spansToSrt(s, 'srt', start_no)
|
||
|
}
|
||
|
|
||
|
//creates new Span (tcIn and tcOut in npt format)
|
||
|
var Span = function(tcIn, tcOut, text, index) {
|
||
|
this.index = index;
|
||
|
this.tcOutMs = npt2ms(tcOut);
|
||
|
this.text = text;
|
||
|
this.tcInMs = npt2ms(tcIn);
|
||
|
}
|
||
|
|
||
|
var SeekBar = function(elem) {
|
||
|
this.elem = $('#' + elem);
|
||
|
this.pointerId = "seekPointer";
|
||
|
this.width = this.elem.width();
|
||
|
this.init()
|
||
|
}
|
||
|
|
||
|
SeekBar.prototype.init = function() {
|
||
|
var that = this;
|
||
|
var e = $('<div />');
|
||
|
e.attr("id", that.pointerId);
|
||
|
e.draggable({
|
||
|
containment: 'parent',
|
||
|
axis: 'horizontally',
|
||
|
drag: function() {
|
||
|
clearInterval(videoListener);
|
||
|
var pos = that.get();
|
||
|
$('#timeCode').html(ms2npt(pos));
|
||
|
},
|
||
|
stop: function() {
|
||
|
var pos = that.get();
|
||
|
Video.set(pos);
|
||
|
videoListener = setInterval(Video.listener, 250);
|
||
|
}
|
||
|
});
|
||
|
that.elem.append(e);
|
||
|
this.pointerElem = e;
|
||
|
}
|
||
|
|
||
|
//gets current time-code (int) of seekbar position
|
||
|
SeekBar.prototype.get = function() {
|
||
|
var cssPos = parseInt(this.pointerElem.css("left"));
|
||
|
var pos = parseInt((cssPos / this.width) * (Video.player.duration * 1000));
|
||
|
return pos;
|
||
|
}
|
||
|
|
||
|
//sets seek bar css pos according to current time-code
|
||
|
SeekBar.prototype.set = function(ms) {
|
||
|
var cssPos = parseInt(((ms / 1000) / Video.player.duration) * this.width);
|
||
|
this.elem.css("left", cssPos + "px");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
var KeyboardController = function() {
|
||
|
this.
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
function loadSrt(filename) {
|
||
|
// alert("hmm.. you have a .srt file but not a txt file - this is a bug. sorry.");
|
||
|
var txt = mozillaLoadFile(filename);
|
||
|
textArea.fromSrt(txt);
|
||
|
}
|
||
|
|
||
|
function loadMeta(filename) {
|
||
|
var m = mozillaLoadFile(filename);
|
||
|
}
|
||
|
|
||
|
function loadSrtTxt(filename) {
|
||
|
var txt = mozillaLoadFile(filename);
|
||
|
$('#txt').val(txt);
|
||
|
}
|