You are here

public function PHPVideoToolkit::getFFmpegInfo in Video 7.2

Same name and namespace in other branches
  1. 7 libraries/phpvideotoolkit/phpvideotoolkit.php5.php \PHPVideoToolkit::getFFmpegInfo()

Returns information about the specified file without having to use ffmpeg-php as it consults the ffmpeg binary directly. NOTE: calling this statically for caching to work you must set the temp directory.

@access public

Return value

mixed FALSE on error encountered, TRUE otherwise

8 calls to PHPVideoToolkit::getFFmpegInfo()
PHPVideoToolkit::getAvailableCodecs in libraries/phpvideotoolkit/phpvideotoolkit.php5.php
Returns the available codecs. @access public
PHPVideoToolkit::getAvailableFormats in libraries/phpvideotoolkit/phpvideotoolkit.php5.php
Returns the available formats. @access public
PHPVideoToolkit::getAvailablePixelFormats in libraries/phpvideotoolkit/phpvideotoolkit.php5.php
Returns the available pixel formats.
PHPVideoToolkit::hasCodecSupport in libraries/phpvideotoolkit/phpvideotoolkit.php5.php
Determines if your ffmpeg has particular codec support for encode or decode.
PHPVideoToolkit::hasVHookSupport in libraries/phpvideotoolkit/phpvideotoolkit.php5.php
Determines if the ffmpeg binary has been compiled with vhook support.

... See full list

File

libraries/phpvideotoolkit/phpvideotoolkit.php5.php, line 573
Libary to access FFmpeg

Class

PHPVideoToolkit

Code

