【发布时间】:2012-03-06 19:28:50
【问题描述】:
我们知道 F4F 是 Adobe 用于 HTTP 动态流 的分段 MP4 文件格式。 F4F Packager 工具可以将一个 F4V 文件转换为多个 F4F 文件和一个清单文件(F4M)。
我的问题是,如何将此类 F4F 文件转换回 F4V 或 MP4 文件?
【问题讨论】:
-
我对捕获这些流的工具更感兴趣。
标签: adobe
我们知道 F4F 是 Adobe 用于 HTTP 动态流 的分段 MP4 文件格式。 F4F Packager 工具可以将一个 F4V 文件转换为多个 F4F 文件和一个清单文件(F4M)。
我的问题是,如何将此类 F4F 文件转换回 F4V 或 MP4 文件?
【问题讨论】:
标签: adobe
我们终于找到了一个简单的方法来合并和转换.f4f文件->.flv文件,其中只有'mdat'框有用。这是一个php代码:
<?php
function ReadInt24($str, $pos)
{
return intval(bin2hex(substr($str, $pos, 3)), 16);
}
function ReadInt32($str, $pos)
{
return unpack("N", substr($str, $pos, 4))[1];
}
echo "\nKSV Adobe HDS Downloader\n\n";
$flvHeader = hex2bin("464c5601050000000900000000");
$firstVideoPacket = true;
$prevTagSize = 4;
$fragCount = 0;
isset($argv[1]) ? $baseFilename = $argv[1] : $baseFilename = "";
$baseFilename ? $outputFile = "$baseFilename.flv" : $outputFile = "Joined.flv";
while (true)
{
if (file_exists("$baseFilename" . $fragCount + 1 . ".f4f"))
$fragCount++;
else
break;
}
echo "Found $fragCount fragments\n";
$flv = fopen("$outputFile", "wb");
fwrite($flv, $flvHeader, 13);
for ($i = 1; $i <= $fragCount; $i++)
{
$frag = file_get_contents("$baseFilename$i.f4f");
preg_match('/(.{4})mdat[\x08\x09\x12]/i', $frag, $mdat, PREG_OFFSET_CAPTURE);
$fragLen = ReadInt32($mdat[1][0], 0) - 8;
$frag = substr($frag, $mdat[1][1] + 8, $fragLen);
$pos = 0;
while ($pos < $fragLen)
{
$packetType = $frag[$pos];
$packetSize = ReadInt24($frag, $pos + 1);
$packetTS = ReadInt24($frag, $pos + 4);
$totalTagLen = 11 + $packetSize + $prevTagSize;
if (($packetType == "\x08" && $packetSize > 4) or ($packetType == "\x09" && $packetSize > 40) or ($packetType == "\x09" && $firstVideoPacket))
{
if ($packetType == "\x09" && $firstVideoPacket)
$firstVideoPacket = false;
fwrite($flv, substr($frag, $pos, $totalTagLen), $totalTagLen);
}
$pos += $totalTagLen;
}
}
fclose($flv);
echo "Finished\n";
?>
【讨论】:
$fragCount + 1 括在括号中以避免错误处理某些包含数字的文件名。
此处提供更全面的答案:https://github.com/K-S-V/Scripts/blob/master/AdobeHDS.php。
严重的事情发生在around line 1046。 此脚本处理比当前最佳答案更多的情况。篇幅有点长,这里就不放全文了。
唉,它也是一个 PHP 脚本,不过我可能需要在几周内用 Java 重写它。如果是这样,我会在完成后发布 Java 重写的链接。
【讨论】:
php AdobeHDS.php --fragments Seg1-Frag(我的 f4f 文件是:Seg1-Frag1、Seg2-Frag2 等)
livestreamer 和 youtube-dl 都支持 HDS 流。这是一个直播者的例子:
$ livestreamer -O 'hds://radio_chym-lh.akamaihd.net/z/KIT967_1@183249/manifest.f4m' 48k >out.m4a
这是一个网络电台。对于视频,只需更改48k 和out.m4a 的文件扩展名即可。
【讨论】: