使用JS将毫秒转换为SRT时间
Converting milliSeconds to SRT time using JS
我有这样的输入:
start: 0.21 | duration: 0.30 | text: Subtitle Text 1
start: 0.32 | duration: 0.52 | text: Subtitle Text 2
这个输入需要转换成SRT格式,所以变成这样:
1
00:00:00,210 --> 00:00:00,300
Subtitle Text 1
2
00:00:00,320 --> 00:00:00,520
Subtitle Text 2
JS:
function formatMilliseconds($milliseconds) {
$seconds = Math.floor($milliseconds / 1000);
$minutes = Math.floor($seconds / 60);
$hours = Math.floor($minutes / 60);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
console.log( $hours, $minutes, $seconds, $milliseconds); // 0 0 0 0.21
}
格式毫秒(0.21)
您可以通过使用 moment.js for date/time manipulations and sprintf 进行字符串格式化来实现此类转换
var data = 'start: 0.21 | duration: 0.30 | text: Subtitle Text 1' + '\n' +
'start: 0.32 | duration: 0.52 | text: Subtitle Text 2';
function formatSrt(data) {
var lines = data.split('\n');
var result = [];
var formatTime = function (value) {
if (typeof value === 'string') {
value = parseFloat(value);
if (isNaN(value)) {
throw new Exception('Invalid time "' + value + '"');
}
}
var d = moment.duration(value * 1000, 'ms');
return sprintf('%02d:%02d:%02d,%03d', d.get('h'), d.get('m'), d.get('s'), d.get('ms'));
}
lines.forEach(function (line, index) {
result.push(index + 1);
var parts = line.split('|');
var start = formatTime(parts.shift().split(':').pop().trim());
var end = formatTime(parts.shift().split(':').pop().trim());
var comment = parts.shift().split(':').pop().trim();
result.push(sprintf('%s --> %s', start, end));
result.push(comment);
result.push('');
})
return result.join('\n');
}
console.log(formatSrt(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.1/sprintf.min.js"></script>
这是我的尝试,可以改进但它正在工作。
可以在这里测试:https://jsfiddle.net/gugp6psb/5/
function toSrt(input) {
var srtOutput = '';
// Each line will contain the following input start: 0.21 | duration: 0.30 | text: Subtitle Text 1
var items = input.split('\n');
for(var i = 0; i < items.length; i++){
var item = items[i];
// Split each element using | as the separator
var inputElements = item.split("|");
// Remove unnecesary text, format numbers
var start = parseFloat(inputElements[0].replace('start:', '').replace(' ',''));
var duration = parseFloat(inputElements[1].replace('duration:', '').replace(' ',''));
var text = inputElements[2].replace('text:','');
var srt = (i + 1) + '\n';
srt += formatMilliseconds(start * 1000) + ' --> ' + formatMilliseconds(duration * 1000) + '\n';
srt += text;
if (i > 0)
srtOutput += '\n';
srtOutput += srt;
}
return srtOutput;
}
function formatMilliseconds(milliseconds) {
var seconds = Math.floor(milliseconds / 1000) % 60;
var minutes = Math.floor(seconds / 60) % 60;
var hours = Math.floor(minutes / 60);
var milliseconds = milliseconds % 1000;
return pad(hours) + ':' + pad(minutes) + ':' + pad(seconds) + ',' + pad(milliseconds);
}
function pad(n) {
return (n < 10) ? ("0" + n) : n;
}
首先,您需要将输入格式转换为可处理的格式,类似于
var subtitles = [
{
start: 0.21,
end: 0.3,
text: "Subtitle Text 1"
},
{
start: 0.32,
end: 0.52,
text: "Subtitle Text 2"
}
];
注意这里我选择的是"end"而不是"duration",因为"duration"在我眼里就是字幕结束+开始+时长(0.21+0.3=0.51)秒.
格式化函数几乎正确,但需要以毫秒而不是十进制秒值形式提供的输入值。对于输出,您还需要用零填充 hours/minuts/seconds。你最好为此使用一个辅助函数,你可以在其中指定目标字符串长度,但对于这个例子,我只是内联:
var subtitles = [
{
start: 0.21,
end: 0.3,
text: "Subtitle Text 1"
},
{
start: 0.32,
end: 0.52,
text: "Subtitle Text 2"
}
],
srtCount = 0;
function srtTimestamp(seconds) {
var $milliseconds = seconds*1000;
$seconds = Math.floor($milliseconds / 1000);
$minutes = Math.floor($seconds / 60);
$hours = Math.floor($minutes / 60);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
return ($hours < 10 ? '0' : '') + $hours + ':'
+ ($minutes < 10 ? '0' : '') + $minutes + ':'
+ ($seconds < 10 ? '0' : '') + $seconds + ','
+ ($milliseconds < 100 ? '0' : '') + ($milliseconds < 10 ? '0' : '') + $milliseconds;
}
function inputToSRT(sub_in) {
return ++srtCount + "\r\n" + srtTimestamp(sub_in.start) + " --> " + srtTimestamp(sub_in.end) + "\r\n" + sub_in.text + "\r\n\r\n";
}
for (var i=0; i<subtitles.length; i++) {
console.log(inputToSRT(subtitles[i]));
}
我有这样的输入:
start: 0.21 | duration: 0.30 | text: Subtitle Text 1
start: 0.32 | duration: 0.52 | text: Subtitle Text 2
这个输入需要转换成SRT格式,所以变成这样:
1
00:00:00,210 --> 00:00:00,300
Subtitle Text 1
2
00:00:00,320 --> 00:00:00,520
Subtitle Text 2
JS:
function formatMilliseconds($milliseconds) {
$seconds = Math.floor($milliseconds / 1000);
$minutes = Math.floor($seconds / 60);
$hours = Math.floor($minutes / 60);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
console.log( $hours, $minutes, $seconds, $milliseconds); // 0 0 0 0.21
}
格式毫秒(0.21)
您可以通过使用 moment.js for date/time manipulations and sprintf 进行字符串格式化来实现此类转换
var data = 'start: 0.21 | duration: 0.30 | text: Subtitle Text 1' + '\n' +
'start: 0.32 | duration: 0.52 | text: Subtitle Text 2';
function formatSrt(data) {
var lines = data.split('\n');
var result = [];
var formatTime = function (value) {
if (typeof value === 'string') {
value = parseFloat(value);
if (isNaN(value)) {
throw new Exception('Invalid time "' + value + '"');
}
}
var d = moment.duration(value * 1000, 'ms');
return sprintf('%02d:%02d:%02d,%03d', d.get('h'), d.get('m'), d.get('s'), d.get('ms'));
}
lines.forEach(function (line, index) {
result.push(index + 1);
var parts = line.split('|');
var start = formatTime(parts.shift().split(':').pop().trim());
var end = formatTime(parts.shift().split(':').pop().trim());
var comment = parts.shift().split(':').pop().trim();
result.push(sprintf('%s --> %s', start, end));
result.push(comment);
result.push('');
})
return result.join('\n');
}
console.log(formatSrt(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.1/sprintf.min.js"></script>
这是我的尝试,可以改进但它正在工作。
可以在这里测试:https://jsfiddle.net/gugp6psb/5/
function toSrt(input) {
var srtOutput = '';
// Each line will contain the following input start: 0.21 | duration: 0.30 | text: Subtitle Text 1
var items = input.split('\n');
for(var i = 0; i < items.length; i++){
var item = items[i];
// Split each element using | as the separator
var inputElements = item.split("|");
// Remove unnecesary text, format numbers
var start = parseFloat(inputElements[0].replace('start:', '').replace(' ',''));
var duration = parseFloat(inputElements[1].replace('duration:', '').replace(' ',''));
var text = inputElements[2].replace('text:','');
var srt = (i + 1) + '\n';
srt += formatMilliseconds(start * 1000) + ' --> ' + formatMilliseconds(duration * 1000) + '\n';
srt += text;
if (i > 0)
srtOutput += '\n';
srtOutput += srt;
}
return srtOutput;
}
function formatMilliseconds(milliseconds) {
var seconds = Math.floor(milliseconds / 1000) % 60;
var minutes = Math.floor(seconds / 60) % 60;
var hours = Math.floor(minutes / 60);
var milliseconds = milliseconds % 1000;
return pad(hours) + ':' + pad(minutes) + ':' + pad(seconds) + ',' + pad(milliseconds);
}
function pad(n) {
return (n < 10) ? ("0" + n) : n;
}
首先,您需要将输入格式转换为可处理的格式,类似于
var subtitles = [
{
start: 0.21,
end: 0.3,
text: "Subtitle Text 1"
},
{
start: 0.32,
end: 0.52,
text: "Subtitle Text 2"
}
];
注意这里我选择的是"end"而不是"duration",因为"duration"在我眼里就是字幕结束+开始+时长(0.21+0.3=0.51)秒.
格式化函数几乎正确,但需要以毫秒而不是十进制秒值形式提供的输入值。对于输出,您还需要用零填充 hours/minuts/seconds。你最好为此使用一个辅助函数,你可以在其中指定目标字符串长度,但对于这个例子,我只是内联:
var subtitles = [
{
start: 0.21,
end: 0.3,
text: "Subtitle Text 1"
},
{
start: 0.32,
end: 0.52,
text: "Subtitle Text 2"
}
],
srtCount = 0;
function srtTimestamp(seconds) {
var $milliseconds = seconds*1000;
$seconds = Math.floor($milliseconds / 1000);
$minutes = Math.floor($seconds / 60);
$hours = Math.floor($minutes / 60);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
return ($hours < 10 ? '0' : '') + $hours + ':'
+ ($minutes < 10 ? '0' : '') + $minutes + ':'
+ ($seconds < 10 ? '0' : '') + $seconds + ','
+ ($milliseconds < 100 ? '0' : '') + ($milliseconds < 10 ? '0' : '') + $milliseconds;
}
function inputToSRT(sub_in) {
return ++srtCount + "\r\n" + srtTimestamp(sub_in.start) + " --> " + srtTimestamp(sub_in.end) + "\r\n" + sub_in.text + "\r\n\r\n";
}
for (var i=0; i<subtitles.length; i++) {
console.log(inputToSRT(subtitles[i]));
}