toSrt, dblclick on time-code, etc.

This commit is contained in:
Sanj 2011-12-30 04:31:23 +05:30
parent e427bb8973
commit 0e151870d0
4 changed files with 590 additions and 12 deletions

View File

@ -1,10 +1,11 @@
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<script type="text/javascript" src="js/jquery.js"></script> <!-- <script type="text/javascript" src="js/jquery.js"></script> -->
<script type="text/javascript" src="oxjs/build/Ox.js"></script> <script type="text/javascript" src="../oxjs/dev/Ox.js"></script>
<script type="text/javascript" src="js/speedtrans.js"></script> <script type="text/javascript" src="js/speedtrans.js"></script>
<!-- <script type="text/javascript" src="js/classes.js"></script> -->
<script type="text/javascript" src="js/staticfuncs.js"></script>
</head> </head>
<body> <body>
foo foo

280
js/pandora-ui.js Normal file
View File

@ -0,0 +1,280 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript
"use strict";
pandora.ui.appPanel = function() {
var that = Ox.SplitPanel({
elements: [
{
element: pandora.$ui.mainMenu = pandora.ui.mainMenu(),
size: 20
},
{
element: pandora.$ui.mainPanel = pandora.ui.mainPanel()
}
],
orientation: 'vertical'
});
return that;
}
pandora.ui.mainMenu = function() {
var that = Ox.MainMenu({
extras: [],
id: 'mainMenu',
menus: [
{
'id': 'speedtransMenu',
'title': 'Speedtrans',
'items': [
{ id: 'TestMenu1', title: 'Test Menu Item'},
{ id: 'TestMenu2', title: 'Test Menu Itemm'}
]
},
{
'id': 'fileMenu',
'title': 'File',
'items': [
{ id: 'openFileMenu', title: 'Open File'},
{ id: 'saveFileMenu', title: 'Save File', keyboard: 'shift control s'}
]
}
]
})
.bindKeyboard()
.bindEvent({
click: function(data) {
// Ox.print(data);
var selected = data.id;
if (data.id == 'saveFileMenu') {
pandora.$ui.textArea.speedtrans.save();
// speedtrans.saveFile();
} else if (data.id == 'openFileMenu') {
pandora.$ui.textArea.speedtrans.load("/A/480p.webm");
}
},
key_control_shift_s: function() {
pandora.$ui.textArea.speedtrans.save();
}
});
return that;
}
pandora.ui.mainPanel = function() {
var that = Ox.SplitPanel({
elements: [
{
element: pandora.$ui.videoPanel = pandora.ui.videoPanel(),
size: 400,
resizable: true,
resize: [0,600]
},
{
element: pandora.$ui.textPanel = pandora.ui.textPanel()
}
],
orientation: 'horizontal'
});
return that;
}
pandora.ui.videoPanel = function() {
var that = Ox.SplitPanel({
elements: [
{
element: pandora.$ui.videoPlayer = pandora.ui.videoPlayer(),
size: 300
},
{
element: pandora.$ui.helpPanel = pandora.ui.helpPanel()
}
],
orientation: 'vertical'
});
return that;
}
pandora.ui.videoPlayer = function() {
var that = Ox.VideoPlayer({
video: '/A/480p.webm',
controlsTop: ['play', 'fullscreen', 'scale', 'position'],
controlsBottom: ['timeline'],
height: 300,
width: 400,
showControlsOnLoad: true,
duration: 35,
timeline: '/speedtrans/img/timeline16p.png',
title: 'Test Video',
enableTimeline: true,
enableKeyboard: true,
enableMouse: true,
externalControls: true
// enableTimeline: true
});
return that;
}
pandora.ui.helpPanel = function() {
var that = $('<div>').text("Help Panel");
return that;
}
pandora.ui.textPanel = function() {
var that = Ox.SplitPanel({
elements: [
{
element: pandora.$ui.textArea = pandora.ui.textArea()
},
{
element: pandora.$ui.textToolBar = pandora.ui.textToolBar(),
size: 20
}
],
orientation: 'vertical'
});
return that;
}
pandora.ui.textArea = function() {
var that = Ox.Input({
type: 'textarea',
width: 400,
height: 400,
changeOnKeypress: true
});
var $video = pandora.$ui.videoPlayer;
that.speedtrans = {
spans: [],
insertTc: function() {
var eDom = that.find("textarea").get(0); //FIXME
var scrollTop = eDom.scrollTop;
var val = that.value();
var pos = eDom.selectionStart;
var tcNpt = ms2npt($video.options("position") * 1000);
var newVal = val.substring(0,pos) + "\n" + tcNpt + "\n" + val.substring(pos, val.length);
that.value(newVal);
that.find("textarea").focus(); //FIXME
eDom.selectionStart = pos + tcNpt.length + 2;
eDom.selectionEnd = pos + tcNpt.length + 2;
eDom.scrollTop = scrollTop + 15;
},
isTc: function() {
var eDom = that.find("textarea").get(0);
var val = that.value();
var pos = eDom.selectionStart;
var word = that.speedtrans.getWord(pos, val);
if (isValidTimecode(word)) {
return npt2ms(word);
} else {
return false;
}
},
getWord: function(pos, 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;
},
toSrt: function(fmt) {
if (!fmt) var fmt = 'srt';
var text = cleanNewlines(that.value());
var lines = [];
lines = text.split("\n");
var i=0;
var j=0;
var spans = this.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";
}
}
var tcOut = $.trim(thisLine);
spans[j] = {
tcInMs: npt2ms(tcIn),
tcOutMs: npt2ms(tcOut),
text: t,
index: j
};
//this.spans.push(spans[j]);
j++;
} else {
i++;
}
}
this.spans = spans;
var duration = $video.options("duration");
var srt = spansToSrt(duration, spans, fmt);
// console.log(srt);
return srt;
},
save: function() {
var filename = $video.options("video");
localStorage[filename] = that.value();
},
load: function(filename) {
var val = localStorage[filename] || '';
that.value(val);
}
};
that.bindEvent({
key_control_space: function() {
$video.options("paused", !$video.options("paused"));
that.find("textarea").focus(); //FIXME
},
key_control_x: function() {
that.speedtrans.insertTc();
},
key_control_shift_s: function() {
that.speedtrans.save();
}
});
that.dblclick(function() {
var tc = that.speedtrans.isTc();
if (tc) {
$video.options("position", tc / 1000);
}
});
return that;
}
pandora.ui.textToolBar = function() {
var that = Ox.Bar();
return that;
}

