Пройдите через объект JSON в указанное время (например, субтитры к фильму)

Прежде всего, извините, если название не является достаточно точным, если у кого-то есть предложения, которые они очень приветствуются. Я объясню свою проблему сейчас. У меня есть файл JSON (хотя здесь это объект javascript), который я хочу просмотреть. Это файл субтитров для фильма, и я хотел бы показать текст в точности так, как вы ожидаете: только в указанное время.

Я не использую видеоплеер или что-либо еще в связи с этим, так что это будет только nodejs, проходящий через этот файл. Я действительно знаю, как я могу пройти через него с помощью простого цикла for, но мне интересно, как пройти через него и сделать это точно в моменты времени, указанные в соответствующих объектах javascript?

 { id: '54',
    startTime: '00:03:46,572',
    endTime: '00:03:53,160',
    text: 'Hello this is a text' 
 },
 { id: '55',
    startTime: '00:03:53,160',
    endTime: '00:03:58,799',
    text: 'To be precise, the subtitle file of a movie' 
 },

2 ответа

Решение

Во-первых, вы должны разобрать startTime а также endTime до миллисекунд.

Вы можете просто разорвать строку, используя : а также , символов, и вычислите миллисекунды, которые он представляет.

function parseTime(t) {
    var segments = t.split(':');
    var ms = parseInt(segments[2].split(',')[1]);
    var h = parseInt(segments[0]);
    var m = parseInt(segments[1]);
    var s = parseInt(segments[2]);
    return h * 60 * 60 * 1000 + m * 60 * 1000 + s * 1000 + ms;
}

Затем перейдите к массиву и преобразуйте время в миллисекунды:

function convertToMs(arr) {
    for (var i = 0; i < arr.length; i++) {
        arr[i].startTime = parseTime(arr[i].startTime);
        arr[i].endTime= parseTime(arr[i].endTime);    
    }
    return arr;
}

Теперь начните с первого элемента в массиве и установите обратный вызов для следующего элемента при каждом вызове, если только вы не достигли конца массива.

function showSubtitles(arr, i) {
    setTimeout(function() {
        console.log(arr[i].text);
        setTimeout(console.clear, arr[i].endTime - arr[i].startTime); // Make the subtitle "disappear"
        i++;
        if (arr.length > i) {
            showSubtitles(arr, i);
        }
    }, i == 0 ? (arr[i].startTime) : (arr[i].startTime - arr[i-1].startTime));
}

Теперь используя ваш массив:

var subtitles = [{
        id: '54',
        startTime: '00:03:46,572',
        endTime: '00:03:53,160',
        text: 'Hello this is a text' 
    },
    { 
        id: '55',
        startTime: '00:03:53,160',
        endTime: '00:03:58,799',
        text: 'To be precise, the subtitle file of a movie' 
    }];
subtitles = convertToMs(subtitles);
showSubtitles(subtitles, 0);

Вот рабочая скрипка с более короткими временами субтитров: https://jsfiddle.net/6oxfx4s1/2/

Я могу придумать одно решение:

Используйте свой массив объектов, установите тайм-аут для разницы во времени между startTime а также endTime,

Как только разница во времени завершена, следующий объект выбирается для обработки или отображения (ваша цель в основном)

var textarr =  [{ id: '54',
    startTime: '00:03:46,572',
    endTime: '00:03:53,160',
    text: 'Hello this is a text' 
 },
 { id: '55',
    startTime: '00:03:53,160',
    endTime: '00:03:58,799',
    text: 'To be precise, the subtitle file of a movie' 
 }]

var i=0;

function getText(textarr,i){
    setTimeout(function(){
        console.log(textarr[i].text);
        i++;
        getText(textarr,i)
    },textarr[i].endTime-textarr[i].startTime) //take care of the difference of time.
}

Позаботьтесь о разнице во времени и таких подробностях в коде. Но это можно использовать для логики.

Другие вопросы по тегам