Чтение файлов WebVTT на PHP

У кого-нибудь есть опыт чтения файлов WebVTT (.vtt) с использованием PHP?

Я разрабатываю приложение в CakePHP, где мне нужно прочитать кучу vtt-файлов и получить время начала и связанный текст.

Итак, как пример файла:

00: 00.999 -> 00:04.999
предложение первое

00:04.999 -> 00:07.999
предложение второе

00:07.999 -> 00:10.999
третье предложение
с разрывом строки

00: 10.999 -> 00:14.999
четвертое предложение
на три
линии

Мне нужно иметь возможность извлечь что-то вроде этого:

00: 00.999 первое предложение
00: 04.999 предложение два
00: 07.999 третье предложение с переводом строки
00: 10.999 четвертое предложение в три строки

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

Мой план состоял в том, чтобы искать "->", который является общей строкой между каждой отметкой времени. У кого-нибудь есть идеи, как лучше всего этого добиться?

3 ответа

Для разбора файла вы можете использовать библиотеку следующим образом:

$subtitles = Subtitles::load('subtitles.vtt');
$blocks = $subtitles->getInternalFormat(); // array

foreach ($blocks as $block) {
    echo $block['start'];
    echo $block['end'];
    foreach ($block['lines'] as $line) {
        echo $line;
    }
} 

https://github.com/mantas-done/subtitles

Похоже, это дает то, что мне нужно, т.е. выводит время начала и любые последующие строки текста. Файлы, которые я использую, довольно малы, поэтому использование PHP-функции file() для считывания всего в массив выглядит нормально; не уверен, что это будет хорошо работать на больших файлах, хотя.

    $file = 'test.vtt'; 
    $file_as_array = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

    foreach ($file_as_array as $f) {    

        // Find lines containing "-->"  
        $start_time = false;
        if (preg_match("/^(\d{2}:[\d\.]+) --> \d{2}:[\d\.]+$/", $f, $match)) {              
            $start_time = explode('-->', $f);
            $start_time = $start_time[0];
            echo '<br>';
            echo $start_time;
        }

        // It's a line of the file that doesn't include a timestamp, so it's caption text. Ignore header of file which includes the word 'WEBVTT'
        if (!$start_time && (!strpos($f, 'WEBVTT')) ) {             
            echo ' ' . $f . ' ';
        }   

    }       
}

Вы можете сделать что-то вроде этого:

<?PHP

function send_reformatted($vtt_file){
 // Add these headers to ease saving the output as text file
    header("Content-type: text/plain");
    header('Content-Disposition: inline; filename="'.$vtt_file.'.txt"');

    $f = fopen($vtt_file, "r");
    $line_new = "";

    while($line = fgets($f)){
        if (preg_match("/^(\d{2}:[\d\.]+) --> \d{2}:[\d\.]+$/", $line, $match)) {
            if($line_new) echo $line_new."\n";
            $line_new = $match[1];
        } else{
            $line = trim($line);
            if($line) $line_new .= " $line";
        }
    }

    echo $line_new."\n";
    fclose($f);
}


send_reformatted("test.vtt");

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