From f53f62a5ecf8343941e2c74d06b429bb271d7df2 Mon Sep 17 00:00:00 2001 From: Heshan Date: Sun, 13 Mar 2011 00:03:05 +0530 Subject: Completed some transcoding stuff and tested the video convert on save. --- includes/conversion.inc | 4 - includes/preset.inc | 11 +- includes/transcoder.inc | 23 ++--- modules/video_ui/video.preset.inc | 12 ++- transcoders/video_ffmpeg.inc | 205 +++++++++++++++----------------------- video.field.inc | 31 +++++- video.module | 25 ----- 7 files changed, 130 insertions(+), 181 deletions(-) diff --git a/includes/conversion.inc b/includes/conversion.inc index b9be2b4..6611e06 100644 --- a/includes/conversion.inc +++ b/includes/conversion.inc @@ -93,10 +93,6 @@ class video_conversion { return $this->transcoder->create_job($video, $nid); } - public function update_job($video) { - return $this->transcoder->update_job($video); - } - public function delete_job($video) { return $this->transcoder->delete_job($video); } diff --git a/includes/preset.inc b/includes/preset.inc index f1c14b8..d3a3fdd 100644 --- a/includes/preset.inc +++ b/includes/preset.inc @@ -36,7 +36,7 @@ class video_preset { } $preset = array(); foreach ($presets as $id => $value) { - $preset[$id] = $value['name'] . ' ' . l(t('edit'), ('admin/config/media/video/presets/preset/' . $value['name'])); + $preset[$value['name']] = $value['name'] . ' ' . l(t('edit'), ('admin/config/media/video/presets/preset/' . $value['name'])); // $help[] = $value['name'] . ' - ' . $value['description'] . ' ' . l(t('edit'), preset_get_preset_path('video', $value['name'])); } @@ -62,10 +62,13 @@ class video_preset { * @return array $properties */ public function properties() { + module_load_include('inc', 'video_ui', 'video.preset'); + $presets = array(); $preset = $this->preset; - return $options['properties']; - if (preset_exists('video', $preset)) - preset_get_settings($preset); + foreach ($preset as $preset_name) { + $presets[$preset_name] = video_get_preset($preset_name); + } + return $presets; } } \ No newline at end of file diff --git a/includes/transcoder.inc b/includes/transcoder.inc index 994ab47..e5f7123 100644 --- a/includes/transcoder.inc +++ b/includes/transcoder.inc @@ -89,22 +89,19 @@ class video_transcoder { } public function convert_video(&$video) { + // load the presets $video_preset = new video_preset(); $presets = $video_preset->properties(); $video->presets = $presets; $output = $this->transcoder->convert_video($video); // if successfully converted the video then update the status to publish - if ($output) + if ($output && variable_get('video_publish_on_complete', TRUE)) // Update our node id to published. We do not do a node_load as it causes editing problems when saving. - db_query("UPDATE {node} SET status=%d WHERE nid=%d", 1, $video->nid); - - // If they are using metadata. - // @TODO : add meta data support -// if (variable_get('video_metadata', FALSE)) { -// module_load_include('inc', 'video', '/includes/metadata'); -// $metadata = new video_metadata; -// $metadata->process($converted); -// } + db_update('node') + ->fields(array( + 'status' => NODE_PUBLISHED)) + ->condition('nid', $video->nid, '=') + ->execute(); return $output; } @@ -171,10 +168,6 @@ class video_transcoder { return $this->transcoder->create_job($video, $nid); } - public function update_job($video) { - return $this->transcoder->update_job($video); - } - public function delete_job($video) { return $this->transcoder->delete_job($video); } @@ -203,8 +196,6 @@ interface transcoder_interface { public function create_job($video, $nid); - public function update_job($video); - public function delete_job($video); public function load_job($fid); diff --git a/modules/video_ui/video.preset.inc b/modules/video_ui/video.preset.inc index 4036c82..981370b 100644 --- a/modules/video_ui/video.preset.inc +++ b/modules/video_ui/video.preset.inc @@ -42,6 +42,16 @@ function video_preset_default_form($form, &$form_state, $preset) { '#collapsible' => TRUE, '#collapsed' => FALSE ); + $video_extension = array(); + foreach (video_video_extensions () as $extension => $theme) { + $video_extension[$extension] = $extension; + } + $form['settings']['video']['video_extension'] = array( + '#type' => 'select', + '#title' => t('Video output extension'), + '#description' => t('Extension of the output video.'), + '#options' => $video_extension + ); $form['settings']['video']['video_codec'] = array( '#type' => 'select', '#title' => t('Video codec'), @@ -523,7 +533,7 @@ function video_preset_delete_confirm_submit($form, &$form_state) { */ function _video_preset_name_validate($element, &$form_state) { $error = video_validate_preset_name($form_state['values']['name']); - if ($error && !isset($form_state['values']['pid']) && !isset ($form_state['values']['default'])) { + if ($error && !isset($form_state['values']['pid']) && !isset($form_state['values']['default'])) { form_set_error('name', $error); } } diff --git a/transcoders/video_ffmpeg.inc b/transcoders/video_ffmpeg.inc index 142eaff..7aed020 100644 --- a/transcoders/video_ffmpeg.inc +++ b/transcoders/video_ffmpeg.inc @@ -58,7 +58,7 @@ class video_ffmpeg implements transcoder_interface { $total_thumbs = variable_get('video_thumbs', 5); $videofile = file_load($video['fid']); //get the actual video file path from the stream wrappers - $videopath = (drupal_realpath($videofile->uri)); + $videopath = drupal_realpath($videofile->uri); //get the playtime from the current transcoder $duration = $this->get_playtime($videopath); @@ -99,108 +99,84 @@ class video_ffmpeg implements transcoder_interface { 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 -// $pathinfo = pathinfo($video->filepath); - // @TODO This about getting the correct path from the filefield if they active it - $files = file_create_path(); - $original = $files . '/videos/original'; - $converted = $files . '/videos/converted'; - - if (!field_file_check_directory($original, FILE_CREATE_DIRECTORY)) { - watchdog('transcoder', 'Video conversion failed. Could not create the directory: ' . $orginal, array(), WATCHDOG_ERROR); - return false; - } - if (!field_file_check_directory($converted, FILE_CREATE_DIRECTORY)) { + // get the paths so tokens will compatible with this + $target = str_replace('original', '', drupal_dirname($video->uri)); + $converted = $target . '/converted/' . $video->fid; + if (!file_prepare_directory($converted, FILE_CREATE_DIRECTORY)) { watchdog('transcoder', 'Video conversion failed. Could not create the directory: ' . $converted, array(), WATCHDOG_ERROR); return false; } - - $original = $original . '/' . $video->filename; - //lets move our video and then convert it. - if (file_move($video, $original)) { - // Update our filepath since we moved it - $update = drupal_write_record('files', $video, 'fid'); - // process presets - $presets = $video->presets; - $converted_files = array(); - foreach ($presets as $name => $preset) { - // reset converted file path - $converted = $files . '/videos/converted'; - //update our filename after the move to maintain filename uniqueness. -// $converted = $converted .'/'. pathinfo($video->filepath, PATHINFO_FILENAME) .'.'. $this->video_extension(); - $converted = file_create_filename(str_replace(' ', '_', pathinfo($video->filepath, PATHINFO_FILENAME)) . '.' . $preset['extension'], $converted); - //call our transcoder -// $command_output = $this->convert_video($video, $converted); - $dimensions = $this->dimensions($video); - $dimention = explode('x', $dimensions); - if ($this->params['enable_faststart'] && in_array($preset['extension'], array('mov', 'mp4'))) { - $ffmpeg_output = file_directory_temp() . '/' . basename($converted); - } else { - $ffmpeg_output = $converted; - } - // Setup our default command to be run. - foreach ($preset['command'] as $command) { - $command = strtr($command, array( - '!cmd_path' => $this->params['cmd_path'], - '!videofile' => '"' . $video->filepath . '"', - '!audiobitrate' => $preset['audio_bitrate'], - '!width' => $dimention[0], - '!height' => $dimention[1], - '!videobitrate' => $preset['video_bitrate'], - '!convertfile' => '"' . $ffmpeg_output . '"', - )); -// print_r($preset['command']); -// die(); - // Process our video -// $command_output = $this->run_command($command); - $command_output = $this->run_command($command); - } - - if ($ffmpeg_output != $converted && 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. - $cmd_path = $this->params['cmd_path']; - $this->params['cmd_path'] = $this->params['faststart_cmd']; - $command_output .= $this->run_command($ffmpeg_output . ' ' . $converted, $verbose); - $this->params['cmd_path'] = $cmd_path; - - // Delete the temporary output file. - file_delete($ffmpeg_output); - } - - //lets check to make sure our file exists, if not error out - if (!file_exists($converted) || !filesize($converted)) { - watchdog('video_conversion', 'Video conversion failed for preset %preset. FFMPEG reported the following output: ' . $command_output, array('%orig' => $video->filepath, '%preset' => $name), WATCHDOG_ERROR); - $this->change_status($video->vid, VIDEO_RENDERING_FAILED); - return FALSE; - } - // Setup our converted video object - $video_info = pathinfo($converted); - //update our converted video - $video->converted = new stdClass(); - $video->converted->vid = $video->vid; - $video->converted->filename = $video_info['basename']; - $video->converted->filepath = $converted; - $video->converted->filemime = file_get_mimetype($converted); - $video->converted->filesize = filesize($converted); - $video->converted->status = VIDEO_RENDERING_COMPLETE; - $video->converted->preset = $name; - $video->converted->completed = time(); - $converted_files[] = $video->converted; + //get the actual video file path from the stream wrappers + $original_video_path = drupal_realpath($video->uri); + // process presets + $presets = $video->presets; + $converted_files = array(); + foreach ($presets as $name => $preset) { + $settings = $preset['settings']; + $converted .= '/' . file_munge_filename(str_replace(' ', '_', pathinfo($original_video_path, PATHINFO_FILENAME)) . '.' . $settings['video_extension'], $settings['video_extension']); + $dimensions = $this->dimensions($video); + $dimention = explode('x', $dimensions); + if ($this->params['enable_faststart'] && in_array($settings['video_extension'], array('mov', 'mp4'))) { + $ffmpeg_output = file_directory_temp() . '/' . basename($converted); + } else { + $ffmpeg_output = $converted; + } + // Setup our default command to be run. + $command = strtr($settings['command'], array( + '!cmd_path' => $this->params['cmd_path'], + '!videofile' => '"' . $original_video_path . '"', + '!audiobitrate' => $settings['audio_bitrate'], + '!width' => $dimention[0], + '!height' => $dimention[1], + '!videobitrate' => $settings['video_bitrate'], + '!convertfile' => '"' . $ffmpeg_output . '"', + )); + // process our video + $command_output = $this->run_command($command); + + + if ($ffmpeg_output != $converted && 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. + $cmd_path = $this->params['cmd_path']; + $this->params['cmd_path'] = $this->params['faststart_cmd']; + $command_output .= $this->run_command($ffmpeg_output . ' ' . $converted, $verbose); + $this->params['cmd_path'] = $cmd_path; + + // Delete the temporary output file. + drupal_unlink($ffmpeg_output); } - // Update our video_files table with the converted video information. - $result = db_query("UPDATE {video_files} SET status=%d, completed=%d, data='%s' WHERE vid=%d", - $video->converted->status, $video->converted->completed, serialize($converted_files), $video->converted->vid); - watchdog('video_conversion', 'Successfully converted %orig to %dest', array('%orig' => $video->filepath, '%dest' => $video->converted->filepath), WATCHDOG_INFO); - return TRUE; - } else { - watchdog('video_conversion', 'Cound not move the video to the original folder.', array(), WATCHDOG_ERROR); - $this->change_status($video->vid, VIDEO_RENDERING_FAILED); - return FALSE; + //lets check to make sure our file exists, if not error out + if (!file_exists($converted) || !filesize($converted)) { + watchdog('video_conversion', 'Video conversion failed for preset %preset. FFMPEG reported the following output: ' . $command_output, array('%orig' => $video->filepath, '%preset' => $name), WATCHDOG_ERROR); + $this->change_status($video->vid, VIDEO_RENDERING_FAILED); + return FALSE; + } + // Setup our converted video object + $video_info = pathinfo($converted); + //update our converted video + $video->converted = new stdClass(); + $video->converted->vid = $video->vid; + $video->converted->filename = $video_info['basename']; + $video->converted->filepath = $converted; + $video->converted->filemime = file_get_mimetype($converted); + $video->converted->filesize = filesize($converted); + $video->converted->status = VIDEO_RENDERING_COMPLETE; + $video->converted->preset = $name; + $video->converted->completed = time(); + $converted_files[] = $video->converted; } + // Update our video_files table with the converted video information. + db_update('video_files') + ->fields(array( + 'status' => VIDEO_RENDERING_COMPLETE, + 'completed' => time(), + 'data' => serialize($converted_files))) + ->condition('vid', $video->converted->vid, '=') + ->execute(); + watchdog('video_conversion', 'Successfully converted %orig to %dest', array('%orig' => $video->filepath, '%dest' => $video->converted->filepath), WATCHDOG_INFO); + return TRUE; } /** @@ -390,23 +366,13 @@ class video_ffmpeg implements transcoder_interface { ->execute(); } - /** - * Interface Implementations - * @see sites/all/modules/video/includes/transcoder_interface#update_job() - */ - public function update_job($video) { - if (!$this->load_job($video['fid'])) - return; - //lets update our table to include the nid - db_query("UPDATE {video_files} SET nid=%d WHERE fid=%d", $video['nid'], $video['fid']); - } - /** * Interface Implementations * @see sites/all/modules/video/includes/transcoder_interface#delete_job() */ public function delete_job($video) { - if (!$video = $this->load_job($video['fid'])) + $video = (object) $video; + if (!$video = $this->load_job($video->fid)) return; // converted output values $converted = unserialize($video->data); @@ -443,26 +409,13 @@ class video_ffmpeg implements transcoder_interface { * @see sites/all/modules/video/includes/transcoder_interface#load_job_queue() */ public function load_job_queue() { - return; +// return; $total_videos = variable_get('video_ffmpeg_instances', 5); $videos = array(); - $result = db_query_range('SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.status as video_status - FROM {video_files} vf LEFT JOIN {files} f ON vf.fid = f.fid + $result = db_query_range('SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.status as video_status + FROM {video_files} vf LEFT JOIN {file_managed} f ON vf.fid = f.fid WHERE vf.status = :vstatus AND f.status = :fstatus ORDER BY f.timestamp', - array(':vstatus' => VIDEO_RENDERING_PENDING, ':fstatus' => FILE_STATUS_PERMANENT), 0, $total_videos, array()); - $job = db_query("SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.data, vf.status as video_status - FROM {video_files} vf LEFT JOIN {file_managed} f ON vf.fid = f.fid WHERE f.fid=vf.fid AND f.fid = :fid", - array(':fid' => $fid)) - ->fetch(); - - $query = db_select('file_managed', 'f'); - $query->join('video_files', 'vf'); - $query->condition('f.status', FILE_STATUS_PERMANENT, '=') - ->condition('vf.status', VIDEO_RENDERING_PENDING, '=') - ->fields('f', array('fid', 'uid', 'filename', 'uri', 'status', 'filemime', 'filesize')) - ->fields('vf', array('vif', 'fid', 'nid', 'dimension', 'status', 'data')) - ->range(0, variable_get('video_ffmpeg_instances', 5)); - $result = $query->execute(); + 0, $total_videos, array(':vstatus' => VIDEO_RENDERING_PENDING, ':fstatus' => FILE_STATUS_PERMANENT)); foreach ($result as $row) { $videos[] = $row; } diff --git a/video.field.inc b/video.field.inc index 0534efc..d81294c 100644 --- a/video.field.inc +++ b/video.field.inc @@ -137,11 +137,32 @@ function video_field_presave($entity_type, $entity, $field, $instance, $langcode function video_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) { file_field_insert($entity_type, $entity, $field, $instance, $langcode, $items); // Create entry for video conversion if auto converison is enabled -// if ($field['settings']['autoconversion'] == 1) { -// foreach ($items as $delta => $item) { -// video_convert_process($item); -// } -// } + if ($field['settings']['autoconversion'] == 1) { + $nid = $entity->vid; + module_load_include('inc', 'video', '/includes/conversion'); + $video_conversion = new video_conversion; + foreach ($items as $delta => $item) { + // skip adding entry if bypass conversion is checked + if ($item['bypass_autoconversion'] == 1 || variable_get('video_bypass_conversion', FALSE)) { + // delete the conversion job if any + $video_conversion->delete_job($item); + return; + } + // Lets verify that we haven't added this video already. Multiple validation fails will cause this to be ran more than once + if (!$video = $video_conversion->load_job($item['fid'])) { + if (!($video_conversion->create_job($item, $nid))) + drupal_set_message(t('Something went wrong with your video job creation. Please check your recent log entries for further debugging.'), 'error'); + } + // if convert on save is checked + if ($item['convert_video_on_save'] == 1 || variable_get('video_convert_on_save', FALSE)) { + if (!$video_conversion->process($item['fid'])) { + drupal_set_message(t('Something went wrong with your video conversion. Please check your recent log entries for further debugging.'), 'error'); + } else { + drupal_set_message(t('Successfully converted your video.')); + } + } + } + } } /** diff --git a/video.module b/video.module index a2be02a..765ee5b 100644 --- a/video.module +++ b/video.module @@ -134,30 +134,6 @@ function video_cron() { } } -/** - * Implementation of hook_form_alter() - * @param string $form - * @param $form_state - * @param $form_id - */ -function video_form_alter(&$form, &$form_state, $form_id) { - if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) { - $form['buttons']['submit']['#submit'][] = 'video_node_update_submit'; - } -} - -function video_node_update_submit($form, &$form_state) { - //lets update our video rending table to include the node id created - if (isset($form_state['nid']) && isset($form_state['values']['video_id']) && is_array($form_state['values']['video_id'])) { - foreach ($form_state['values']['video_id'] as $fid) { - // @TODO : check for enable trancoder - $transcoder = new video_transcoder; - $video = array('nid' => $form_state['nid'], 'fid' => $fid); - $transcoder->update_job($video); - } - } -} - /* * Utility function that will add a preview of thumbnails for you to select when uploading videos. */ @@ -239,7 +215,6 @@ function video_thumb_process(&$element, &$form_state) { function video_file_delete($file) { // @TODO : check for enable trancoder // delete the transcoder job - module_load_include('inc', 'video', '/includes/transcoder'); $transcoder = new video_transcoder; $transcoder->delete_job($file); -- cgit v1.2.3