【问题标题】:Reading WebVTT files in PHP用 PHP 读取 WebVTT 文件
【发布时间】: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)来做到这一点确实是我所追求的信息。

标签: php parsing webvtt vtt


【解决方案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("/^(\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 . ' ';
            }   
    
        }       
    }
    

    【讨论】:

    • 我不得不调整正则表达式以考虑 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("/^(\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");
    
    ?>
    

    【讨论】:

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