相关文章推荐
销魂的棒棒糖  ·  Java ...·  1 年前    · 
深沉的鸡蛋面  ·  monaco-editor ...·  1 年前    · 
大方的炒饭  ·  Javascript ...·  1 年前    · 
刚分手的足球  ·  Qt 中的字体_qt ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

We know F4F is Adobe's fragmented MP4 file format for HTTP Dynamic Streaming . A tool called F4F Packager could convert an F4V file to several F4F files and a manifest file(F4M).

My question is, how to convert such F4F files back to an F4V or MP4 file?

We finally found a simple method to merge & convert .f4f files -> .flv file , in which only 'mdat' box is usefull. Here is a the php code:

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++; 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"; Couldn't get this to work. Firstly there is no hex2bin function, the ReadInt32 function is invalid. I fixed all of these but still had a problem. I think my file is a 64bit mdat fragment as the first 4 character before mdat are 00 00 00 01 which obviously is not the size of the mdat. Craig Apr 23, 2013 at 10:36 Enclose $fragCount + 1 in parentheses to avoid bad handling of certain file names containing numbers. Alden Dec 16, 2015 at 7:18

A more comprehensive answer is available here : https://github.com/K-S-V/Scripts/blob/master/AdobeHDS.php .

The serious stuff happens around line 1046 . This script handles more cases that the current top answer. I won't post the whole script here since it's a bit long.

Alas, it's a PHP script too, though I may need to rewrite this in Java in a couple of weeks. If so, I'll post a link to the Java rewrite when it's done.

Using the script worked for me: php AdobeHDS.php --fragments Seg1-Frag (my f4f files were: Seg1-Frag1 , Seg2-Frag2 , etc.) dusan Jan 12, 2014 at 22:08 Using the HDS Link Detector add-on in FireFox makes working with this script much easier. I let the add-on generate the proper command, paste it into the console, and run it this way. Michael Szczepaniak Nov 28, 2014 at 19:36

livestreamer and youtube-dl both support HDS streams. Here's an example of livestreamer:

$ livestreamer -O 'hds://radio_chym-lh.akamaihd.net/z/KIT967_1@183249/manifest.f4m' 48k >out.m4a

This is an internet radio station. For video, only a change in 48k and the file extension of out.m4a should be necessary.