From b6e86040dd3faa3a70ec16e77220d852bdb09a04 Mon Sep 17 00:00:00 2001 From: Heshan Wanigasooriya Date: Sun, 5 Dec 2010 12:56:20 +0000 Subject: Adding latest files. --- includes/.cvsignore | 1 + includes/conversion.inc | 117 ++++++++++++++++++++++++++ includes/filesystem.inc | 129 +++++++++++++++++++++++++++++ includes/metadata.inc | 118 ++++++++++++++++++++++++++ includes/preset.inc | 106 ++++++++++++++++++++++++ includes/transcoder.inc | 205 ++++++++++++++++++++++++++++++++++++++++++++++ includes/video_helper.inc | 116 ++++++++++++++++++++++++++ 7 files changed, 792 insertions(+) create mode 100644 includes/.cvsignore create mode 100644 includes/conversion.inc create mode 100644 includes/filesystem.inc create mode 100644 includes/metadata.inc create mode 100644 includes/preset.inc create mode 100644 includes/transcoder.inc create mode 100644 includes/video_helper.inc (limited to 'includes') diff --git a/includes/.cvsignore b/includes/.cvsignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/includes/.cvsignore @@ -0,0 +1 @@ +.DS_Store diff --git a/includes/conversion.inc b/includes/conversion.inc new file mode 100644 index 0000000..021640b --- /dev/null +++ b/includes/conversion.inc @@ -0,0 +1,117 @@ +transcoder = new video_transcoder; + } + + /** + * Our main function to call when converting queued up jobs. + */ + public function run_queue() { + if ($videos = $this->load_job_queue()) { + foreach ($videos as $video) { + $this->process($video); + } + //clear cache once completed the conversion to update the file paths + cache_clear_all('*', 'cache_content', true); + } + } + + /** + * Select videos from our queue + * + * @return + * An array containing all the videos to be proccessed. + */ + private function load_job_queue() { + // @TODO : allow only limited jobs to process + return $this->transcoder->load_job_queue(); + } + + /** + * Process the video through ffmpeg. + * + * @param $video + * This can either be the file object or the file id (fid) + * + * @return + * TRUE of FALSE if video was converted successfully. + */ + public function process($video) { + if (is_object($video) && isset($video->fid)) { + $return = $this->render($video); + } else { + $video_object = $this->load_job($video); + $return = $this->render($video_object); + } + return $return; + } + + private function render($video) { + if (!is_object($video)) { + watchdog('video_conversion', 'Video object is not present', array(), WATCHDOG_ERROR); + return FALSE; + } + // Make sure this video is pending or do nothing. + if ($video->video_status == VIDEO_RENDERING_PENDING) { + return $this->transcoder->convert_video($video); + } + return NULL; + } + + /** + * Load a converted video based on the file id ($fid) + * + * @todo: Need to figure something out here for multiple files (HTML 5) + * @param $fid + * Integer of the file id to be loaded. + */ + public function load_completed_job($video) { + return $this->transcoder->load_completed_job($video); + } + + public function create_job($video) { + return $this->transcoder->create_job($video); + } + + public function update_job($video) { + return $this->transcoder->update_job($video); + } + + public function delete_job($video) { + return $this->transcoder->delete_job($video); + } + + /** + * Load a file based on the file id ($fid) + * + * @param $fid + * Integer of the file id to be loaded. + */ + public function load_job($fid) { + return $this->transcoder->load_job($fid); + } + +} + +?> \ No newline at end of file diff --git a/includes/filesystem.inc b/includes/filesystem.inc new file mode 100644 index 0000000..3041ee5 --- /dev/null +++ b/includes/filesystem.inc @@ -0,0 +1,129 @@ +name == $filesystem) + require_once $file->filename; + } + } + } + } + if (class_exists($filesystem)) { + $this->filesystem = new $filesystem; + } else { + drupal_set_message(t('The filesystem is not configured properly.'), 'error'); + } + } + + public function save_file($video) { + return $this->filesystem->save_file($video); + } + + public function prepare_file($video) { + return $this->filesystem->prepare_file($video); + } + + public function load_file(&$video) { + return $this->filesystem->load_file($video); + } + + public function admin_settings() { + $form = array(); + $options = $this->_filesystem(); + $form['vid_filesystem'] = array( + '#type' => 'radios', + '#title' => t('Video Filesystem'), + '#default_value' => variable_get('vid_filesystem', 'drupal'), + '#options' => $options['radios'], + '#description' => t('!list', array('!list' => theme('item_list', $options['help']))), + '#prefix' => '
', + '#suffix' => '
', + ); + $form = $form + $options['admin_settings']; + return $form; + } + + private function _filesystem() { + $files = array(); + // Lets find our transcoder classes and build our radio options + // We do this by scanning our transcoders folder + $form = array('radios' => array(), 'help' => array(), 'admin_settings' => array()); + $path = drupal_get_path('module', 'video') . '/filesystem'; + $files = file_scan_directory($path, '^.*\.inc$'); + // check inside sub modules + $modules = module_list(); + foreach ($modules as $module) { + $mobule_files = array(); + $module_path = drupal_get_path('module', $module) . '/filesystem'; + $mobule_files = file_scan_directory($module_path, '^.*\.inc$'); + $files = array_merge($files, $mobule_files); + } + + foreach ($files as $file) { + if (!module_load_include('inc', 'video', '/filesystem/' . $file->name)) + require_once $file->filename; + $focus = new $file->name; + $form['radios'][$focus->get_value()] = $focus->get_name(); + $form['help'][] = $focus->get_help(); + // creating div for each option + $form['video_' . $focus->get_value() . '_start'] = array( + 'video_' . $focus->get_value() . '_start' => array( + '#type' => 'markup', + '#value' => '
', + ), + ); + $form['video_' . $focus->get_value() . '_end'] = array( + 'video_' . $focus->get_value() . '_end' => array( + '#type' => 'markup', + '#value' => '
', + ), + ); + + $form['admin_settings'] = $form['admin_settings'] + $form['video_' . $focus->get_value() . '_start'] + $focus->admin_settings() + $form['video_' . $focus->get_value() . '_end']; + } + return $form; + } + + public function admin_settings_validate(&$form, &$form_state) { + return $this->filesystem->admin_settings_validate($form, $form_state); + } + +} + +interface filesystem_interface { + + public function save_file($video); + + public function prepare_file($video); + + public function load_file($video); + + public function get_name(); + + public function get_help(); + + public function admin_settings(); + + public function admin_settings_validate($form, &$form_state); +} \ No newline at end of file diff --git a/includes/metadata.inc b/includes/metadata.inc new file mode 100644 index 0000000..42f80b7 --- /dev/null +++ b/includes/metadata.inc @@ -0,0 +1,118 @@ +name == $metadata) + require_once $file->filename; + } + } +// + } + } + if (class_exists($metadata)) { + $this->metadata = new $metadata; + } else { + drupal_set_message(t('The metadata is not configured properly.'), 'error'); + } + } + + public function process($video) { + $command_output = $this->metadata->process($video); + return $command_output; + } + + public function admin_settings() { + $form = array(); + $form['video_metadata'] = array( + '#type' => 'checkbox', + '#title' => t('Enable Metadata'), + '#default_value' => variable_get('video_metadata', FALSE), + '#description' => t('Metadata is particularly useful in video, where information about its contents (such as transcripts of conversations and text descriptions of its scenes) are not directly understandable by a computer, but where efficient search is desirable.'), + ); + $options = $this->_metadata(); + $form['vid_metadata'] = array( + '#type' => 'radios', + '#title' => t('Video Metadata'), + '#default_value' => variable_get('vid_metadata', 'flvtool2'), + '#options' => $options['radios'], + '#description' => t('!list', array('!list' => theme('item_list', $options['help']))), + '#prefix' => '
', + '#suffix' => '
', + ); + $form = $form + $options['admin_settings']; + $form['video_metadata_dimensions'] = array( + '#type' => 'textarea', + '#title' => t('Selectable Dimensions when uploading videos'), + '#description' => t('Enter one dimension per line as Video Resolutions. Each resolution must be in the form of WxH where W=Width and H=Height in pixels. Example dimensions are 1280x720.'), + '#default_value' => variable_get("video_metadata_dimensions", video_default_dimensions()), + ); + + return $form; + } + + private function _metadata() { + $files = array(); + // Lets find our transcoder classes and build our radio options + // We do this by scanning our transcoders folder + $form = array('radios' => array(), 'help' => array(), 'admin_settings' => array()); + $path = drupal_get_path('module', 'video') . '/metadata'; + $files = file_scan_directory($path, '^.*\.inc$'); + // check inside sub modules + $modules = module_list(); + foreach ($modules as $module) { + $mobule_files = array(); + $module_path = drupal_get_path('module', $module) . '/metadata'; + $mobule_files = file_scan_directory($module_path, '^.*\.inc$'); + $files = array_merge($files, $mobule_files); + } + + foreach ($files as $file) { + if (!module_load_include('inc', 'video', '/metadata/' . $file->name)) + require_once $file->filename; + $focus = new $file->name; + $form['radios'][$focus->get_value()] = $focus->get_name(); + $form['help'][] = $focus->get_help(); + $form['admin_settings'] = $form['admin_settings'] + $focus->admin_settings(); + } + return $form; + } + + public function admin_settings_validate($form, $form_state) { + return $this->metadata->admin_settings_validate($form, $form_state); + } + +} + +interface metadata_interface { + + public function get_name(); + + public function get_help(); + + public function process($video); + + public function admin_settings(); + + public function admin_settings_validate($form, &$form_state); +} \ No newline at end of file diff --git a/includes/preset.inc b/includes/preset.inc new file mode 100644 index 0000000..aca0b26 --- /dev/null +++ b/includes/preset.inc @@ -0,0 +1,106 @@ +presets = $preset; + if (!isset($preset)) + $this->presets = variable_get('vid_preset', ''); +//get our configured transcoder. +// if (!isset($preset)) +// $preset = variable_get('vid_preset', 'flash_hq'); +// echo print_r($preset); +// if (!module_load_include('inc', 'video', '/video_preset/' . $preset)) { +// $modules = module_list(); +// foreach ($modules as $module) { +// $mobule_files = array(); +// $module_path = drupal_get_path('module', $module) . '/video_preset'; +// $mobule_files = file_scan_directory($module_path, '^.*\.inc$'); +// if (is_array($mobule_files)) { +// foreach ($mobule_files as $file) { +// if ($file->name == $preset) +// require_once $file->filename; +// } +// } +//// +// } +// } +// if (class_exists($preset)) { +// $this->preset = new $preset; +// } else { +// drupal_set_message(t('The preset is not configured properly.'), 'error'); +// } + } + + public function admin_settings() { + $form = array(); + $options = $this->_preset(); + $form['vid_preset'] = array( + '#type' => 'checkboxes', + '#title' => t('Video transcode presets'), + '#options' => $options['radios'], + '#default_value' => variable_get('vid_preset', array('status', 'promote')), + '#description' => t('!list', array('!list' => theme('item_list', $options['help']))), + '#prefix' => '
', + '#suffix' => '
', + ); +// $form = $form + $options['admin_settings']; + return $form; + } + + private function _preset($presets = null) { +// @TDOO : Observer will match in this case + $files = array(); +// Lets find our transcoder classes and build our radio options +// We do this by scanning our transcoders folder + $form = array('radios' => array(), 'help' => array(), 'properties' => array()); + $path = drupal_get_path('module', 'video') . '/video_preset'; + $files = file_scan_directory($path, '^.*\.inc$'); +// check inside sub modules + $modules = module_list(); + foreach ($modules as $module) { + $mobule_files = array(); + $module_path = drupal_get_path('module', $module) . '/video_preset'; + $mobule_files = file_scan_directory($module_path, '^.*\.inc$'); + $files = array_merge($files, $mobule_files); + } + + foreach ($files as $file) { + if (!module_load_include('inc', 'video', '/video_preset/' . $file->name)) + require_once $file->filename; + $focus = new $file->name; + $form['radios'][$focus->get_value()] = $focus->get_name(); + $form['help'][] = $focus->get_help(); +// $form['admin_settings'] = $form['admin_settings'] + $focus->admin_settings(); + if (is_array($presets) && !empty($presets[$focus->get_value()])) + $form['properties'][$focus->get_value()] = $focus->get_properties(); +// echo $focus->get_value(); + } + return $form; + } + + public function properties() { + $presets = $this->presets; + $options = $this->_preset($presets); + return $options['properties']; + } + +} + +interface video_preset_interface { + + public function get_name(); + + public function get_help(); + + public function get_properties(); +} \ No newline at end of file diff --git a/includes/transcoder.inc b/includes/transcoder.inc new file mode 100644 index 0000000..c9d79b8 --- /dev/null +++ b/includes/transcoder.inc @@ -0,0 +1,205 @@ +transcoder = $this->get_instance($transcoder); + } + + /** + * + * @param $transcoder + */ + private function get_instance($transcoder = null) { + //get our configured transcoder. + if (!isset($transcoder)) + $transcoder = variable_get('vid_convertor', 'video_ffmpeg'); +// module_load_include('inc', 'video', '/transcoders/' . $transcoder); + if (!module_load_include('inc', 'video', '/transcoders/' . $transcoder)) { + $modules = module_list(); + $files = array(); + foreach ($modules as $module) { + $module_path = drupal_get_path('module', $module) . '/transcoders'; + $inc_files = file_scan_directory($module_path, '^.*\.inc$'); + if (!empty($inc_files)) + $files[$module] = $inc_files; + } + // @TODO : add lazy load + foreach ($files as $module => $_files) { + foreach ($_files as $file) { + if ($file->name == $transcoder) + module_load_include('inc', $module, '/transcoders/' . $file->name); + } + } + } + + if (class_exists($transcoder)) { + $transcoder_instance = new $transcoder; + $this->transcoder = $transcoder_instance; + return $transcoder_instance; + } else { + drupal_set_message(t('The transcoder is not configured properly.'), 'error'); + } + } + + public function generate_thumbnails($video) { + return $this->transcoder->generate_thumbnails($video); + } + + public function convert_video(&$video) { + module_load_include('inc', 'video', '/includes/preset'); + $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) + // 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); +// } + return $output; + } + + public function admin_settings() { + $form = array(); + $options = $this->_transcoders(); + $form['vid_convertor'] = array( + '#type' => 'radios', + '#title' => t('Video transcoder'), + '#default_value' => variable_get('vid_convertor', 'video_ffmpeg'), + '#options' => $options['radios'], + '#description' => t('Selecting a video transcoder will help you convert videos and generate thumbnails. !list', array('!list' => theme('item_list', $options['help']))), + '#prefix' => '
', + '#suffix' => '
', + ); + $form = $form + $options['admin_settings']; + return $form; + } + + public function admin_settings_validate($form, &$form_state) { + return $this->transcoder->admin_settings_validate($form, $form_state); + } + + private function _transcoders() { + // @TODO : think to change this to observer patteren + $files = array(); + // Lets find our transcoder classes and build our radio options + // We do this by scanning our transcoders folder + $form = array('radios' => array(), 'help' => array(), 'admin_settings' => array()); + $path = drupal_get_path('module', 'video') . '/transcoders'; + $files = file_scan_directory($path, '^.*\.inc$'); + // check inside sub modules + $modules = module_list(); + foreach ($modules as $module) { + $mobule_files = array(); + $module_path = drupal_get_path('module', $module) . '/transcoders'; + $mobule_files = file_scan_directory($module_path, '^.*\.inc$'); + $files = array_merge($files, $mobule_files); + } + + foreach ($files as $file) { + if (!module_load_include('inc', 'video', '/transcoders/' . $file->name)) + require_once $file->filename; + $focus = new $file->name; + $form['radios'][$focus->get_value()] = $focus->get_name(); + $form['help'][] = $focus->get_help(); + $form['admin_settings'] = $form['admin_settings'] + $focus->admin_settings(); + } +// //we need to move our video/thumbnail fieldsets to the bottom of our form as they are used for each trancoder +// $autothumb = $form['admin_settings']['autothumb']; +// $autoconv = $form['admin_settings']['autoconv']; +// unset($form['admin_settings']['autothumb'], $form['admin_settings']['autoconv']); +// if(!$this->transcoder->is_wsod()) +// $form['admin_settings']['autothumb'] = $autothumb; +// $form['admin_settings']['autoconv'] = $autoconv; + return $form; + } + + public function get_dimensions($video) { + return $this->transcoder->get_dimensions($video); + } + + public function create_job($video) { + return $this->transcoder->create_job($video); + } + + public function update_job($video) { + return $this->transcoder->update_job($video); + } + + public function delete_job($video) { + return $this->transcoder->delete_job($video); + } + + /** + * Load a file based on the file id ($fid) + * + * @param $fid + * Integer of the file id to be loaded. + */ + public function load_job($fid) { + return $this->transcoder->load_job($fid); + } + + public function load_job_queue() { + return $this->transcoder->load_job_queue(); + } + + public function load_completed_job(&$video) { + return $this->transcoder->load_completed_job($video); + } + +} + +interface transcoder_interface { + + public function create_job($video); + + public function update_job($video); + + public function delete_job($video); + + public function load_job($fid); + + public function load_job_queue(); + + public function load_completed_job(&$video); + + public function change_status($vid, $status); + + public function generate_thumbnails($video); + + public function convert_video($video); + + public function get_name(); + + public function get_value(); + + public function get_help(); + + public function admin_settings(); + + public function admin_settings_validate($form, &$form_state); +} \ No newline at end of file diff --git a/includes/video_helper.inc b/includes/video_helper.inc new file mode 100644 index 0000000..16598f9 --- /dev/null +++ b/includes/video_helper.inc @@ -0,0 +1,116 @@ +fid = $element['#item']['fid']; + $video->original = $element['#item']; + $extension = strtolower(pathinfo($element['#item']['filename'], PATHINFO_EXTENSION)); + $video->files->{$extension}->filename = pathinfo($element['#item']['filepath'], PATHINFO_FILENAME) . '.' . $extension; + $video->files->{$extension}->filepath = $element['#item']['filepath']; + $video->files->{$extension}->url = file_create_url($element['#item']['filepath']); + $video->files->{$extension}->extension = $extension; + $video->player = strtolower(pathinfo($element['#item']['filename'], PATHINFO_EXTENSION)); + $video->width = trim($dimensions[0]); + $video->height = trim($dimensions[1]); + $video->player_width = trim($player_dimensions[0]); + $video->player_height = trim($player_dimensions[1]); + $video->thumbnail = $this->thumbnail_object($element); + $video->formatter = $element['#formatter']; + $video->autoplay = variable_get('video_autoplay', TRUE); + $video->autobuffering = variable_get('video_autobuffering', TRUE); + $video->theora_player = variable_get('video_ogg_player', 'http://theora.org/cortado.jar'); + // lets find out if we have transcoded this file and update our paths. + if (isset($field['widget']['autoconversion']) && $field['widget']['autoconversion'] + && !$element['#item']['data']['bypass_autoconversion']) { + // discard all existing file data + $video->files = new stdClass(); + module_load_include('inc', 'video', '/includes/conversion'); + $conversion = new video_conversion; + $conversion->load_completed_job($video); + } +// echo '
';
+//    print_r($video);
+//    die();
+    // Let othere module to load the video files by referance
+    // Lets find out if we have pushed this file to the cdn if enabled.
+    // @TODO : add correct filesystem load to this
+    $filesystem = variable_get('vid_filesystem', 'drupal');
+    if ($filesystem != 'drupal' && !module_exists('video_zencoder')) {
+      module_load_include('inc', 'video', '/includes/filesystem');
+      $filesystem = new video_filesystem();
+      $filesystem->load_file($video);
+    }
+
+
+    // Moved to last to recheck incase we changed our extension above.
+    $video->flash_player = variable_get('video_extension_' . $video->player . '_flash_player', '');
+
+    // Return our object
+    return $video;
+  }
+
+  public function thumbnail_object($element) {
+    $field = content_fields($element['#field_name'], $element['#type_name']);
+    // Build our thumbnail object
+    $thumbnail = new stdClass();
+    $thumbnail->filepath = '';
+    $thumbnail->url = '';
+    //@todo future enhancements for our thumbnails
+    $thumbnail->alt = '';
+    $thumbnail->title = '';
+    $thumbnail->description = '';
+
+    // Setup our thumbnail path.
+    $use_default_img = isset($element['#item']['data']['use_default_video_thumb']) ? $element['#item']['data']['use_default_video_thumb'] : false;
+    if ($use_default_img && !empty($field['widget']['default_video_thumb']['filepath'])) {
+      $thumbnail->filepath = $field['widget']['default_video_thumb']['filepath'];
+    } elseif (isset($element['#item']['data']['video_thumb']) ? $element['#item']['data']['video_thumb'] : false) {
+      $thumbnail->filepath = $element['#item']['data']['video_thumb'];
+    } else {
+      //need some type of default if nothing is present
+      //drupal_set_message(t('No thumbnail has been configured for the video.'), 'error');
+    }
+    //lets check for an imagecache preset
+    if (isset($element['imagecache_preset'])) {
+      $thumbnail->url = imagecache_create_url($element['imagecache_preset'], $thumbnail->filepath);
+      $thumbnail->filepath = imagecache_create_path($element['imagecache_preset'], $thumbnail->filepath);
+    } else {
+      $thumbnail->url = file_create_url($thumbnail->filepath);
+    }
+
+    //swftools appends sites/default/files to the front of our path...
+    //@todo Is this a setting?  Need to figure this out.
+    $thumbnail->swfthumb = $thumbnail->filepath;
+    // Return our object
+    return $thumbnail;
+  }
+
+}
-- 
cgit v1.2.3