sanj
14 years ago
commit
510feb01d3
11 changed files with 5123 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||
content speedtrans chrome/content/ |
|||
overlay chrome://browser/content/browser.xul chrome://speedtrans/content/menu.xul |
|||
|
|||
|
@ -0,0 +1,307 @@ |
|||
//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); |
|||
} |
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
@ -0,0 +1,21 @@ |
|||
var padma={ |
|||
openAnnot:function() |
|||
{ |
|||
window.open("chrome://speedtrans/content/transcribe.html"); |
|||
/* |
|||
window.open("chrome://speedtrans/content/transcribe.html", |
|||
"annot", "chrome,centerscreen,resizable=yes,toolbar=no,menubar=no"); |
|||
*/ |
|||
} |
|||
} |
|||
|
|||
function getMainWindow() { |
|||
return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|||
.getInterface(Components.interfaces.nsIWebNavigation) |
|||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem) |
|||
.rootTreeItem |
|||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|||
.getInterface(Components.interfaces.nsIDOMWindow); |
|||
} |
|||
|
|||
|
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0"?> |
|||
<overlay id="annot" |
|||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
|||
|
|||
<script type="application/x-javascript" |
|||
src="chrome://speedtrans/content/menu.js" /> |
|||
|
|||
<menupopup id="menu_ToolsPopup"> |
|||
<menuitem id="annot_menu" image="chrome://speedtrans/content/icon.png" |
|||
class="menuitem-iconic" |
|||
insertafter="javascriptConsole,devToolsSeparator" |
|||
label="Pad.ma Transcription Client" |
|||
oncommand="padma.openAnnot();"/> |
|||
</menupopup> |
|||
</overlay> |
@ -0,0 +1,116 @@ |
|||
function Player() { |
|||
this.supportsOverlay = false; |
|||
this.muted = false; |
|||
} |
|||
Player.prototype.init = function(elemID) { |
|||
//make overlay settings happy..., add a dummy element
|
|||
this.player = document.getElementById(elemID); |
|||
} |
|||
Player.prototype.play = function() { } |
|||
Player.prototype.pause = function() { } |
|||
Player.prototype.get = function() { } |
|||
Player.prototype.listener = function() { } |
|||
Player.prototype.set = function(pos) { } |
|||
Player.prototype.mute = function(pos) { } |
|||
|
|||
Player.prototype.seekFwd = function(ms) { |
|||
var currentMs = this.get(); |
|||
var newMs = currentMs + ms; |
|||
this.set(newMs); |
|||
} |
|||
|
|||
Player.prototype.seekBack = function(ms) { |
|||
var currentMs = this.get(); |
|||
var newMs = currentMs - ms; |
|||
this.set(newMs); |
|||
} |
|||
|
|||
Player.prototype.unmute = function(pos) { } |
|||
/* Player.prototype.url = function(pos) { |
|||
var timecode = pos2npt(pos); |
|||
var link = video.url; |
|||
if(pos > 0) |
|||
link += "?t=npt:" + timecode; |
|||
return link; |
|||
}; |
|||
*/ |
|||
|
|||
function VideoPlayer() { |
|||
this.supportsOverlay = true; |
|||
this.isPlaying = false; |
|||
} |
|||
|
|||
VideoPlayer.prototype = new Player(); |
|||
VideoPlayer.prototype.init = function(elemID) { |
|||
this.player = document.getElementById(elemID); |
|||
this.width = $(this.player).attr('width'); |
|||
this.height = $(this.player).attr('height'); |
|||
} |
|||
|
|||
VideoPlayer.prototype.set = function(pos) { |
|||
/* var url = this.url(pos); |
|||
var autoplay = 'true'; |
|||
if(this.isPlaying) |
|||
varautoplay = 'true'; |
|||
if(this.player) { |
|||
var element = $(this.player); |
|||
this.player.pause(); |
|||
} else { |
|||
var element = $('#' + playerID); |
|||
} |
|||
this.player = document.createElement('video'); |
|||
this.player.id = playerID; |
|||
this.player.width = this.width; |
|||
this.player.height = this.height; |
|||
this.player.setAttribute('src', url); |
|||
//this.player.setAttribute('autoplay', autoplay);
|
|||
element.replaceWith(this.player); */ |
|||
this.player.currentTime = pos / 1000; |
|||
} |
|||
|
|||
|
|||
VideoPlayer.prototype.get = function() { |
|||
try { |
|||
return parseInt(this.player.currentTime * 1000); |
|||
} catch(err) { } |
|||
return -1; |
|||
} |
|||
|
|||
VideoPlayer.prototype.play = function() { |
|||
this.isPlaying = true; |
|||
this.player.play(); |
|||
} |
|||
|
|||
VideoPlayer.prototype.pause = function() { |
|||
this.isPlaying = false; |
|||
this.player.pause(); |
|||
} |
|||
|
|||
VideoPlayer.prototype.mute = function(pos) { |
|||
this.player.muted = true; |
|||
this.muted = true; |
|||
} |
|||
|
|||
VideoPlayer.prototype.unmute = function(pos) { |
|||
this.player.muted = false; |
|||
this.muted = false; |
|||
} |
|||
|
|||
VideoPlayer.prototype.togglePause = function() { |
|||
if (Video.isPlaying == true) { |
|||
Video.pause(); |
|||
} else { |
|||
Video.play(); |
|||
} |
|||
} |
|||
VideoPlayer.prototype.listener = function() { |
|||
var ms = Video.get(); |
|||
var npt = ms2npt(ms); |
|||
$('#timeCode').html(npt); |
|||
var seekBarPos = parseInt((ms / (Video.duration * 1000)) * 320); |
|||
$('#seekPointer').css("left", seekBarPos + "px"); |
|||
} |
|||
|
|||
VideoPlayer.prototype.setDuration = function(duration) { |
|||
this.duration = duration; |
|||
} |
@ -0,0 +1,184 @@ |
|||
function npt2ms(npt) { |
|||
var ms = 0.0 |
|||
npt = String(npt); |
|||
var p = npt.split(':') |
|||
for(i=0;i<p.length;i++) |
|||
ms = ms * 60 + parseFloat(p[i]) |
|||
return ms * 1000; |
|||
} |
|||
|
|||
function ms2npt(ms) { |
|||
var it, ss, mm, hh, npt; |
|||
var it = parseInt(ms / 1000) |
|||
ms = ms - it * 1000; |
|||
if (ms.toString().length > 3) { |
|||
ms = ms.toString().substring(0,3); |
|||
} |
|||
ss = it % 60; |
|||
mm = ((it - ss) / 60) % 60; |
|||
hh = ((it - (mm * 60) - ss) / 3600) % 60; |
|||
npt = hh+':'+strpad(mm.toString(), '0', 2, 'left') |
|||
npt += ':'+strpad(ss.toString(), '0', 2, 'left') |
|||
npt += '.'+strpad(ms.toString(), '0', 3, 'left') |
|||
return npt; |
|||
} |
|||
|
|||
function ms2frames(ms, fmt) { |
|||
if (!fmt) var fmt = "PAL"; |
|||
var npt = ms2npt(ms); |
|||
var dotpos = npt.lastIndexOf("."); |
|||
var mmStr = npt.substring(dotpos + 1, npt.length); |
|||
var mmInt = parseInt(mmStr); |
|||
if (fmt == 'PAL') { |
|||
var frames = parseInt((mmInt / 1000) * 24); |
|||
} else if (fmt == "NTSC") { |
|||
var frames = parseInt((mmInt / 1000) * 29.97); |
|||
} |
|||
var framesTc = ''; |
|||
var joinToken = ":"; |
|||
var framesTc = npt.substring(0, dotpos ) + joinToken + frames; |
|||
return framesTc; |
|||
} |
|||
|
|||
function ms2time(ms) { |
|||
var npt = ms2npt(ms) |
|||
return npt.substr(npt.length-9, npt.length-6); |
|||
} |
|||
|
|||
function framesToNpt(timeCode) { |
|||
var frames = timeCode.substring(9, 11); |
|||
var ms = parseInt(frames) / 25 * 1000; |
|||
var ms = String(ms); |
|||
var ms = strpad(ms, '0', 3, 'right'); |
|||
var timeCodeNpt = timeCode.substring(0,8) + "." + ms; |
|||
return timeCodeNpt; |
|||
} |
|||
|
|||
|
|||
function strpad(str, pad, len, dir) { |
|||
while (str.length < len) { |
|||
if (dir == 'left') |
|||
str = pad + str; |
|||
else if (dir == 'right') |
|||
str = str + pad; |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
function isValidTimecode(tc) { |
|||
var tc = $.trim(tc); |
|||
var nptRegex = new RegExp("^[0-9][0-9]?\:[0-9][0-9]\:[0-9][0-9][\.|\,|\:][0-9]?[0-9]?[0-9]?$"); |
|||
return nptRegex.test(tc); |
|||
} |
|||
|
|||
function selectFile() { |
|||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|||
const nsIFilePicker = Components.interfaces.nsIFilePicker; |
|||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); |
|||
fp.init(window, "Choose a File", nsIFilePicker.modeOpen); |
|||
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText); |
|||
fp.appendFilters("Video Files", "*.ogg;*.ogv;*.ogx;*.dv;*.avi;*.mov"); |
|||
var rv = fp.show(); |
|||
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { |
|||
var file = fp.file; |
|||
var path = fp.file.path; |
|||
return path; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
|
|||
function mozillaSaveFile(filePath,content) |
|||
{ |
|||
if(window.Components) { |
|||
try { |
|||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); |
|||
file.initWithPath(filePath); |
|||
if(!file.exists()) |
|||
file.create(0,0664); |
|||
var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); |
|||
var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); |
|||
out.init(file,0x20|0x02,00004,null); |
|||
os.init(out, "UTF-8", 0, 0x0000); |
|||
os.writeString(content); |
|||
//out.write(content,content.length);
|
|||
os.close(); |
|||
//out.flush();
|
|||
out.close(); |
|||
return true; |
|||
} catch(ex) { |
|||
alert(ex); |
|||
return false; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
|||
function mozillaLoadFile(filePath) |
|||
{ |
|||
if(window.Components) { |
|||
try { |
|||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); |
|||
file.initWithPath(filePath); |
|||
if(!file.exists()) |
|||
return null; |
|||
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream); |
|||
inputStream.init(file,0x01,00004,null); |
|||
//var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
|
|||
//sInputStream.init(inputStream);
|
|||
var charset = "UTF-8"; |
|||
const replacementChar = Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER; |
|||
var cInputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"] |
|||
.createInstance(Components.interfaces.nsIConverterInputStream); |
|||
cInputStream.init(inputStream, charset, 1024, replacementChar); |
|||
var str = {}; |
|||
var contents = ''; |
|||
while (cInputStream.readString(4096, str) != 0) { |
|||
contents += str.value; |
|||
} |
|||
|
|||
//var contents = sInputStream.read(sInputStream.available());
|
|||
cInputStream.close(); |
|||
//sInputStream.close();
|
|||
inputStream.close(); |
|||
return contents; |
|||
} catch(ex) { |
|||
alert(ex); |
|||
return false; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
|
|||
function checkFileExists(filePath) { |
|||
if(window.Components) { |
|||
try { |
|||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
|||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); |
|||
file.initWithPath(filePath); |
|||
if (file.exists()) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} catch(ex) { |
|||
//alert("Error");
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function getFileNameSansExt(filename) { |
|||
var dotPos = filename.lastIndexOf("."); |
|||
if (dotPos != '-1') { |
|||
var filenameSansExt = filename.substring(0,dotPos); |
|||
} else { |
|||
var filenameSansExt = filename; |
|||
} |
|||
return filenameSansExt; |
|||
} |
|||
|
@ -0,0 +1,126 @@ |
|||
body { |
|||
background: #000; |
|||
color: #fff; |
|||
} |
|||
|
|||
#additionalFeatures { |
|||
display: none; |
|||
} |
|||
|
|||
#wrapper { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
#videoWrapper { |
|||
float: left; |
|||
width: 400px; |
|||
height: 100%; |
|||
} |
|||
|
|||
#selectFileDiv { |
|||
text-align: center; |
|||
} |
|||
|
|||
#helpWrapper { |
|||
-moz-border-radius: 8px; |
|||
font-size: 13px; |
|||
color: #000; |
|||
border: 2px solid #999; |
|||
background: #ccc; |
|||
padding: 4px; |
|||
margin-top: 8px; |
|||
} |
|||
|
|||
#video { |
|||
height: 300px; |
|||
width: 400px; |
|||
} |
|||
|
|||
#txtWrapper { |
|||
width: 50%; |
|||
margin-left: 20px; |
|||
float: left; |
|||
} |
|||
|
|||
#buttonsWrapper { |
|||
text-align: center; |
|||
} |
|||
|
|||
#eventMetadata { |
|||
display: none; |
|||
margin-left: 20px; |
|||
float: left; |
|||
width: 50%; |
|||
} |
|||
|
|||
input.eventMeta, textarea.eventMeta { |
|||
padding: 5px; |
|||
margin: 3px; |
|||
width: 250px; |
|||
} |
|||
|
|||
#seekTime { |
|||
width: 20px; |
|||
} |
|||
|
|||
#dateYear { |
|||
width: 30px; |
|||
} |
|||
|
|||
#dateMonth { |
|||
width: 25px; |
|||
} |
|||
|
|||
#dateDay { |
|||
width: 25px; |
|||
} |
|||
|
|||
#description { |
|||
width: 80%; |
|||
height: 100px; |
|||
} |
|||
|
|||
.button { |
|||
padding: 8px; |
|||
margin-left: 10px; |
|||
cursor: pointer; |
|||
font-size: 15px; |
|||
background: #ccc; |
|||
-moz-border-radius: 5px; |
|||
border: 2px solid #000; |
|||
color: #f33; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
#txt { |
|||
height: 500px; |
|||
width: 100%; |
|||
} |
|||
|
|||
#seekBar { |
|||
height: 16px; |
|||
width: 320px; |
|||
margin-left: 40px; |
|||
background: #666; |
|||
opacity: 0.7; |
|||
z-index: 100; |
|||
} |
|||
|
|||
#seekPointer { |
|||
height: 12px; |
|||
width: 10px; |
|||
position: relative; |
|||
margin-top: 2px; |
|||
margin-bottom: 2px; |
|||
-moz-border-radius: 10px; |
|||
background: #f00; |
|||
} |
|||
|
|||
#timeCode { |
|||
color: #f00; |
|||
font-size: 12px; |
|||
font-weight: bold; |
|||
text-align: center; |
|||
} |
|||
|
@ -0,0 +1,216 @@ |
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|||
<html xmlns="http://www.w3.org/1999/xhtml"> |
|||
<head> |
|||
<title> |
|||
Pad.ma: Subtitle n more... |
|||
</title> |
|||
<script type="text/javascript" src="jquery.js"></script> |
|||
<script type="text/javascript" src="player.js"></script> |
|||
<script type="text/javascript" src="jquery-ui.js"></script> |
|||
<script type="text/javascript" src="staticfuncs.js"></script> |
|||
<script type="text/javascript" src="classes.js"></script> |
|||
<link rel="stylesheet" href="styles.css" /> |
|||
<script type="text/javascript"> |
|||
//init globals |
|||
var seekBar; |
|||
var textArea; |
|||
var Video; |
|||
var filePath = false; |
|||
var spans; |
|||
var videoListener; |
|||
|
|||
$(document).ready(function() { |
|||
textArea = new TextArea("txt"); |
|||
$('#saveFile').click(saveFile); |
|||
$('#saveSrt').click(saveSrt); |
|||
$('#addTime').click(function() { |
|||
var timeToAdd = npt2ms($.trim($('#timeToAdd').val())); |
|||
var startNo = parseInt($('#startNo').val()); |
|||
var r = textArea.addTime(timeToAdd, startNo); |
|||
$('#addTimeResult').val(r); |
|||
}); |
|||
$('#showMore').toggle(function() { |
|||
$(this).text("Show Less Features"); |
|||
$('#additionalFeatures').show("fast"); |
|||
}, function() { |
|||
$(this).text("Show More Features"); |
|||
$('#additionalFeatures').hide("fast"); |
|||
}); |
|||
$('#saveEncore').click(saveEncore); |
|||
$('#selectFile').click(function() { |
|||
var videoFile = selectFile(); |
|||
alert(videoFile); |
|||
filePath = getFileNameSansExt(videoFile); |
|||
var srtTxtFilename = filePath + ".srt.txt"; |
|||
var srtFilename = filePath + ".srt"; |
|||
var metaFilename = filePath + ".txt"; |
|||
if (checkFileExists(srtTxtFilename)) { |
|||
loadSrtTxt(srtTxtFilename); |
|||
} else if (checkFileExists(srtFilename)) { |
|||
loadSrt(srtFilename); |
|||
} |
|||
if (checkFileExists(metaFilename)) { |
|||
loadMeta(metaFilename); |
|||
} |
|||
$('#video').attr("src", "file://" + videoFile); |
|||
document.getElementById("video").load(); |
|||
$('#video').one("loadedmetadata", function() { |
|||
$('#selectFileDiv').fadeOut(); |
|||
Video = new VideoPlayer(); |
|||
Video.init("video"); |
|||
// |
|||
// seekBar = new SeekBar("seekBar"); |
|||
Video.setDuration(Video.player.duration); |
|||
$('#insertTc').click(textArea.insertTc); |
|||
/* $('#video').click(function() { |
|||
Video.togglePause(); |
|||
}); |
|||
*/ |
|||
$('#video').dblclick(function() { |
|||
textArea.insertTc(); |
|||
}); |
|||
videoListener = setInterval(Video.listener, 250); |
|||
}); |
|||
}); |
|||
|
|||
$(document).keyup(function(e) { |
|||
//Esc |
|||
if (e.keyCode == 27 && textArea.hasFocus) { |
|||
Video.togglePause(); |
|||
} |
|||
//Ins |
|||
if (e.keyCode == 45) { |
|||
if (!textArea.isTc()) { |
|||
textArea.insertTc(); |
|||
} |
|||
} |
|||
//Ctrl - Seek Back |
|||
if (e.keyCode == 17) { |
|||
var seekTime = parseInt(parseFloat($('#seekTime').val()) * 1000); |
|||
var currTime = Video.get(); |
|||
var newTime = currTime - seekTime; |
|||
Video.set(newTime); |
|||
} |
|||
//Alt - Seek Fwd. |
|||
if (e.keyCode == 18) { |
|||
var seekTime = parseInt(parseFloat($('#seekTime').val()) * 1000); |
|||
var currTime = Video.get(); |
|||
var newTime = currTime + seekTime; |
|||
Video.set(newTime); |
|||
} |
|||
|
|||
//Space - togglePause if no focus on TA |
|||
if (e.keyCode == 32 && textArea.hasFocus == false) { |
|||
Video.togglePause(); |
|||
} |
|||
}); |
|||
$('#fillMeta').click(function() { |
|||
$('#txtWrapper').hide(); |
|||
$('#eventMetadata').show(); |
|||
}); |
|||
$('#doneMetadata').click(function() { |
|||
$('#eventMetadata').hide(); |
|||
$('#txtWrapper').show(); |
|||
}); |
|||
$('.eventMeta').each(function() { |
|||
var defVal = $(this).attr('data-default'); |
|||
$(this).val(defVal); |
|||
$(this).focus(function() { |
|||
if ($(this).val() == $(this).attr("data-default")) { |
|||
$(this).val(''); |
|||
} |
|||
}).blur(function() { |
|||
if ($(this).val() == '') { |
|||
$(this).val($(this).attr('data-default')); |
|||
} |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
function saveFile() { |
|||
var savePath = filePath + ".srt.txt"; |
|||
var content = $('#txt').val(); |
|||
if (mozillaSaveFile(savePath, content)) { |
|||
alert("saved file at " + savePath); |
|||
} else { |
|||
alert("error saving file"); |
|||
} |
|||
} |
|||
|
|||
function saveSrt() { |
|||
var srtPath = filePath + ".srt"; |
|||
var content = textArea.toSrt(); |
|||
if (mozillaSaveFile(srtPath, content)) { |
|||
alert("export .srt file to " + srtPath); |
|||
} else { |
|||
alert("error exporting srt"); |
|||
} |
|||
} |
|||
|
|||
function saveEncore() { |
|||
var encPath = filePath + ".enc.txt"; |
|||
var content = textArea.toSrt("enc"); |
|||
if (mozillaSaveFile(encPath, content)) { |
|||
alert("saved encore compatible subtitle file at " + encPath); |
|||
} else { |
|||
alert("error creating encore compatible subtitle file"); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
</head> |
|||
<body> |
|||
<div id="wrapper"> |
|||
<div id="videoWrapper"> |
|||
<div id="selectFileDiv"> |
|||
<button id="selectFile">Select File</button> |
|||
</div> |
|||
<video id="video" src="" controls="true"> |
|||
Sorry you need <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5 Beta</a> for this to work. |
|||
</video> |
|||
<div id="seekBar"> |
|||
|
|||
</div> |
|||
<div id="timeCode">0:00:00.000</div> |
|||
<div id="helpWrapper"> |
|||
Shortcuts: <br /><br /> |
|||
Esc: Pause / Unpause <br /> |
|||
Insert: Insert time-code<br /> |
|||
Double-click in Textarea: insert time-code <br /> |
|||
Double-click on video: insert time-code<br /> |
|||
Double-click on time-code in textarea: Seek video to time-code. <br /> |
|||
Ctrl / Alt: Seek back / forward <input id="seekTime" value="1" /> seconds. |
|||
</div> |
|||
|
|||
</div> |
|||
<div id="txtWrapper"> |
|||
<textarea id="txt"></textarea><br /> <br /> |
|||
<div id="buttonsWrapper"> |
|||
<!-- <button id="fillMeta" class="button">Enter Metadata</button> --> |
|||
<button id="saveFile" class="button">Save File</button> |
|||
<button id="saveSrt" class="button">Export SRT</button> |
|||
<button id="saveEncore" class="button">Export to Encore</button> |
|||
<button id="showMore" class="button">Show More Features</button> |
|||
</div> |
|||
<div id="additionalFeatures"> |
|||
<div id="addTimeWrap"> |
|||
Time to add: <input id="timeToAdd" /><br /> |
|||
Start no: <input id="startNo" /> <button id="addTime">Add</button><br /> |
|||
<textarea id="addTimeResult"></textarea> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div id="eventMetadata"> |
|||
<input id="title" data-default="Title" class="eventMeta" /><br /> |
|||
<input id="director" data-default="Director" class="eventMeta" /><br /> |
|||
<input id="collection" data-default="Collection" class="eventMeta" /><br /> |
|||
<input id="source" data-default="Source" class="eventMeta" /><br /> |
|||
<textarea id="description" data-default="Event Description" class="eventMeta"></textarea><br /> |
|||
Date: <input id="dateYear" data-default="YYYY" class="eventMeta" /> <input id="dateMonth" data-default="MM" class="eventMeta" /> <input id="dateDay" data-default="DD" class="eventMeta" /><br /> |
|||
Logged by: <input id="loggedBy" data-default="Your name" class="eventMeta" /><br /><br /> |
|||
<button id="doneMetadata" class="button">Done Adding Metadata</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -0,0 +1,29 @@ |
|||
<?xml version="1.0"?> |
|||
|
|||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|||
xmlns:em="http://www.mozilla.org/2004/em-rdf#"> |
|||
|
|||
<Description about="urn:mozilla:install-manifest"> |
|||
<em:id>b@pad.ma</em:id> |
|||
<em:version>0.2</em:version> |
|||
<em:type>2</em:type> |
|||
|
|||
<!-- Target Application this extension can install into, |
|||
with minimum and maximum supported versions. --> |
|||
<em:targetApplication> |
|||
<Description> |
|||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> |
|||
<em:minVersion>1.5</em:minVersion> |
|||
<em:maxVersion>3.9</em:maxVersion> |
|||
</Description> |
|||
</em:targetApplication> |
|||
<!-- Front End MetaData --> |
|||
<em:name>pad.ma transcription client</em:name> |
|||
<em:description>pad.ma offline transcription client</em:description> |
|||
<em:creator>pad.ma</em:creator> |
|||
<em:updateURL>http://files.pad.ma/annot/update.rdf</em:updateURL> |
|||
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcI+EIEmZ2UMEMzksirJQ6rbRZebeQzM9LCf9i7EZny5umQOF+92G+DxlKrk1BC+B1ZhXHMZNBRWEhn9kuW8mgXL1JBKVPbg4RjbJ39XigtXL5wNWU6EVdUvzFH1D49HwGpDRWJhnlUTMFhJL2FW47Qg1yCttQSEYmmSum3Y77rwIDAQAB</em:updateKey> |
|||
<em:homepageURL>http://wiki.pad.ma/wiki/Annot</em:homepageURL> |
|||
<em:iconURL>chrome://annot/content/icon.png</em:iconURL> |
|||
</Description> |
|||
</RDF> |
Loading…
Reference in new issue