用 PHP 读取 WebVTT 文件

Posted

技术标签:

【中文标题】用 PHP 读取 WebVTT 文件【英文标题】:Reading WebVTT files in PHP 【发布时间】:2014-10-01 15:56:23 【问题描述】:

有人有使用 php 读取 WebVTT (.vtt) 文件的经验吗?

我正在使用 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 三行第四句

请注意,可以有换行符,因此每个时间戳之间没有固定的行数。

我的计划是搜索“-->”,这是每个时间戳之间的公共字符串。有谁知道如何最好地实现这一目标?

【问题讨论】:

如果您能详细说明您面临的具体问题,您可能会得到更好的答案。最好的办法?有数百种不同的方法,到目前为止您尝试过什么? strpos() 怎么样?如果您需要一些基本的东西来开始,遍历所有行,使用strpos() 检查-->,使用preg_match() 解析行,将以下所有行读入一个字符串,直到你到达一个空行,重复直到到达EOF。有关解析 WebVTT 文件的更多信息,请参阅the Parsing section of the WebVTT specs 嗯,具体的问题是我正在寻找实现示例中给出的输出的最佳方法。因此,详细说明我如何使用您的建议(strpos 和 preg_match)来做到这一点确实是我所追求的信息。 【参考方案1】:

要解析文件,您可以使用这样的库:

$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

【讨论】:

【参考方案2】:

这似乎达到了我的需要,即输出开始时间和任何后续的文本行。我使用的文件非常小,因此使用 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("/^(\d2:[\d\.]+) --> \d2:[\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 . ' ';
           

           

【讨论】:

我不得不调整正则表达式以考虑 hh:mm:ss,但除此之外它按预期工作【参考方案3】:

你可以这样做:

<?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("/^(\d2:[\d\.]+) --> \d2:[\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");

?>

【讨论】:

这似乎只是输出了整个文件?如果您将我给出的示例复制到一个名为 test.vtt 的文件中,然后运行 ​​send_reformatted("test.vtt") 它只会输出提供的文件。 我在发布上面的代码之前已经对此进行了测试,它对我来说效果很好。我必须检查为什么它对你不起作用。我在ubuntu上。你的操作系统是什么? 在 Apache, PHP 5.3 下的 CentOS 服务器上运行它。我实际上已经想出了一些几乎可以满足我的需求的东西,所以一旦完成就会完整发布。您上面回复中的 preg_match 非常有用,并且在我的解决方案中使用了它。谢谢。

以上是关于用 PHP 读取 WebVTT 文件的主要内容,如果未能解决你的问题,请参考以下文章

PHP 用PHP读取CSV文件

用php读取pdf文件

用 php 读取纯文本文件

PHP学习笔记:用php读取xml文件

如果代码是用 PHP 生成的,WEBVTT 字幕不显示

用PHP读取ExcelCSV文件