我最近在解析视频文件中的元数据方面遇到了一个令人头痛的问题,发现部分问题是视频制作软件供应商无视各种标准(或至少是互动的差异)(以及其他原因)
因此,我需要能够扫描各种格式,容器和编解码器的非常大的视频(和图像)文件,并挖掘出元数据。我已经有FFMpeg,ExifTool Imagick和Exiv2各自处理各种文件类型的不同类型的元数据,并通过各种其他选项填补其他一些空白(请不要建议库或其他工具,我已经尝试了所有: ))。
现在我要为XMP块扫描大文件(每个高达2GB)(通常由Adobe套件和其他软件写入电影文件)。我已经写了一个功能,但我担心它可以改进。
function extractBlockReverse($file, $searchStart, $searchEnd)
{
$handle = fopen($file, "r");
if($handle)
{
$startLen = strlen($searchStart);
$endLen = strlen($searchEnd);
for($pos = 0,
$output = '',
$length = 0,
$finished = false,
$target = '';
$length < 10000 &&
!$finished &&
fseek($handle, $pos, SEEK_END) !== -1;
$pos--)
{
$currChar = fgetc($handle);
if(!empty($output))
{
$output = $currChar . $output;
$length++;
$target = $currChar . substr($target, 0, $startLen - 1);
$finished = ($target == $searchStart);
}
else
{
$target = $currChar . substr($target, 0, $endLen - 1);
if($target == $searchEnd)
{
$output = $target;
$length = $length + $endLen;
$target = '';
}
}
}
fclose($handle);
return $output;
}
else
{
throw new Exception('not found file');
}
return false;
}
echo extractBlockReverse("very_large_video_file.mov",
'<x:xmpmeta',
'</x:xmpmeta>');
目前它还没问题,但是我真的希望在不破坏我的服务器的情况下充分利用php,所以我想知道是否有更好的方法来做到这一点(或者调整代码会改进它)因为这种方法看起来有点过分,就像找到几个字符串并在它们之间拉出任何东西一样简单。
答案 0 :(得分:3)
您可以使用其中一种快速字符串搜索算法 - 例如Knuth-Morris-Pratt 或Boyer-Moore以查找开始和结束标记的位置,然后读取它们之间的所有数据。
你应该测量它们的性能,因为如此小的搜索模式可能会导致所选算法的常量不足以使它值得。
答案 1 :(得分:1)
对于文件这么大,我认为最重要的优化是不在任何地方搜索字符串。我不相信视频或图像会在中间有一个XML块 - 或者如果它有,它可能会是垃圾。
好的,有可能 - TIFF可以做到这一点,也可以用JPEG和PNG;为什么不是视频格式呢?但在实际应用中,XMP等松散格式的元数据通常存储在最后。更少见的是,它们存储在文件的开头附近,但这种情况不太常见。
另外,我认为大多数XMP块的尺寸都不会太大(即使Adobe经常填充它们以便能够“几乎总是”快速地就地更新它们。)
所以我的第一次尝试是从文件中提取第一个,例如100 Kb和最后100 Kb的信息。然后扫描这两个块“
如果搜索不成功,您仍然可以执行详尽的搜索,但如果搜索成功,则会在万分之一的时间内返回。相反,即使这个“技巧”仅在一千次中成功一次,它仍然是值得的。