View File

@ -3,26 +3,57 @@
'use strict'; 'use strict';
(function() { (function() {
$(function() {
Ox.load({ Ox.load({
UI: { UI: {
theme: 'modern' //FIXME: get theme through localStorage theme: 'modern' //FIXME: get theme through localStorage
} }
}, loadSpeedtrans); }, loadSpeedtrans);
});
function loadSpeedtrans(browserSupported) { function loadSpeedtrans(browserSupported) {
if (!browserSupported) { alert("your browser is not supported"); return; } if (!browserSupported) { alert("your browser is not supported"); return; }
initSpeedtrans(); //FIXME: actually call as Ox.App callback window.pandora = Ox.App({url: '/api/'}).bindEvent({
'load': function(data) {
// console.log(data);
Ox.extend(pandora, {
$ui: {
body: $('body'),
document: $(document),
window: $(window).resize(function() {
pandora.resizeWindow();
})
},
ui: {},
site: {},
user: {}
});
pandora.resizeWindow = function() {
pandora.$ui.textArea.options({
'width': pandora.$ui.textPanel.width() - 20,
'height': pandora.$ui.textPanel.height() - 40
});
}
var prefix = "/speedtrans/js/";
Ox.loadFile(prefix + "pandora-ui.js", function() {
initSpeedtrans(data);
});
}
});
} }
function initSpeedtrans(data) { function initSpeedtrans(data) {
pandora.$ui.appPanel = pandora.ui.appPanel().appendTo(pandora.$ui.body);
pandora.resizeWindow();
} }
})(); })();

266
js/staticfuncs.js Executable file
View File

@ -0,0 +1,266 @@
function npt2ms(npt) {
var ms = 0.0;
npt = String(npt);
var p = npt.split(':');
for(var i=0;i<p.length;i++)
ms = (ms * 60) + parseFloat(p[i]);
// alert(ms);
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);to
}
//where filters is a JSON object, for eg. {'Video Files': '*.dv;*.ogg;*.ogv;*.ogx;*.avi;*.mov;*.mp4;*.mpeg;*.mpg;*.vob'}
function selectFile(filters) {
// 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.appendFilter("Ogg Video Files", "*.ogg;*.ogv;*.ogx;");
for (var f in filters) {
if (filters.hasOwnProperty(f)) {
fp.appendFilter(f, filters[f]);
}
}
// fp.appendFilter("All Video Files", "*.dv;*.ogg;*.ogv;*.ogx;*.avi;*.mov;*.mp4;*.mpeg;*.mpg;*.vob");
fp.appendFilters(nsIFilePicker.filterAll);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
return fp;
/*
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;
}
function mozillaSaveAs() {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
fp.init(window, "Save srt as...", Components.interfaces.nsIFilePicker.modeSave);
fp.appendFilters(Components.interfaces.nsIFilePicker.filterAll);
var output = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
var pth = typeof(srtFilePath) != 'undefined' ? srtFilePath : filePath + ".srt";
output.initWithPath(pth);
fp.defaultString = output.leafName;
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
return fp.file.path;
/*
var file = fp.file;
srtFilePath = file.path;
saveSrt(srtFilePath);
return true;
*/
}
return false;
}
// 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 getFileNameExt(filename) {
var dotPos = filename.lastIndexOf(".");
var ext = filename.substring(dotPos + 1, filename.length);
return ext;
}
function getFileNameSansExt(filename) {
var dotPos = filename.lastIndexOf(".");
if (dotPos != '-1') {
var filenameSansExt = filename.substring(0,dotPos);
} else {
var filenameSansExt = filename;
}
return filenameSansExt;
}
function spansToSrt(duration, 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(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;
}
function cleanNewlines(str) {
var s = str.replace(/\r\n|\r|\n/g, '\n');
return s;
}