2014-10-01 29 views
1

有沒有人有使用PHP讀取WebVTT(.vtt)文件的經驗?在PHP中讀取WebVTT文件

我正在CakePHP中開發一個應用程序,我需要通讀一堆vtt文件並獲取開始時間和相關文本。

因此,作爲該文件的一個例子:

 
00:00.999 --> 00:04.999 
sentence one 

00:04.999 --> 00:07.999 
sentence two 

00:07.999 --> 00:10.999 
third sentence 
with a line break 

00:10.999 --> 00:14.999 
a fourth sentence 
on three 
lines 

我需要能夠提取這樣的事情:

 
00:00.999 sentence one 
00:04.999 sentence two 
00:07.999 third sentence with a line break 
00:10.999 a fourth sentence on three lines 

注意,可以有換行符所以有沒有定數每個時間戳之間的線。

我的計劃是搜索「 - >」,這是每個時間戳之間的常用字符串。有沒有人有任何想法如何最好地實現這一目標?

+0

您可能會收到更好的答案,如果你想詳細說明你面對多一點具體的問題。最好的辦法?有幾百種不同的方式,到目前爲止您嘗試過什麼? 'strpos()'怎麼樣?如果你需要一些基本的入門知識,對所有行進行迭代,使用'strpos()'來檢查' - >',使用'preg_match()'解析這行,讀取下面所有行到一個字符串中,直到到達空行,重複直至到達EOF。有關解析WebVTT文件的更多信息,請參閱[** WebVTT規範**的解析部分](http://dev.w3.org/html5/webvtt/#parsing)。 – ndm 2014-10-01 16:47:39

+0

那麼,具體問題是我正在尋找實現我在示例中給出的輸出的最佳方式。因此,詳細闡述如何使用您的建議(strpos和preg_match)來實現這一點,這實際上就是我所追求的信息。 – 2014-10-02 09:29:58

回答

0

你可以做這樣的事情:

<?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"); 

?> 
+0

這似乎只輸出整個文件?如果您將我給出的示例複製到名爲test.vtt的文件中,然後運行send_reformatted(「test.vtt」),它將只輸出提供的文件。 – 2014-10-02 09:34:13

+0

在我發佈上面的代碼之前,我已經測試過了,它對我很好。我必須檢查它爲什麼不適合你。我在Ubuntu上。你的操作系統是什麼? – kums 2014-10-02 09:39:11

+0

在Apache,PHP 5.3下的CentOS服務器上運行它。我實際上已經想出了一些幾乎可以滿足我需求的東西,所以一旦完成就可以完整發布。上面回覆中的preg_match非常有用,並且已經在我的解決方案中使用了它。謝謝。 – 2014-10-02 10:59:12

1

這似乎達到我所需要的,即輸出的開始時間和文本的任何後續行。我使用的文件相當小,因此使用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 . ' '; 
     } 

    }  
} 
+0

我不得不調整正則表達式來解釋hh:mm:ss,但是其他的按預期工作 – GDP 2015-06-02 13:33:37

0

解析文件,您可以使用庫這樣的:

$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