toSrt, dblclick on time-code, etc.
This commit is contained in:
parent
e427bb8973
commit
0e151870d0
|
@ -1,10 +1,11 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="js/jquery.js"></script>
|
||||
<script type="text/javascript" src="oxjs/build/Ox.js"></script>
|
||||
<!-- <script type="text/javascript" src="js/jquery.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/classes.js"></script> -->
|
||||
<script type="text/javascript" src="js/staticfuncs.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
foo
|
||||
|
|
280
js/pandora-ui.js
Normal file
280
js/pandora-ui.js
Normal 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;
|
||||
}
|
|
@ -3,26 +3,57 @@
|
|||
'use strict';
|
||||
|
||||
(function() {
|
||||
$(function() {
|
||||
Ox.load({
|
||||
UI: {
|
||||
theme: 'modern' //FIXME: get theme through localStorage
|
||||
}
|
||||
}, loadSpeedtrans);
|
||||
});
|
||||
|
||||
Ox.load({
|
||||
UI: {
|
||||
theme: 'modern' //FIXME: get theme through localStorage
|
||||
}
|
||||
}, loadSpeedtrans);
|
||||
|
||||
function loadSpeedtrans(browserSupported) {
|
||||
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) {
|
||||
|
||||
pandora.$ui.appPanel = pandora.ui.appPanel().appendTo(pandora.$ui.body);
|
||||
pandora.resizeWindow();
|
||||
|
||||
}
|
||||
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
266
js/staticfuncs.js
Executable file
266
js/staticfuncs.js
Executable 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user