* TODO: add common settings from video module configurations and extend it from ffmpeg.inc
* since we need to have executable path of ffmpeg to ffmpeg.inc we need to have it
*/
/**
* Define some constants
*/
defined('VIDEO_RENDERING_PENDING')
or define('VIDEO_RENDERING_PENDING', 1);
defined('VIDEO_RENDERING_ACTIVE')
or define('VIDEO_RENDERING_ACTIVE', 5);
defined('VIDEO_RENDERING_COMPLETE')
or define('VIDEO_RENDERING_COMPLETE', 10);
defined('VIDEO_RENDERING_FAILED')
or define('VIDEO_RENDERING_FAILED', 20);
// nice value to append at the beginning of the command
defined('VIDEO_RENDERING_NICE')
or define('VIDEO_RENDERING_NICE', 'nice -n 19');
// curl related data
defined('HTTP_CONNECT_TIMEOUT')
or define('HTTP_CONNECT_TIMEOUT', 600);
defined('HTTP_LOW_SPEED_LIMIT')
or define('HTTP_LOW_SPEED_LIMIT', 256);
defined('HTTP_LOW_SPEED_TIMEOUT')
or define('HTTP_LOW_SPEED_TIMEOUT', 600);
// TODO : add cron API to video module
function zencoder_cron() {
global $base_url;
if(variable_get('video_zencoder_helper_auto_cvr_cron', true)) {
exec("php video_scheduler.php $base_url > /dev/null &");
}
}
/**
* Get some informations from the video file
*/
function zencoder_get_video_info($vidfile) {
static $zencoder_info;
$fid = $vidfile['fid'];
// $command_output = cache_get($fid);
// if(empty($command_output)) {
// escape file name for safety
$file = escapeshellarg($vidfile['filepath']);
// create the full command to execute
$command = variable_get('video_transcoder_path', '/usr/bin/ffmpeg') . ' -i ' . $file;
//execute the command
ob_start();
passthru($command." 2>&1", $command_return);
$command_output = ob_get_contents();
ob_end_clean();
// cache the result for further calls
// $zencoder_info[$vidfile['fid']] = $command_output;
// cache_set($vidfile['fid'], $command_output);
// }
return $command_output;
}
/**
* Return the video resolution
*/
function zencoder_auto_resolution(&$node) {
if(!variable_get('video_zencoder_helper_auto_resolution', false)) {
// call ffmpeg -i
$zencoder_output = zencoder_get_video_info($node);
// get resolution
$pattern = '/Video: .*, ([0-9]{2,4}x[0-9]{2,4})/';
preg_match_all($pattern, $zencoder_output, $matches, PREG_PATTERN_ORDER);
$resolution = $matches[1][0];
return explode("x", $resolution);
}
return null;
}
/**
* Return the playtime seconds of a video
*/
function zencoder_auto_playtime($file) {
if(!variable_get('video_zencoder_helper_auto_playtime', false)) {
// call ffmpeg -i
$zencoder_output = zencoder_get_video_info($file);
// get playtime
$pattern = '/Duration: ([0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9])/';
preg_match_all($pattern, $zencoder_output, $matches, PREG_PATTERN_ORDER);
$playtime = $matches[1][0];
// ffmpeg return lenght as 00:00:31.1 Let's get playtime from that
$hmsmm = explode(":", $playtime);
$tmp = explode(".", $hmsmm[2]);
$seconds = $tmp[0];
$hours = $hmsmm[0];
$minutes = $hmsmm[1];
return $seconds + ($hours * 3600) + ($minutes * 60);
}
}
/**
* Generates a thumbnail from the video file
* Implementing hook_auto_thumbnail on inc
*
* @param $vidfile
* object with element information
*
* @return
* a drupal file objects
*/
function zencoder_auto_thumbnail($vidfile) {
global $user;
$uploaded_file = $vidfile;
$fid = $uploaded_file["fid"];
// are we debugging?
// escape the filename for safety
$videofile = escapeshellarg($uploaded_file['filepath']);
$thumb_path = variable_get('video_thumb_path', 'video_thumbs');
//files will save in files/video_thumbs/#fileId folder
$tmp = file_directory_path(). '/' . $thumb_path . '/' . $fid;
// Ensure the destination directory exists and is writable.
$directories = explode('/', $tmp);
// array_pop($directories); // Remove the file itself.
// Get the file system directory.
$file_system = file_directory_path();
foreach ($directories as $directory) {
$full_path = isset($full_path) ? $full_path . '/' . $directory : $directory;
// Don't check directories outside the file system path.
if (strpos($full_path, $file_system) === 0) {
field_file_check_directory($full_path, FILE_CREATE_DIRECTORY);
}
}
$count = variable_get('no_of_video_thumbs', 5);
$duration = zencoder_auto_playtime($vidfile);
$files = NULL;
for($i = 1; $i <= $count; $i++) {
// get ffmpeg configurations
$seek = ($duration/$count) * $i;
$thumbfile = $tmp . "/video-thumb-for-$fid-$i.png";
//skip files already exists, this will save ffmpeg traffic
if (!is_file($thumbfile)) {
$tnail = variable_get('video_transcoder_path', '/usr/bin/ffmpeg');
$options = preg_replace(array('/%videofile/', '/%thumbfile/', '/%seek/'), array($videofile, $thumbfile, $seek), variable_get('video_zencoder_thumbnailer_options', '-i %videofile -an -y -f mjpeg -ss %seek -vframes 1 %thumbfile'));
// $options = preg_replace(array('/%videofile/', '/%tmp/', '/%id/', '/%interval/'), array($videofile, $tmp, $i, ($duration/$count)), variable_get('video_image_thumbnailer_options', '-ss %id*%interval -i %videofile -vframes 1 %thumbfile'));
// ffmpeg -ss $i*$interval -i intro.mov -vframes 1 -s 320x240 thumb_$i.jpg
//ffmpeg -i superstunt_8uiarzrh.mp4 -r 0.1 -ss 00:00:5 -f image2 img/images%02d.png
////ffmpeg -i superstunt_8uiarzrh.mp4 -r 0.05 -ss 00:00:5 -f image2 img/images%1d.jpg
// executes the command
$command = "$tnail $options";
ob_start();
passthru($command." 2>&1", $tnail_return);
$tnail_output = ob_get_contents();
ob_end_clean();
if (!file_exists($thumbfile)) {
$error_param = array(
'%file' => $thumbfile,
'%cmd' => $command,
'%out' => $tnail_output,
);
$error_msg = t("error generating thumbnail for video: generated file %file does not exist.
Command Executed:
%cmd
Command Output:
%out", $error_param);
// let's log this
watchdog('video_ffmpeg',$error_msg, array(), WATCHDOG_ERROR);
}
}
// Begin building file object.
//TODO : use file_munge_filename()
$file = new stdClass();
$file->uid = $user->uid;
$file->status = FILE_STATUS_TEMPORARY;
$file->filename = trim("video-thumb-for-$fid-$i.png");
$file->filepath = $thumbfile;
$file->filemime = file_get_mimetype("video-thumb-for-$fid-$i.png");
$file->filesize = filesize($thumbfile);
$file->timestamp = time();
$files[] = $file;
}
return $files;
}
/**
* Implementing hook_chcek_exepath() on inc
* To check the the path is executable or not
* @param path to check
* @return bool TRUE/FALSE
*/
function zencoder_check_exe_path($path=NULL) {
if (!$path) {
$path = variable_get('video_transcoder_path', '/usr/bin/ffmpeg');
}
if (function_exists('is_executable')) {
$test = 'is_executable';
} else {
$test = 'file_exists';
}
return $test($path);
}
/**
* Implementing hook_auto_convert();
* @param $job
*/
function zencoder_auto_convert(&$job) {
$videofile = escapeshellarg($job->filepath); // escape file name for safety
$convfile = tempnam(file_directory_temp(), 'video-rendering');
$audiobitrate = variable_get('video_zencoder_helper_auto_cvr_audio_bitrate', 64);
$videobitrate = variable_get('video_zencoder_helper_auto_cvr_video_bitrate', 200);
$size = _video_render_get_size();
$converter = variable_get('video_transcoder_path', '/usr/bin/ffmpeg');
$options = preg_replace(array('/%videofile/', '/%convertfile/', '/%audiobitrate/', '/%size/', '/%videobitrate/'),
array($videofile, $convfile, $audiobitrate, $size, $videobitrate),
variable_get('video_zencoder_helper_auto_cvr_options',
'-y -i %videofile -f flv -ar 22050 -ab %audiobitrate -s %size -b %videobitrate -qscale 1 %convertfile'));
// set to the converted file output
$job->convfile = $convfile;
$command = VIDEO_RENDERING_NICE . " $converter $options";
//print('executing ' . $command); die;
watchdog('video_render', 'executing: ' . $command, array(), WATCHDOG_DEBUG);
// watchdog('video_render', 'Starting : ' . time());
//execute the command
ob_start();
passthru($command." 2>&1", $command_return);
$command_output = ob_get_contents();
ob_end_clean();
// watchdog('video_render', 'Completed');
//print $command_output;
if (!file_exists($job->convfile) || !filesize($job->convfile)) {
watchdog('video_render', 'video conversion failed. ffmpeg reported the following output: ' . $command_output, array(), WATCHDOG_ERROR);
// _video_render_set_video_encoded_fid($job->nid, $job->vid, -1);
// _video_render_job_change_status($job->nid, $job->vid, VIDEO_RENDERING_FAILED);
}
else {
$file_name = basename($job->filename . ".flv");
$file = new stdClass();
$file->uid = $job->uid;
$file->status = FILE_STATUS_PERMANENT;
$file->filename = basename($file_name);
$file->filepath = $job->convfile;
$file->filemime = file_get_mimetype($file_name);
$file->filesize = filesize($job->convfile);
$file->timestamp = time();
$job->converted = $file;
}
}
/**
* Calculate the converted video size basing on the width set on administration.
* Aspect ration is maintained.
*/
//function _video_render_get_size() {
// return variable_get('video_zencoder_width', 640) . 'x' . variable_get('video_zencoder_height', 480);
//}
function _video_curl_post($url, $fields, &$output) {
$options = array(
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $fields,
CURLOPT_CONNECTTIMEOUT => HTTP_CONNECT_TIMEOUT,
CURLOPT_LOW_SPEED_LIMIT => HTTP_LOW_SPEED_LIMIT,
CURLOPT_LOW_SPEED_TIME => HTTP_LOW_SPEED_TIMEOUT,
CURLOPT_RETURNTRANSFER => TRUE
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$output = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $http_code;
}
/** S3 API functions **/
/** ---------------- **/