You are here

public function TranscoderAbstractionFactoryFfmpeg::extractFrames in Video 7.2

Extract frames from the current video.

The thumbnails are be saved to the given scheme. The files are not be saved to the database, this will be done by the caller. The uid, filesize and timestamp properties are not set by this method.

Parameters

$destinationScheme: A valid stream wrapper scheme

$format: png or jpg

Return value

array of file objects, FALSE on error

Overrides TranscoderFactoryInterface::extractFrames

File

transcoders/TranscoderAbstractionFactoryFfmpeg.inc, line 190
File containing class TranscoderAbstractionFactoryFfmpeg

Class

TranscoderAbstractionFactoryFfmpeg
Class that handles FFmpeg transcoding.

Code

public function extractFrames($destinationScheme, $format) {

  // When $job is null, we are viewing the thumbnails before the form has been submitted.
  $fid = intval($this->settings['input']['fid']);
  $job = video_jobs::load($fid);

  // Get the file system directory.
  $dsturibase = $destinationScheme . '://' . variable_get('video_thumbnail_path', 'videos/thumbnails') . '/' . $fid . '/';
  file_prepare_directory($dsturibase, FILE_CREATE_DIRECTORY);
  $dstwrapper = file_stream_wrapper_get_instance_by_scheme($destinationScheme);

  // get the video file informations
  $file_info = $this
    ->getFileInfo();
  $duration = floor($file_info['duration']['seconds']);
  $no_of_thumbnails = variable_get('video_thumbnail_count', 5);

  // Precaution for very short videos
  if (2 * $no_of_thumbnails > $duration) {
    $no_of_thumbnails = floor($duration / 2);
  }
  $thumbs = array();
  for ($i = 1; $i <= $no_of_thumbnails; $i++) {
    $seek = ceil($duration / ($no_of_thumbnails + 1) * $i);
    $filename = file_munge_filename('thumbnail-' . $fid . '_' . sprintf('%04d', $i) . '.' . $format, '', FALSE);
    $dsturi = $dsturibase . $filename;
    if (!file_exists($dsturi)) {

      // Create a temporary file that will be moved to the final URI later
      $dstpath = video_utility::createTempFile($format);
      $error = NULL;
      if (class_exists('ffmpeg_movie')) {
        $movie = new ffmpeg_movie($this->transcoder
          ->getInputFile());
        $frames = $movie
          ->getFrameCount();
        $fps = $movie
          ->getFrameRate();
        $frame = $movie
          ->getFrame(min($frames, (int) $seek * $fps));
        $thumb = $frame
          ->toGDImage();
        $result = video_utility::imageSave($thumb, $dstpath, $format);
        if (!$result) {
          $error = t('Unknown FFmpeg-php error');
        }
      }
      else {
        $this->transcoder
          ->extractFrame($seek, FALSE, '%st');
        $result = $this->transcoder
          ->setOutput(dirname($dstpath) . '/', basename($dstpath), PHPVideoToolkit::OVERWRITE_EXISTING);
        if ($result === PHPVideoToolkit::RESULT_OK) {
          if (isset($file_info['video']['rotate'])) {
            switch ($file_info['video']['rotate']) {
              case 90:
                $this->transcoder
                  ->addCommand('-vf', 'transpose=1');
                break;
              case 180:
                $this->transcoder
                  ->addCommand('-vf', 'vflip');
                break;
              case 270:
                $this->transcoder
                  ->addCommand('-vf', 'transpose=2');
                break;
            }
          }
          $result = $this->transcoder
            ->execute() === PHPVideoToolkit::RESULT_OK;
        }
        if (!$result) {
          $error = $this->transcoder
            ->getLastError();
          $this->transcoder
            ->reset(true);
        }
      }

      // Check if the extraction was successfull
      if ($error === NULL) {
        if (!file_exists($dstpath)) {
          $error = t('generated file %file does not exist', array(
            '%file' => $dstpath,
          ));
        }
        elseif (filesize($dstpath) == 0) {
          $error = t('generated file %file is empty', array(
            '%file' => $dstpath,
          ));
          drupal_unlink($dstpath);
        }
      }
      if ($error !== NULL) {
        form_set_error(NULL, t('Error generating thumbnail for video %videofilename: !error.', array(
          '%videofilename' => $this->settings['input']['filename'],
          '!error' => $error,
        )));
        watchdog('transcoder', 'Error generating thumbnail for video %videofilename: !error.', array(
          '%videofilename' => $this->settings['input']['filename'],
          '!error' => $error,
        ), WATCHDOG_ERROR);
        continue;
      }

      // Move the file to the final URI
      copy($dstpath, $dsturi);
    }

    // Begin building the file object.
    $thumb = new stdClass();
    $thumb->status = 0;
    $thumb->filename = basename($dsturi);
    $thumb->uri = $dsturi;
    $thumb->filemime = $dstwrapper
      ->getMimeType($dsturi);
    $thumbs[] = $thumb;
  }
  return !empty($thumbs) ? $thumbs : FALSE;
}