用 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 文件的主要内容,如果未能解决你的问题,请参考以下文章