From 18fbdce5034299832762b72e4653bf6028e8252d Mon Sep 17 00:00:00 2001 From: Fabio Varesano Date: Thu, 11 Jan 2007 07:43:59 +0000 Subject: Added *draft* and *incomplete* support for video conversion throught the video_render.php script Added functions for video_render.php to video_ffmpeg_helper.module Fixed bug #108445 reported by incom (http://drupal.org/user/64246) Call to undefined function: module_exist() in /home/..../modules/video/views_video.inc on line 69 --- .../video_ffmpeg_helper/video_ffmpeg_helper.module | 75 ++++++++++++-- plugins/video_ffmpeg_helper/video_render.php | 110 +++++++++++++++++++++ 2 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 plugins/video_ffmpeg_helper/video_render.php (limited to 'plugins/video_ffmpeg_helper') diff --git a/plugins/video_ffmpeg_helper/video_ffmpeg_helper.module b/plugins/video_ffmpeg_helper/video_ffmpeg_helper.module index 96e16dc..16db8f4 100644 --- a/plugins/video_ffmpeg_helper/video_ffmpeg_helper.module +++ b/plugins/video_ffmpeg_helper/video_ffmpeg_helper.module @@ -8,6 +8,13 @@ * @author Fabio Varesano */ +/** + * Define some constants +*/ +define('VIDEO_RENDERING_PENGING', 0); +define('VIDEO_RENDERING_ACTIVE', 5); +define('VIDEO_RENDERING_COMPLETE', 10); + /** * Implementation of hook_help(). @@ -132,6 +139,32 @@ function video_ffmpeg_helper_admin_settings() { '#title' => t('Debug auto-thumbnail process'), '#default_value' => variable_get('video_ffmpeg_helper_auto_thumbnail_debug', false), ); + + // automatic video conversion settings + $form['autoconv'] = array( + '#type' => 'fieldset', + '#title' => t('Automatic video conversion'), + '#collapsible' => TRUE, + '#collapsed' => TRUE + ); + $form['autoconv']['video_ffmpeg_helper_auto_conversion'] = array( + '#type' => 'checkbox', + '#title' => t('Auto conversion for videos'), + '#description' => t('If set up correctly, this will auto-convert each uploaded video to the configured format.') . '
' . t("IMPORTANT: you will need the video_render.php correctly configured and run by cron. See README.txt for more informations."), + '#default_value' => variable_get('video_ffmpeg_helper_auto_conversion', false), + ); + $form['autoconv']['video_ffmpeg_helper_auto_converter_options'] = array( + '#type' => 'textfield', + '#title' => t('Video thumbnailer options'), + '#description' => t('Provide the ffmpeg options to configure the video conversion. Available argument values are: ').'
  1. '.t('%videofile (the video file to convert)').'
  2. '.t('%convertfile (a newly created file to store the converted file)').'
