View source
<?php
class video_zencoder implements transcoder_interface {
private $name = 'Zencoder';
private $value = 'video_zencoder';
public function generate_thumbnails($video) {
global $user;
$video_thumb_path = variable_get('video_thumb_path', 'videos/thumbnails');
$final_thumb_path = file_default_scheme() . '://' . $video_thumb_path . '/' . $video['fid'];
file_prepare_directory($final_thumb_path, FILE_CREATE_DIRECTORY);
$files = array();
$number_of_thumbs = variable_get('video_thumbs', 5);
for ($i = 0; $i < $number_of_thumbs; $i++) {
$filename = $video['fid'] . '_' . sprintf("%04d", $i) . '.png';
$thumbfile = $final_thumb_path . '/' . $filename;
if (!file_exists(drupal_realpath($thumbfile))) {
$default = drupal_get_path('module', 'video') . '/images/no-thumb.png';
libraries_load('awssdk');
$key = variable_get('media_amazon_key', '');
$secret_key = variable_get('media_amazon_key_secret', '');
$bucket = variable_get('media_amazon_s3_bucket', '');
$s3 = new AmazonS3($key, $secret_key);
if ($s3
->get_object_metadata($bucket, $video_thumb_path . '/' . $video['fid'] . '/' . $filename)) {
$s3
->get_object($bucket, $video_thumb_path . '/' . $video['fid'] . '/' . $filename, array(
'fileDownload' => drupal_realpath($thumbfile),
));
}
else {
$thumbfile = $final_thumb_path . '/no-thumb.png';
@copy($default, drupal_realpath($thumbfile), FILE_EXISTS_REPLACE);
}
if (!file_exists(drupal_realpath($thumbfile))) {
$error_param = array(
'%file' => $thumbfile,
'%out' => $s3_get_object,
);
$error_msg = t("Error downloading thumbnail for video: generated file %file does not exist.<br />S3 Output:<br />%out", $error_param);
watchdog('zencoder', $error_msg, array(), WATCHDOG_ERROR);
continue;
}
}
$file = new stdClass();
$file->uid = $user->uid;
$file->status = 0;
$file->filename = trim($filename);
$file->uri = $thumbfile;
$file->filemime = file_get_mimetype($filename);
$file->filesize = filesize(drupal_realpath($thumbfile));
$file->timestamp = time();
$files[] = $file;
}
return $files;
}
public function convert_video($video) {
if ($video->video_status == VIDEO_RENDERING_ACTIVE) {
return;
}
$this
->change_status($video->vid, VIDEO_RENDERING_ACTIVE);
module_load_include('inc', 'video_zencoder', '/includes/zencoder');
$zc = new video_zencoder_api();
if ($encoding_job = $zc
->create($video)) {
$video->vid = $video->vid;
$video->jobid = $encoding_job->id;
$outputs = new stdClass();
foreach ($encoding_job->outputs as $output) {
$outputs->{$output->id}->id = $output->id;
$outputs->{$output->id}->label = $output->label;
$outputs->{$output->id}->url = $output->url;
$outputs->{$output->id}->state = $output->state;
$outputs->{$output->id}->error_message = $output->error_message;
$outputs->{$output->id}->error_link = $output->error_link;
}
$video->data = serialize($outputs);
if ($this
->update($video)) {
watchdog('zencoder', t('Successfully created trancoding job on !jobid.', array(
'!jobid' => $video->jobid,
)), array(), WATCHDOG_INFO);
}
}
else {
watchdog('zencoder', 'Failed to queus our file to Zencoder.', array(), WATCHDOG_ERROR);
$this
->change_status($video->vid, VIDEO_RENDERING_FAILED);
return FALSE;
}
}
public function get_name() {
return $this->name;
}
public function get_value() {
return $this->value;
}
public function get_help() {
$help = l(t('Zencoder'), 'http://zencoder.com/');
return $help;
}
public function admin_settings() {
global $user;
if (!module_exists('media_amazon')) {
drupal_set_message(t('You must enable Video Amazon S3 Module to enable this module.'), 'error');
}
$form = array();
$form['video_zencoder_start'] = array(
'#type' => 'markup',
'#markup' => '<div id="video_zencoder">',
);
$zencoder_api = variable_get('video_zencoder_api_key', null);
if (!isset($zencoder_api) && empty($zencoder_api)) {
$form['zencoder_user'] = array(
'#type' => 'fieldset',
'#title' => t('Zencoder User'),
'#collapsible' => FALSE,
'#collapsed' => FALSE,
'#description' => t('Save configurations to creare your Zencoder account to transcode and manage your videos using Zencode API. Once you save your configurations then this will automatically create an account on the Zencoder.com and password and all ther other relevent details will be emailled to you.', array(
'!link' => l(t('Zencoder.com'), 'http://zencoder.com'),
)),
);
$form['zencoder_user']['zencoder_username'] = array(
'#type' => 'textfield',
'#title' => t('Your email address'),
'#default_value' => variable_get('zencoder_username', 'me@localhost'),
'#size' => 50,
'#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.'),
);
$form['zencoder_user']['agree_terms_zencoder'] = array(
'#type' => 'checkbox',
'#title' => t('Agree Zencoder !link.', array(
'!link' => l(t('Terms and Conditions'), 'http://zencoder.com/terms', array(
'attributes' => array(
'target' => '_blank',
),
)),
)),
'#default_value' => variable_get('agree_terms_zencoder', TRUE),
);
}
else {
$form['zencoder_info'] = array(
'#type' => 'fieldset',
'#title' => t('Zencoder API'),
'#collapsible' => FALSE,
'#collapsed' => FALSE,
);
$form['zencoder_info']['video_zencoder_api_key'] = array(
'#type' => 'textfield',
'#title' => t('Zencoder API Key'),
'#default_value' => variable_get('video_zencoder_api_key', null),
'#description' => t('Zencoder API Key. Click <b>Reset to default</b> button to add new account.'),
);
$form['zencoder_info']['video_thumbs'] = array(
'#type' => 'textfield',
'#title' => t('Number of thumbnails'),
'#description' => t('Number of thumbnails to display from video.'),
'#default_value' => variable_get('video_thumbs', 5),
'#size' => 5,
);
$form['zencoder_info']['video_thumbs_size'] = array(
'#type' => 'textfield',
'#title' => t('Dimention of thumbnails'),
'#description' => t('Size of thumbnails to extract from video.'),
'#default_value' => variable_get('video_thumbs_size', '160x120'),
'#size' => 10,
);
global $base_url;
$form['zencoder_info']['video_zencoder_postback'] = array(
'#type' => 'textfield',
'#title' => t('Postback URL for Zencoder'),
'#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.'),
'#default_value' => variable_get('video_zencoder_postback', $base_url . '/postback/jobs'),
);
}
$form['video_zencoder_end'] = array(
'#type' => 'markup',
'#markup' => '</div>',
);
return $form;
}
public function admin_settings_validate($form, &$form_state) {
if (variable_get('video_zencoder_api_key', FALSE)) {
return;
}
if ($form_state['values']['agree_terms_zencoder'] == 0) {
form_set_error('agree_terms_zencoder', t('You must agree !link.', array(
'!link' => l(t('terms and conditions'), 'http://zencoder.com/terms'),
)));
}
if ($error = user_validate_mail($form_state['values']['zencoder_username'])) {
form_set_error('zencoder_username', $error);
}
if (!form_get_errors()) {
$email = $form_state['values']['zencoder_username'];
module_load_include('inc', 'video_zencoder', '/includes/zencoder');
$zc = new video_zencoder_api();
$user = new stdClass();
$user->email = $email;
$result = $zc
->create_user($user);
if ($result !== TRUE) {
form_set_error('zencoder_username', $result);
}
}
}
public function get_dimensions($video) {
return;
}
public function get_codecs() {
$codecs = array(
'encode' => array(
'video' => array(
'h264' => 'H.264 (default)',
'vp8' => 'VP8',
'theora' => 'Theora',
'vp6' => 'VP6',
'mpeg4' => 'MPEG-4',
'wmv' => 'WMV',
),
'audio' => array(
'aac' => 'AAC (default for most cases)',
'mp3' => 'MP3',
'vorbis' => 'Vorbis (default for VP8 and Theora)',
'wma' => 'WMA',
),
),
'decoding' => array(),
);
return $codecs;
}
public function create_job($video, $nid) {
return db_insert('video_zencoder')
->fields(array(
'fid' => $video['fid'],
'nid' => $nid,
'status' => VIDEO_RENDERING_PENDING,
'dimensions' => $video['dimensions'],
))
->execute();
}
public function delete_job($video) {
$video = (object) $video;
if (!($video = $this
->load_job($video->fid))) {
return;
}
$converted = unserialize($video->data);
if (!empty($converted)) {
foreach ($converted as $file) {
if (file_exists(drupal_realpath($file->uri))) {
@drupal_unlink($file->uri);
}
}
}
db_delete('video_zencoder')
->condition('fid', $video->fid)
->execute();
}
public function load_job($fid) {
$job = null;
$job = db_query("SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.data, vf.status as video_status\n FROM {video_zencoder} vf LEFT JOIN {file_managed} f ON vf.fid = f.fid WHERE f.fid=vf.fid AND f.fid = :fid", array(
':fid' => $fid,
))
->fetch();
if (!empty($job)) {
return $job;
}
else {
return FALSE;
}
}
public function load_job_by_jobid($jobid) {
$job = db_query("SELECT f.*, vf.vid, vf.nid, vf.dimensions, vf.data, vf.status as video_status\n FROM {video_zencoder} vf LEFT JOIN {file_managed} f ON vf.fid = f.fid WHERE f.fid=vf.fid AND f.jobid = :jobid", array(
':jobid' => $jobid,
))
->fetch();
if (!empty($job)) {
return $job;
}
else {
return FALSE;
}
}
public function load_job_queue() {
$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_zencoder} vf LEFT JOIN {file_managed} f ON vf.fid = f.fid
WHERE vf.status = :vstatus AND f.status = :fstatus ORDER BY f.timestamp', 0, $total_videos, array(
':vstatus' => VIDEO_RENDERING_PENDING,
':fstatus' => FILE_STATUS_PERMANENT,
));
foreach ($result as $row) {
$videos[] = $row;
}
return $videos;
}
public function load_completed_job(&$video) {
$file = $this
->load_job($video->fid);
$data = unserialize($file->data);
if (!empty($data)) {
foreach ($data as $value) {
$extension = pathinfo(drupal_realpath($value->uri), PATHINFO_EXTENSION);
$video->files->{$extension}->filename = $value->filename;
$video->files->{$extension}->filepath = $value->uri;
$video->files->{$extension}->filemime = file_get_mimetype($value->uri);
$video->files->{$extension}->url = file_create_url($value->uri);
$video->files->{$extension}->uri = $value->uri;
$video->files->{$extension}->extension = $extension;
$video->player = strtolower($extension);
}
}
else {
return FALSE;
}
}
public function change_status($vid, $status) {
db_update('video_zencoder')
->fields(array(
'status' => $status,
))
->condition('vid', $vid, '=')
->execute();
}
private function update($video) {
return db_update('video_zencoder')
->fields(array(
'jobid' => $video->jobid,
'completed' => time(),
'data' => $video->data,
))
->condition('vid', $vid, '=')
->execute();
}
}