最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Converting milliSeconds to SRT time using JS - Stack Overflow

programmeradmin2浏览0评论

I have an input like like this:

start: 0.21 | duration: 0.30 | text: Subtitle Text 1 
start: 0.32 | duration: 0.52 | text: Subtitle Text 2 

This input needs to be converted into SRT format, so it bees something like this:

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

}

formatMilliseconds(0.21)

I have an input like like this:

start: 0.21 | duration: 0.30 | text: Subtitle Text 1 
start: 0.32 | duration: 0.52 | text: Subtitle Text 2 

This input needs to be converted into SRT format, so it bees something like this:

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

}

formatMilliseconds(0.21)

Share Improve this question edited Oct 21, 2017 at 15:41 Gobinath M asked Oct 21, 2017 at 15:35 Gobinath MGobinath M 2,0316 gold badges29 silver badges47 bronze badges 1
  • formatMilliseconds is expecting milliseconds so call it like this: formatMilliseconds(0.21 * 1000);. – ibrahim mahrir Commented Oct 21, 2017 at 15:48
Add a ment  | 

3 Answers 3

Reset to default 8

First you'll want to bring your input format into a processable format, something along the lines of

var subtitles = [
{
  start: 0.21,
  end: 0.3,
  text: "Subtitle Text 1"
},
{
  start: 0.32,
  end: 0.52,
  text: "Subtitle Text 2"
}
];

Note that I chose "end" instead of "duration" here, because "duration" in my eyes would mean that the subtitle ends at start + duration (0.21 + 0.3 = 0.51) seconds.

The formatting function was almost correct, but needed the input value supplied as milliseconds instead of decimal second values. For output, you also need to pad hours/minuts/seconds with zeroes. You'd better use a helper function for this where you can specify the target string length, but for this example I just did it inline:

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]));
}

You can implement such conversion by using moment.js for date/time manipulations and sprintf for strings formatting

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 ment = parts.shift().split(':').pop().trim();
        result.push(sprintf('%s --> %s', start, end));
        result.push(ment);
        result.push('');
    })
    return result.join('\n');
}

console.log(formatSrt(data));
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.19.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/sprintf/1.1.1/sprintf.min.js"></script>

Here is my attempt, could be improved but it's working.

Can be tested here: https://jsfiddle/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;
}
发布评论

评论列表(0)

  1. 暂无评论