You are here

public function video_ffmpeg::convert_video in Video 6.4

Same name and namespace in other branches
  1. 7 transcoders/video_ffmpeg.inc \video_ffmpeg::convert_video()

Overrides transcoder_interface::convert_video

File

transcoders/video_ffmpeg.inc, line 125

Class

video_ffmpeg

Code

public function convert_video($video) {

  // This will update our current video status to active.
  $this
    ->change_status($video->vid, VIDEO_RENDERING_ACTIVE);

  // Get the converted file object

  //we are going to move our video to an "original" folder

  //we are going to transcode the video to the "converted" folder

  // @TODO This about getting the correct path from the filefield if they active it
  $files = file_create_path();
  $originaldir = $files . '/videos/original';
  $converteddir = $files . '/videos/converted';
  if (!field_file_check_directory($originaldir, FILE_CREATE_DIRECTORY)) {
    watchdog('video_ffmpeg', 'Video conversion failed. Could not create directory %dir for storing original videos.', array(
      '%dir' => $originaldir,
    ), WATCHDOG_ERROR);
    return false;
  }
  if (!field_file_check_directory($converteddir, FILE_CREATE_DIRECTORY)) {
    watchdog('video_ffmpeg', 'Video conversion failed. Could not create directory %dir for storing converted videos.', array(
      '%dir' => $converteddir,
    ), WATCHDOG_ERROR);
    return false;
  }
  $original = $originaldir . '/' . $video->filename;

  //lets move our video and then convert it.
  $filepath = $video->filepath;
  if (!file_move($filepath, $original)) {
    watchdog('video_ffmpeg', 'Could not move video %orig to the original folder.', array(
      '%orig' => $video->filepath,
    ), WATCHDOG_ERROR);
    $this
      ->change_status($video->vid, VIDEO_RENDERING_FAILED);
    return FALSE;
  }

  // Update our filepath since we moved it
  $video->filepath = $filepath;
  drupal_write_record('files', $video, 'fid');

  // Increase the database timeout to prevent database errors after a long upload
  _video_db_increase_timeout();

  // Get video information before doing a chdir
  $dimensions = $this
    ->dimensions($video);
  $dimension = explode('x', $dimensions, 2);
  $filepath = realpath($video->filepath);

  // Create a temporary directory
  $drupaldir = getcwd();
  $tmpdir = tempnam(file_directory_temp(), 'ffmpeg-' . $video->fid);
  unlink($tmpdir);
  mkdir($tmpdir, 0777);
  chdir($tmpdir);
  $result = TRUE;

  // process presets
  $presets = $video->presets;
  $converted_files = array();
  foreach ($presets as $presetname => $preset) {

    //update our filename after the move to maintain filename uniqueness.
    $converted = file_create_filename(str_replace(' ', '_', pathinfo($video->filepath, PATHINFO_FILENAME)) . '.' . $preset['extension'], $converteddir);
    $convertedfull = $drupaldir . '/' . $converted;

    //call our transcoder
    $ffmpeg_output = $convertedfull;
    if ($this->enablefaststart && ($preset['extension'] == 'mp4' || $preset['extension'] == 'mov')) {
      $ffmpeg_output = file_directory_temp() . '/' . basename($converted);
    }
    $command_output = '';

    // Setup our default command to be run.
    foreach ($preset['command'] as $command) {
      $command = strtr($command, array(
        '!cmd_path' => $this->cmdpath,
        '!videofile' => escapeshellarg($filepath),
        '!audiobitrate' => $preset['audio_bitrate'],
        '!width' => intval($dimension[0]),
        '!height' => intval($dimension[1]),
        '!videobitrate' => $preset['video_bitrate'],
        '!convertfile' => escapeshellarg($ffmpeg_output),
      ));

      // Process our video
      if (!$this
        ->run_command($command, $command_output, t('rendering preset %preset', array(
        '%preset' => $presetname,
      )))) {
        $result = FALSE;
        break 2;
      }
    }
    if ($ffmpeg_output != $convertedfull && file_exists($ffmpeg_output)) {

      // Because the transcoder_interface doesn't allow the run_command() to include the ability to pass
      // the command to be execute so we need to fudge the command to run qt-faststart.
      $command_result = $this
        ->run_command($this->faststartcmd . ' ' . $ffmpeg_output . ' ' . $convertedfull, $command_output, t('running qt-faststart'));

      // Delete the temporary output file.
      file_delete($ffmpeg_output);
    }

    //lets check to make sure our file exists, if not error out
    if (!file_exists($convertedfull) || ($filesize = filesize($convertedfull)) === 0) {
      watchdog('video_ffmpeg', 'Video conversion failed for preset %preset: result file was not found.', array(
        '%preset' => $presetname,
      ), WATCHDOG_ERROR);
      $result = FALSE;
      break;
    }

    //Create result object
    $converted_files[] = $file = new stdClass();
    $file->vid = intval($video->vid);
    $file->filename = basename($converted);
    $file->filepath = $converted;
    $file->filemime = file_get_mimetype($converted);
    $file->filesize = $filesize;
    $file->preset = $presetname;
  }
  chdir($drupaldir);
  rmdirr($tmpdir);

  // Update our video_files table with the converted video information.
  if ($result) {
    $result = db_query('UPDATE {video_files} SET status = %d, completed = %d, data = "%s" WHERE vid = %d', VIDEO_RENDERING_COMPLETE, time(), serialize($converted_files), $video->vid);

    // Prepare the watchdog statement
    $destinationfiles = array();
    foreach ($converted_files as $file) {
      $destinationfiles[] = $file->filepath;
    }
    watchdog('video_ffmpeg', 'Successfully converted %orig to !destination-files', array(
      '%orig' => $video->filepath,
      '!destination-files' => implode(', ', $destinationfiles),
    ), WATCHDOG_INFO);
  }
  else {

    // Remove files that have been created
    foreach ($converted_files as $file) {
      file_delete($file->filepath);
    }

    // Try to move back the original file
    $filepath = $video->filepath;
    file_move($filepath, $files . '/videos');
    $video->filepath = $filepath;
    drupal_write_record('files', $video, 'fid');
    $this
      ->change_status($video->vid, VIDEO_RENDERING_FAILED);
  }
  return $result;
}