public function getFFmpegInfo($read_from_cache = TRUE) {

  // check to see if the info has already been cached
  if ($read_from_cache && PHPVideoToolkit::$ffmpeg_info !== FALSE) {
    return PHPVideoToolkit::$ffmpeg_info;
  }
  $data = array();
  $formats = $this
    ->_captureExecBuffer($this->_ffmpeg_binary . ' -formats');
  $codecs = $this
    ->_captureExecBuffer($this->_ffmpeg_binary . ' -codecs');
  $filters = $this
    ->_captureExecBuffer($this->_ffmpeg_binary . ' -bsfs');
  $protocols = $this
    ->_captureExecBuffer($this->_ffmpeg_binary . ' -protocols');
  $pixformats = $this
    ->_captureExecBufferFallback($this->_ffmpeg_binary . ' -pix_fmts', $this->_ffmpeg_binary . ' -pix_fmt list');
  $help = $this
    ->_captureExecBuffer($this->_ffmpeg_binary . ' -h');
  self::$ffmpeg_found = $data['ffmpeg-found'] = !empty($formats) && strpos($formats[0], 'not found') === FALSE && strpos($formats[0], 'No such file or directory') === FALSE;
  $data['compiler'] = array();
  $data['binary'] = array();
  $data['ffmpeg-php-support'] = self::hasFFmpegPHPSupport();

  // FFmpeg 0.5 and lower don't support -codecs, -bsfs or -protocols, but the info is in -formats
  if (strpos(end($codecs), 'missing argument for option')) {
    $formats = implode("\n", $formats);
    $codecs = $formats;
    $filters = $formats;
    $protocols = $formats;
    $pixformats = implode("\n", $pixformats);
    $help = implode("\n", $help);
    $data['raw'] = $formats . $pixformats;
  }
  else {
    $formats = implode("\n", $formats);
    $codecs = implode("\n", $codecs);
    $filters = implode("\n", $filters);
    $protocols = implode("\n", $protocols);
    $pixformats = implode("\n", $pixformats);
    $help = implode("\n", $help);
    $data['raw'] = $formats . "\n" . $codecs . "\n" . $filters . "\n" . $protocols . "\n" . $pixformats;
  }
  if (!self::$ffmpeg_found) {
    self::$ffmpeg_info = $data;
    return $data;
  }

  // grab the versions
  $data['binary']['versions'] = self::getVersion($data['raw']);

  // grab the ffmpeg configuration flags
  $config_flags = array();
  if (preg_match_all('/--[a-zA-Z0-9\\-]+/', $formats, $config_flags)) {
    $data['binary']['configuration'] = $config_flags[0];
    $data['binary']['vhook-support'] = in_array('--enable-vhook', $config_flags[0]) || !in_array('--disable-vhook', $config_flags[0]);

    // grab the ffmpeg compile info
    preg_match('/built on (.*), gcc: (.*)/', $formats, $conf);
    if (count($conf) > 0) {
      $data['compiler']['gcc'] = $conf[2];
      $data['compiler']['build_date'] = $conf[1];
      $data['compiler']['build_date_timestamp'] = strtotime($conf[1]);
    }
  }

  // grab the file formats available to ffmpeg
  $formatmatches = array();
  $data['formats'] = array();
  if (preg_match_all('/ (DE|D|E) (.*) {1,} (.*)/', $formats, $formatmatches)) {

    // 			loop and clean
    // Formats:
    //  D. = Demuxing supported
    //  .E = Muxing supported
    for ($i = 0, $a = count($formatmatches[0]); $i < $a; $i++) {
      $data['formats'][strtolower(trim($formatmatches[2][$i]))] = array(
        'mux' => $formatmatches[1][$i] == 'DE' || $formatmatches[1][$i] == 'E',
        'demux' => $formatmatches[1][$i] == 'DE' || $formatmatches[1][$i] == 'D',
        'fullname' => $formatmatches[3][$i],
      );
    }
  }

  // grab the codecs available
  $codecsmatches = array();
  $data['codecs'] = array(
    'video' => array(),
    'audio' => array(),
    'subtitle' => array(),
  );
  if (preg_match_all('/((?:[DEVAST ]{6})|(?:[DEVASTFB ]{8})|(?:[DEVASIL\\.]{6})) ([A-Za-z0-9\\_]+) (.+)/', $codecs, $codecsmatches)) {

    // FFmpeg 0.12+
    //  D..... = Decoding supported
    //  .E.... = Encoding supported
    //  ..V... = Video codec
    //  ..A... = Audio codec
    //  ..S... = Subtitle codec
    //  ...I.. = Intra frame-only codec
    //  ....L. = Lossy compression
    //  .....S = Lossless compression
    // FFmpeg other
    //  D..... = Decoding supported
    //  .E.... = Encoding supported
    //  ..V... = Video codec
    //  ..A... = Audio codec
    //  ..S... = Subtitle codec
    //  ...S.. = Supports draw_horiz_band
    //  ....D. = Supports direct rendering method 1
    //  .....T = Supports weird frame truncation
    for ($i = 0, $a = count($codecsmatches[0]); $i < $a; $i++) {
      $options = preg_split('//', $codecsmatches[1][$i], -1, PREG_SPLIT_NO_EMPTY);
      if ($options) {
        $id = trim($codecsmatches[2][$i]);
        $type = $options[2] === 'V' ? 'video' : ($options[2] === 'A' ? 'audio' : 'subtitle');
        switch ($options[2]) {

          // 					video
          case 'V':
            $data['codecs'][$type][$id] = array(
              'encode' => isset($options[1]) === TRUE && $options[1] === 'E',
              'decode' => isset($options[0]) === TRUE && $options[0] === 'D',
              'draw_horizontal_band' => isset($options[3]) === TRUE && $options[3] === 'S',
              'direct_rendering_method_1' => isset($options[4]) === TRUE && $options[4] === 'D',
              'weird_frame_truncation' => isset($options[5]) === TRUE && $options[5] === 'T',
              'fullname' => trim($codecsmatches[3][$i]),
            );
            break;

          // 					audio
          case 'A':

          // 					subtitle
          case 'S':
            $data['codecs'][$type][$id] = array(
              'encode' => isset($options[1]) === TRUE && $options[1] === 'E',
              'decode' => isset($options[0]) === TRUE && $options[0] === 'D',
              'fullname' => trim($codecsmatches[3][$i]),
            );
            break;
        }
      }
    }
  }

  // grab the bitstream filters available to ffmpeg
  $data['filters'] = array();
  $locate = 'Bitstream filters:';
  if (!empty($filters) && ($pos = strpos($filters, $locate)) !== FALSE) {
    $filters = trim(substr($filters, $pos + strlen($locate)));
    $data['filters'] = explode("\n", $filters);
  }

  // grab the file protocols available to ffmpeg
  $data['protocols'] = array();
  $locate = 'Supported file protocols:';
  if (!empty($protocols) && ($pos = strpos($protocols, $locate)) !== FALSE) {
    $protocols = trim(substr($filters, $pos + strlen($locate)));
    $data['protocols'] = explode("\n", $protocols);
  }

  // grab the pixel formats available to ffmpeg
  $data['pixelformats'] = array();

  // Separate code for FFmpeg 0.5
  if (strpos($pixformats, 'Pixel formats') === FALSE) {

    // Format:
    // name       nb_channels depth is_alpha
    // yuv420p         3         8      n
    // yuyv422         1         8      n
    $matches = array();
    preg_match_all('#(\\w+)\\s+(\\d+)\\s+(\\d+)\\s+(y|n)#', $pixformats, $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
      $data['pixelformats'][$match[1]] = array(
        'encode' => TRUE,
        // Assume true
        'decode' => TRUE,
        // Assume true
        'components' => intval($match[2]),
        'bpp' => intval($match[3]),
      );
    }
  }
  else {

    // Format:
    // Pixel formats:
    // I.... = Supported Input  format for conversion
    // .O... = Supported Output format for conversion
    // ..H.. = Hardware accelerated format
    // ...P. = Paletted format
    // ....B = Bitstream format
    // FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL
    // -----
    // IO... yuv420p                3            12
    $matches = array();
    preg_match_all('#(I|\\.)(O|\\.)(H|\\.)(P|\\.)(B|\\.)\\s+(\\w+)\\s+(\\d+)\\s+(\\d+)#', $pixformats, $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
      $data['pixelformats'][$match[6]] = array(
        'encode' => $match[1] == 'I',
        'decode' => $match[2] == 'O',
        'components' => intval($match[7]),
        'bpp' => intval($match[8]),
      );
    }
  }

  // grab the command line options available to ffmpeg
  $data['commandoptions'] = array();
  $matches = array();
  preg_match_all('#\\n-(\\w+)(?:\\s+<(int|string|binary|flags|int64|float|rational)>)?#', $help, $matches, PREG_SET_ORDER);
  foreach ($matches as $match) {
    $data['commandoptions'][$match[1]] = array(
      'datatype' => isset($match[2]) ? $match[2] : NULL,
    );
  }
  PHPVideoToolkit::$ffmpeg_info = $data;
  return $data;
}