Подтвердить что ты не робот

Как преобразовать файл F4F в MP4?

Мы знаем, что F4F представляет собой фрагментированный фрагмент файла формата MP4 в формате Adobe для динамической потоковой передачи HTTP. Инструмент под названием F4F Packager может преобразовывать файл F4V в несколько файлов F4F и файл манифеста (F4M).

Мой вопрос: как преобразовать такие файлы F4F в файл F4V или MP4?

4b9b3361

Ответ 1

Наконец, мы нашли простой способ слияния и преобразования файлов .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";
?>

Ответ 2

Более полный ответ доступен здесь: https://github.com/K-S-V/Scripts/blob/master/AdobeHDS.php.

Серьезный материал происходит вокруг строки 1046. Этот script обрабатывает больше случаев, когда текущий верхний ответ. Я не буду публиковать здесь весь script, так как он немного длинный.

Увы, это PHP script тоже, хотя мне может понадобиться переписать это на Java через пару недель. Если это так, я отправлю ссылку на переписывание Java, когда это будет сделано.

Ответ 3

livestreamer и youtube-dl поддерживают HDS-потоки. Вот пример livestreamer:

$ livestreamer -O 'hds://radio_chym-lh.akamaihd.net/z/[email protected]/manifest.f4m' 48k >out.m4a

Это интернет-радиостанция. Для видео требуется только изменение 48k и расширение файла out.m4a.