| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * @file 4 * Transcoder class file to handle Zencoder settings and conversions. 5 * @TODO 6 * - Cancel transcode job when delete. 7 * - Add number of cronjobs pertime set to 5 now. 8 * - Replace load_completed_job with load_job 9 * - Add a metadata extractor class to extract width and height 10 * 11 */ 12 module_load_include('inc', 'video', 'includes/transcoder'); 13 14 class video_zencoder implements transcoder_interface { 15 private $name = 'Zencoder'; 16 private $value = 'video_zencoder'; 17 18 public function generate_thumbnails($video) { 19 global $user; 20 21 $job = $this->load_job($video['fid']); 22 $complete = $job && $job->video_status == VIDEO_RENDERING_COMPLETE; 23 24 $final_thumb_path = video_thumb_path($video); 25 $number_of_thumbs = $complete ? variable_get('video_thumbs', 5) : 1; 26 27 $files = array(); 28 for ($i = 0; $i < $number_of_thumbs; $i++) { 29 $filename = $video['fid'] .'_'. sprintf('%04d', $i) .'.png'; 30 $thumbfile = $final_thumb_path .'/'. $filename; 31 32 if (!$complete) { 33 $default = drupal_get_path('module', 'video') .'/images/no-thumb.png'; 34 $thumbfile = video_thumb_path(NULL, FALSE) .'/no-thumb.png'; 35 36 // The default file is shared between videos 37 if (!is_file($thumbfile)) { 38 file_copy($default, $thumbfile, FILE_EXISTS_REPLACE); 39 } 40 } 41 elseif (!is_file($thumbfile)) { 42 break; 43 } 44 45 // Begin building the file object. 46 $file = new stdClass(); 47 $file->uid = $user->uid; 48 $file->status = FILE_STATUS_TEMPORARY; 49 $file->filename = $filename; 50 $file->filepath = $thumbfile; 51 $file->filemime = 'image/png'; 52 $file->filesize = filesize($thumbfile); 53 $file->timestamp = time(); 54 $files[] = $file; 55 } 56 57 return $files; 58 } 59 60 public function video_converted_extension() { 61 return variable_get('video_zencoder_ext', 'flv'); 62 } 63 64 public function convert_video($video) { 65 // load the S3 lib 66 module_load_include('lib.inc', 'video_s3'); 67 $s3 = new video_amazon_s3(); 68 69 // get the active jobs and check for the status 70 if ($video->video_status == VIDEO_RENDERING_ACTIVE) { 71 return FALSE; 72 } 73 74 // We need to check if this file id exists in our S3 table to avoid file not found error. 75 if ($s3_file = $s3->verify($video->fid)) { 76 // This is a s3 file, lets verify it has been pushed and if so lets push to Zencoder queue. 77 if ($s3_file->status == VIDEO_S3_COMPLETE) { 78 $video_s3 = $s3_file; 79 } 80 } 81 else { 82 watchdog('zencoder', 'You must activate the Video S3 module to work with Zencoder, file is not found in S3 table.', array(), WATCHDOG_ERROR); 83 return FALSE; 84 } 85 86 // If we have a video lets go ahead and send it. 87 if ($video_s3 != NULL) { 88 $this->change_status($video->vid, VIDEO_RENDERING_ACTIVE); 89 $video_s3->dimensions = $video->dimensions; 90 $video_s3->presets = $video->presets; 91 92 module_load_include('lib.inc', 'video_zencoder'); 93 $zc = new video_zencoder_api(); 94 95 if ($encoding_job = $zc->create($video_s3)) { 96 // Update our table. 97 $video->vid = $video->vid; 98 99 //job id 100 $video->jobid = $encoding_job->id; 101 $outputs = new stdClass(); 102 foreach ($encoding_job->outputs as $output) { 103 $outputs->{$output->id}->id = $output->id; 104 $outputs->{$output->id}->label = $output->label; 105 $outputs->{$output->id}->url = $output->url; 106 } 107 $video->data = serialize($outputs); 108 109 // write output values to the table 110 if ($this->update($video)) { 111 watchdog('zencoder', 'Successfully created Zencoder trancoding job @jobid for video @video.', array('@jobid' => $video->jobid, '@video' => $video_s3->filename), WATCHDOG_INFO); 112 } 113 } else { 114 watchdog('zencoder', 'Failed to queue file %file to Zencoder.', array('%file' => $s3_file->filepath), WATCHDOG_ERROR); 115 $this->change_status($video->vid, VIDEO_RENDERING_FAILED); 116 } 117 } else { 118 watchdog('zencoder', 'We did not find the file id @fid or it is still queued for S3 push.', array('@fid' => $video->fid), WATCHDOG_DEBUG); 119 } 120 121 return FALSE; 122 } 123 124 /** 125 * Interface Implementations 126 * @see sites/all/modules/video/includes/transcoder_interface#get_name() 127 */ 128 public function get_name() { 129 return $this->name; 130 } 131 132 /** 133 * Interface Implementations 134 * @see sites/all/modules/video/includes/transcoder_interface#get_value() 135 */ 136 public function get_value() { 137 return $this->value; 138 } 139 140 /** 141 * Interface Implementations 142 * @see sites/all/modules/video/includes/transcoder_interface#get_help() 143 */ 144 public function get_help() { 145 return l(t('Zencoder'), 'http://zencoder.com/'); 146 } 147 148 /** 149 * Interface Implementations 150 * @see sites/all/modules/video/includes/transcoder_interface#admin_settings() 151 */ 152 public function admin_settings() { 153 global $user; 154 // check amazon s3 module is exists or not 155 if (!module_exists('video_s3')) { 156 drupal_set_message(t('You must enable Video Amazon S3 Module to enable this module.'), 'error'); 157 } 158 159 $form = array(); 160 $form['video_zencoder_start'] = array( 161 '#type' => 'markup', 162 '#value' => '<div id="video_zencoder">', 163 ); 164 $zencoder_api = variable_get('video_zencoder_api_key', NULL); 165 if (empty($zencoder_api)) { 166 $form['zencoder_user'] = array( 167 '#type' => 'fieldset', 168 '#title' => t('Zencoder User'), 169 '#collapsible' => FALSE, 170 '#collapsed' => FALSE, 171 '#description' => t('Save configurations to create your !link account to transcode and manage your videos using Zencoder API. Once you save your configuration this will automatically create an account on Zencoder.com and password and all ther other relevant details will be emailed to you.', array('!link' => l(t('Zencoder.com'), 'http://zencoder.com'))) 172 ); 173 $form['zencoder_user']['zencoder_username'] = array( 174 '#type' => 'textfield', 175 '#title' => t('Your email address'), 176 '#default_value' => variable_get('zencoder_username', variable_get('site_mail', '')), 177 '#size' => 50, 178 '#description' => t('Make sure the email is accurate, since we will send all the password details to manage transcoding online and API key details to this.<br/>If you already have a Zencoder account, enter the e-mail address that is associated with your Zencoder account.') 179 ); 180 181 $form['zencoder_user']['agree_terms_zencoder'] = array( 182 '#type' => 'checkbox', 183 '#title' => t('Agree Zencoder Terms and Conditions.'), 184 '#default_value' => variable_get('agree_terms_zencoder', TRUE), 185 '#description' => t('Read terms and conditions on !link.', array('!link' => l(t('Zencoder.com'), 'http://zencoder.com'))), 186 ); 187 } else { 188 // Zencoder API is exists 189 $form['zencoder_info'] = array( 190 '#type' => 'fieldset', 191 '#title' => t('Zencoder API'), 192 '#collapsible' => FALSE, 193 '#collapsed' => FALSE, 194 ); 195 $form['zencoder_info']['video_zencoder_api_key'] = array( 196 '#type' => 'textfield', 197 '#title' => t('Zencoder API Key'), 198 '#default_value' => variable_get('video_zencoder_api_key', null), 199 '#description' => t('Zencoder API Key. Click <b>Reset to default</b> button to add a new account.') 200 ); 201 $form['zencoder_info']['video_thumbs'] = array( 202 '#type' => 'textfield', 203 '#title' => t('Number of thumbnails'), 204 '#description' => t('Number of thumbnails to display from video.'), 205 '#default_value' => variable_get('video_thumbs', 5), 206 '#size' => 5 207 ); 208 $form['zencoder_info']['video_thumbs_size'] = array( 209 '#type' => 'textfield', 210 '#title' => t('Dimension of thumbnails'), 211 '#description' => t('Size of thumbnails to extract from video.'), 212 '#default_value' => variable_get('video_thumbs_size', '160x120'), 213 '#size' => 10 214 ); 215 global $base_url; 216 $form['zencoder_info']['video_zencoder_postback'] = array( 217 '#type' => 'textfield', 218 '#title' => t('Postback URL for Zencoder'), 219 '#description' => t('Important: Do not change this if you do not know what your doing.<br/>This postback URL will receive video data when they are completed.'), 220 '#default_value' => variable_get('video_zencoder_postback', url('postback/jobs', array('absolute' => TRUE))), 221 ); 222 } 223 $form['video_zencoder_end'] = array( 224 '#type' => 'markup', 225 '#value' => '</div>', 226 ); 227 return $form; 228 } 229 230 /** 231 * Interface Implementations 232 * @see sites/all/modules/video/includes/transcoder_interface#admin_settings_validate() 233 */ 234 public function admin_settings_validate($form, &$form_state) { 235 $zencoder_api = isset($form_state['values']['video_zencoder_api_key']) ? $form_state['values']['video_zencoder_api_key'] : NULL; 236 if (!empty($zencoder_api) || $form_state['values']['vid_convertor'] != 'video_zencoder') { 237 if (variable_get('vid_filesystem', 'drupal') != 'video_s3') { 238 form_set_error('video_zencoder', t('You must enable Amazon S3 at !link.', array('!link' => l(t('the File System tab'), 'admin/settings/video/filesystem')))); 239 } 240 return; 241 } 242 243 $errors = false; 244 // check terms and condition 245 if ($form_state['values']['agree_terms_zencoder'] == 0) { 246 $errors = true; 247 form_set_error('agree_terms_zencoder', t('You must agree to the terms and conditions.')); 248 } 249 // check for email exists 250 // Validate the e-mail address: 251 if ($error = user_validate_mail($form_state['values']['zencoder_username'])) { 252 $errors = true; 253 form_set_error('zencoder_username', $error); 254 } 255 256 // get the API key from zencoder and save it to variable 257 if (!$errors) { 258 module_load_include('lib.inc', 'video_zencoder'); 259 $zc = new video_zencoder_api(); 260 261 $result = $zc->create_user($form_state['values']['zencoder_username']); 262 if ($result !== true) { 263 form_set_error('zencoder_username', $result); 264 } 265 } 266 } 267 268 /** 269 * Return the dimensions of a video 270 */ 271 public function get_dimensions($video) { 272 // @TODO get object properties 273 return NULL; 274 } 275 276 public function create_job($video) { 277 return db_query("INSERT INTO {video_zencoder} (fid, status, dimensions) VALUES (%d, %d, '%s')", $video['fid'], VIDEO_RENDERING_PENDING, $video['dimensions']); 278 } 279 280 public function update_job($video) { 281 if (!$this->load_job($video['fid'])) 282 return; 283 //lets update our table to include the nid 284 db_query("UPDATE {video_zencoder} SET nid=%d WHERE fid=%d", $video['nid'], $video['fid']); 285 } 286 287 public function delete_job($video) { 288 if (!$this->load_job($video->fid)) 289 return; 290 //lets get all our videos and unlink them 291 $sql = db_query("SELECT vid FROM {video_zencoder} WHERE fid=%d", $video->fid); 292 //we loop here as future development will include multiple video types (HTML 5) 293 while ($row = db_fetch_object($sql)) { 294 // @TODO : cancel the job to transcode 295 } 296 //now delete our rows. 297 db_query('DELETE FROM {video_zencoder} WHERE fid = %d', $video->fid); 298 } 299 300 public function load_job($fid) { 301 $job = db_fetch_object(db_query('SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.status as video_status FROM {video_zencoder} vf INNER JOIN {files} f ON vf.fid = f.fid WHERE f.fid = %d', $fid)); 302 if (empty($job)) { 303 return FALSE; 304 } 305 return $job; 306 } 307 308 public function load_job_queue() { 309 // load jobs with status as pending and active both 310 $total_videos = variable_get('video_ffmpeg_instances', 5); 311 $videos = array(); 312 $result = db_query_range('SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.status as video_status FROM {video_zencoder} vf LEFT JOIN {files} f ON vf.fid = f.fid WHERE vf.status = %d AND f.status = %d ORDER BY f.timestamp', 313 VIDEO_RENDERING_PENDING, FILE_STATUS_PERMANENT, 0, $total_videos); 314 315 while ($row = db_fetch_object($result)) { 316 $videos[] = $row; 317 } 318 return $videos; 319 } 320 321 /** 322 * @todo : replace with the load job method 323 * @param <type> $video 324 * @return <type> 325 */ 326 public function load_completed_job(&$video) { 327 $video_row = db_fetch_object(db_query('SELECT data FROM {video_zencoder} WHERE fid = %d', $video->fid)); 328 $data = unserialize($video_row->data); 329 330 if (empty($data)) 331 return $video; 332 333 foreach ($data as $value) { 334 $path = parse_url($value->url, PHP_URL_PATH); 335 $extension = pathinfo($path, PATHINFO_EXTENSION); 336 $video->files->{$extension}->filename = pathinfo($path, PATHINFO_FILENAME) .'.'. $extension; 337 $video->files->{$extension}->filepath = substr($path, 1); // Remove the leading slash 338 $video->files->{$extension}->url = $value->url; // Authentication tokens are added by video_s3->load() 339 $video->files->{$extension}->extension = $extension; 340 $video->files->{$extension}->filemime = file_get_mimetype($value->url); 341 $video->player = strtolower($extension); 342 } 343 344 return $video; 345 } 346 347 /** 348 * Change the status of the file. 349 * 350 * @param (int) $vid 351 * @param (int) $status 352 */ 353 public function change_status($vid, $status) { 354 db_query('UPDATE {video_zencoder} SET status = %d WHERE vid = %d ', $status, $vid); 355 } 356 357 /* 358 * Updates the database after a successful transfer to amazon. 359 */ 360 361 private function update($video) { 362 return db_query("UPDATE {video_zencoder} SET jobid = %d, completed=%d, data='%s' WHERE vid=%d", 363 $video->jobid, time(), $video->data, $video->vid); 364 } 365 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |