web-dev-qa-db-fra.com

Comment convertir un fichier F4F en MP4?

Nous savons que F4F est le format de fichier MP4 fragmenté par Adobe pour HTTP Dynamic Streaming . Un outil appelé F4F Packager pourrait convertir un fichier F4V en plusieurs fichiers F4F et un fichier manifeste (F4M).

Ma question est, comment convertir de tels fichiers F4F en un fichier F4V ou MP4?

20
LitNakex

Nous avons finalement trouvé une méthode simple pour fusionner et convertir fichiers .f4f -> fichier .flv , dans lesquels seule la boîte 'mdat' est utile. Voici le code 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";
?>
10
LitNakex

Une réponse plus complète est disponible ici: https://github.com/K-S-V/Scripts/blob/master/AdobeHDS.php

Les choses sérieuses se produisent autour de la ligne 1046 . Ce script traite plus d’affaires que la première réponse actuelle. Je ne posterai pas tout le script ici car il est un peu long.

Hélas, c'est aussi un script PHP, bien que je puisse avoir besoin de le réécrire en Java dans quelques semaines. Si c'est le cas, je posterai un lien vers la réécriture Java lorsque ce sera fait.

10
david_p

livestreamer et youtube-dl prennent en charge les flux HDS. Voici un exemple de livestreamer:

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

Ceci est une station de radio Internet. Pour la vidéo, seule une modification de 48k et l'extension de fichier de out.m4a sont nécessaires.

0