', + '#default_value' => variable_get('video_ffmpeg_helper_auto_converter_options', '-y -i %videofile -f flv %convertfile'), + ); + $form['autoconv']['video_ffmpeg_helper_auto_converter_busy_video_path'] = array( + '#type' => 'textfield', + '#title' => t('Busy video path'), + '#description' => t('Provide the relative path to a video displayed when the video is being rendered.'), + '#default_value' => variable_get('video_ffmpeg_helper_auto_converter_busy_video_path', 'busy.flv'), + ); return system_settings_form($form); } @@ -141,7 +174,7 @@ function video_ffmpeg_helper_admin_settings() { */ function video_ffmpeg_helper_form_alter($form_id, &$form) { - //print_r($form); + //print_r($form); if($form_id == 'video_node_form') { if (function_exists('_image_check_settings')) { @@ -154,7 +187,7 @@ function video_ffmpeg_helper_form_alter($form_id, &$form) { } } - if(variable_get('video_ffmpeg_helper_auto_resolution', false)) { + if(variable_get('video_ffmpeg_helper_auto_resolution', false) || variable_get('video_ffmpeg_helper_auto_convert', false)) { $form['video']['videox'] = NULL; $form['video']['videoy'] = NULL; } @@ -182,10 +215,19 @@ function video_ffmpeg_helper_nodeapi(&$node, $op, $teaser) { if(variable_get('video_ffmpeg_helper_auto_resolution', false) || variable_get('video_ffmpeg_helper_auto_playtime', false)) { _video_ffmpeg_helper_get_video_info($node); } + break; - case 'prepare': + case 'insert': + if(variable_get('video_ffmpeg_helper_auto_conversion', false)) { + // add rendering job to queue + _video_ffmpeg_helper_add_rendering($node); + } + + break; + case 'prepare': + ; // for future uses break; case 'view': @@ -193,7 +235,7 @@ function video_ffmpeg_helper_nodeapi(&$node, $op, $teaser) { break; case 'delete': - ; // for future uses + db_query('DELETE FROM {video_rendering} WHERE vid = %d AND nid = %d', $node->vid, $node->nid); break; } @@ -201,6 +243,25 @@ function video_ffmpeg_helper_nodeapi(&$node, $op, $teaser) { } +/** + * Add a video conversion rendering process to the queue +*/ +function _video_ffmpeg_helper_add_rendering(&$node) { + $file = $_SESSION['video_upload_file_stored']->filepath; + //print_r($node); die; + db_query('INSERT INTO {video_rendering} (vid, nid, origfile, pid, status, started, completed) VALUES (%d, %d, "%s", %d, %d, %d, %d)', $node->vid, $node->nid, $file, 0, VIDEO_RENDERING_PENGING, 0, 0); + + // let's add the rendering in progress video + $node->vidfile = variable_get('video_ffmpeg_helper_auto_converter_busy_video_path', 'busy.flv'); + db_query('UPDATE {video} SET vidfile = "%s" WHERE nid=%d AND vid=%d', $node->vidfile, $node->nid, $node->vid); + +} + + + +/** + * Get some informations from the video file +*/ function _video_ffmpeg_helper_get_video_info(&$node) { // escape file name for safety @@ -216,7 +277,7 @@ function _video_ffmpeg_helper_get_video_info(&$node) { $command_output = ob_get_contents(); ob_end_clean(); - print $command_output; + // print $command_output; if(variable_get('video_ffmpeg_helper_auto_resolution', false)) { // get resolution @@ -231,13 +292,13 @@ function _video_ffmpeg_helper_get_video_info(&$node) { } - if(variable_get('video_ffmpeg_helper_auto_resolution', false) || variable_get('video_ffmpeg_helper_auto_playtime', false)) { + if(variable_get('video_ffmpeg_helper_auto_playtime', false)) { // get playtime $pattern = '/[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]/'; preg_match_all($pattern, $command_output, $matches, PREG_PATTERN_ORDER); $playtime = $matches[0][0]; - // ffmpge return lenght as 00:00:31.1 Let's get palytime from that + // ffmpge return lenght as 00:00:31.1 Let's get playtime from that $hmsmm = explode(":", $playtime); $tmp = explode(".", $hmsmm[2]); diff --git a/plugins/video_ffmpeg_helper/video_render.php b/plugins/video_ffmpeg_helper/video_render.php new file mode 100644 index 0000000..eddae56 --- /dev/null +++ b/plugins/video_ffmpeg_helper/video_render.php @@ -0,0 +1,110 @@ + + */ + + +/** + * Configuration constats +*/ +define(VIDEO_RENDERING_FFMPEG_PATH, '/usr/bin/ffmpeg'); // set to the ffmpeg executable +define(VIDEO_RENDERING_TEMP_PATH, '/tmp/video'); // set to the temp file path + + +/** + * Define some constants +*/ +define(VIDEO_RENDERING_PENGING, 0); +define(VIDEO_RENDERING_ACTIVE, 5); +define(VIDEO_RENDERING_COMPLETE, 10); + + +include_once './includes/bootstrap.inc'; +drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); + +video_render_main(); + +/** + * Main for video_render.php +*/ +function video_render_main() { + + if($job = video_render_select()) { + video_render_start($job); + } + else { + print 'no jobs to schedule' . "\n"; + } +} + + +/** + * Starts rendering for a job +*/ +function video_render_start($job) { + // escape file name for safety + $videofile = escapeshellarg($job->origfile); + $convfile = tempnam(VIDEO_RENDERING_TEMP_PATH, 'video-rendering'); + $converter = VIDEO_RENDERING_FFMPEG_PATH; + $options = preg_replace(array('/%videofile/', '/%convertfile/'), array($videofile, $convfile), variable_get('video_ffmpeg_helper_auto_converter_options', '-y -i %videofile -f flv %convertfile.flv')); + + $command = "$converter $options"; + + print('executing ' . $command); + + //execute the command + ob_start(); + passthru($command." 2>&1", $command_return); + $command_output = ob_get_contents(); + ob_end_clean(); + + print $command_output; + + if (!file_exists($convfile)) { + print 'video conversion failed'; + // TODO: better error handling + } + else { + // move the video to the definitive location + $file = array( + 'filename' => $job->origfile . ".flv", + 'filemime' => 'application/octet-stream', // is there something better??? + 'filesize' => filesize($convfile), + 'filepath' => $convfile, + 'nid' => $job->nid, + ); + + $file = ((object) $file); + + $dest_dir = variable_get('video_upload_default_path', 'videos') .'/'; + + //print file_directory_path() . '/' . $dest_dir . basename($file->filename); + if (file_move($file, $dest)) { + $file->fid = db_next_id('{files}_fid'); + print_r($file); + db_query("INSERT INTO {files} (fid, nid, filename, filepath, filemime, filesize) VALUES (%d, %d, '%s', '%s', '%s', %d)", $file->fid, $job->nid, $file->filename, $file->filepath, $file->filemime, $file->filesize); + + db_query("INSERT INTO {file_revisions} (fid, vid, list, description) VALUES (%d, %d, %d, '%s')", $file->fid, $job->vid, $file->list, $file->description); + + db_query('UPDATE {video} SET vidfile = "%s" WHERE nid=%d AND vid=%d', $file->filename, $job->nid, $job->vid); + } + else { + print 'error moving video to the final directory'; + } + } +} + + +/** + * Select a job from the queue +*/ +function video_render_select() { + $result = db_query('SELECT * FROM {video_rendering} vr INNER JOIN {node} n ON vr.vid = n.vid INNER JOIN {video} v ON n.vid = v.vid WHERE n.nid = v.nid AND vr.nid = n.nid AND vr.status = %d ORDER BY n.created', VIDEO_RENDERING_PENDING); + + return db_fetch_object($result); +} -- cgit v1.2.3