Файл: adultscript-2.0.3-pro/files/libraries/framework/video.php
Строк: 538
<?php
defined('_VALID') or die('Restricted Access!');
define('RESIZE_METHOD', 'filter');
define('THUMB_DEBUG', false);
class VVideo
{
private $cfg;
private $vcfg;
public $data = array();
public $log_clean = FALSE;
private $log = FALSE;
private $log_file;
private $flv_formats = array(
'flv', 'flv1', 'vp3', 'vp5', 'vp6', 'vp6a', 'vp6f'
);
private $positions = array(
'top-left' => '10:10',
'bottom-left' => '10:main_h-overlay_h-10',
'top-right' => 'main_w-overlay_w-10:10',
'bottom-right' => 'main_w-overlay_w-10:main_h-overlay_h-10'
);
public function __construct()
{
$this->cfg = VF::cfg('library.video');
$this->vcfg = VF::cfg('module.video');
$this->log = ($this->vcfg['log']) ? TRUE : FALSE;
}
public function __destruct()
{
// we need to delete the log file here
if ($this->log_clean === TRUE) {
// VFile::delete($this->log_file);
}
}
public function load($file)
{
if (!file_exists($file)) {
return FALSE;
}
$this->data = array();
$options = '-v quiet -loglevel quiet -show_format -show_streams -print_format json';
$this->data['cmd'] = sprintf('%s %s %s', $this->vcfg ['ffprobe_path'], $options, escapeshellarg($file));
exec($this->data['cmd'], $output);
$json = json_decode(implode('', $output));
if (!isset($json->format)) {
return false;
}
foreach ($json->streams as $stream) {
if ($stream->codec_type == 'video') {
$video = $stream;
}
}
foreach ($json->streams as $stream) {
if ($stream->codec_type == 'audio') {
$audio = $stream;
}
}
if (!isset($video)) {
return false;
}
$this->data['container'] = $json->format->format_name;
$this->data['duration_seconds'] = $json->format->duration;
$this->data['duration_timecode'] = VDate::seconds_to_time($this->data['duration_seconds']);
$this->data['start'] = round($json->format->start_time);
$this->data['bitrate'] = $json->format->bit_rate;
$this->data['format'] = $video->codec_name;
$this->data['colorspace'] = $video->pix_fmt;
$this->data['framerate'] = $video->r_frame_rate;
$this->data['frames'] = (isset($video->nb_frames))
? $video->nb_frames
: round((substr($video->r_frame_rate, 0, strpos($video->r_frame_rate, '/')))*$json->format->duration);
$this->data['width'] = $video->width;
$this->data['height'] = $video->height;
if (isset($video->tags) && isset($video->tags->rotate)) {
$this->data['rotation'] = $video->tags->rotate;
}
if (round($this->data['width']/$this->data['height'], 1) == round(16/9, 1)) {
$this->data['dar'] = '16:9';
$this->data['dar_float'] = 16/9;
} elseif (round($this->data['width']/$this->data['height'], 1) == round(3/2, 1)) {
$this->data['dar'] = '3:2';
$this->data['dar_float'] = 3/2;
} else {
$this->data['dar'] = '4:3';
$this->data['dar_float'] = 4/3;
}
if (isset($audio)) {
$this->data['audio'] = $audio->codec_name;
$this->data['audio_frequency'] = $audio->sample_rate;
$this->data['audio_stereo'] = $audio->channel_layout;
$this->data['audio_bitrate'] = $audio->bit_rate;
}
return true;
}
public function get_data_string()
{
$string = NULL;
foreach ($this->data as $key => $value) {
$string .= $key.' => '.$value."n";
}
return $string;
}
public function get_data()
{
return $this->data;
}
public function get_dimensions($resize_width, $resize_height, $force=FALSE)
{
$width = $this->data['width'];
$height = $this->data['height'];
// width/height lower than the resize dimenstions...keep video size (some codecs wont keep aspect ratio)
if ($width <= $resize_width && $height <= $resize_height) {
$new_width = $width;
$new_height = $height;
// reduce width
} elseif ($resize_width/$width <= $resize_height/$height) {
$new_width = $resize_width;
$new_height = round($height * $resize_width/$width);
// reduce height
} else {
$new_width = round($width * $resize_height/$height);
$new_height = $height;
}
// most codecs require size to be even
return array(
'width' => round($new_width/2)*2,
'height' => round($new_height/2)*2
);
}
public function get_filter($resize_width, $resize_height, $format = false)
{
$width = $this->data['width'];
$height = $this->data['height'];
if ($format) {
$watermark = $this->vcfg[$format.'_watermark'];
$watermark_path = MEDIA_DIR.'/videos/wm/'.$watermark;
$watermark_pos = $this->vcfg[$format.'_watermark_pos'];
}
// we never upscale
if ($width < $resize_width && $height < $resize_height) {
if (isset($watermark) && $watermark) {
return ' -i '.$watermark.' -filter_complex "overlay='.$this->positions[$watermark_pos].'"';
}
return false;
}
$new_width = ($width > $height) ? $resize_width : 'trunc(oh*a/2)*2';
$new_height = ($width > $height) ? 'trunc(ow/a/2)*2' : $resize_height;
if (isset($watermark) && $watermark) {
return ' -i '.$watermark.' -filter_complex "[0:0] scale='.$new_width.':'.$new_height.' [wm]; [wm][1:0] overlay='.$this->positions[$watermark_pos].' [out]" -map "[out]"';
}
return ' -filter_complex "scale='.$new_width.':'.$new_height.'"';
}
public function get_bitrate($width, $height, $bitrate, $fix=FALSE)
{
if ($fix !== FALSE) {
return $bitrate;
}
//need to implement bitrate calculations for FLV
$area = $width * $height;
$resize_area = $this->cfg['hd_width'] * $this->cfg['hd_height'];
return round((1/2 * $area/$resize_area + 1/2 * sqrt($area/$resize_area)) * $bitrate);
}
public function get_mobile_bitrate($width, $height, $bitrate)
{
$area = $width * $height;
$resize_area = $this->cfg['mobile_width'] * $this->cfg['mobile_height'];
return round((1/2 * $area/$resize_area + 1/2 * sqrt($area/$resize_area)) * $bitrate);
}
public function get_aspect()
{
return $this->data['dar'];
}
public function convert_to_flv($src, $dst, $short=FALSE)
{
$function = 'convert_to_flv_'.$this->cfg['convert_flv'];
return $this->$function($src, $dst, $short);
}
public function convert_to_flv_ffmpeg($src, $dst, $short)
{
if (!file_exists($this->vcfg['ffmpeg_path'])) {
return FALSE;
}
$options .= '-acodec libmp3lame -ar '.$this->vcfg['flv_audio_samplerate'].' -ab '.$this->vcfg['flv_audio_bitrate'].'k';
if ($this->vcfg['flv_resize']) {
$dimensions = $this->get_dimensions($this->vcfg['flv_width'], $this->vcfg['flv_height']);
$aspect = $this->get_aspect();
$options .= ' -aspect '.$aspect.' -s '.$dimensions['width'].'x'.$dimensions['height'];
}
if ($this->vcfg['flv_bitrate_method'] == 'fixed') {
$options .= ' -b'.FFMPEG_V.' '.$this->vcfg['flv_bitrate'].'k';
} else {
$bitrate = $this->get_bitrate($dimensions['width'], $dimensions['height'], $this->vcfg['flv_bitrate'], TRUE);
$options .= ' -b'.FFMPEG_V.' '.$bitrate.'k';
}
if ($short === TRUE) {
$options .= ' -t '.$this->vcfg['view_limit'];
}
$cmd = $this->nice().$this->vcfg['ffmpeg_path'].' -y -i '.escapeshellarg($src).' -f flv '.$options.' '.escapeshellarg($dst);
$this->log($cmd);
exec($cmd.' 2>&1', $output);
$this->log(implode("n", $output));
if (file_exists($dst) && is_file($dst) && filesize($dst) > 1000) {
return TRUE;
}
return FALSE;
}
public function convert_to_mp4($src, $dst, $short = false, $watermark = false)
{
$function = 'convert_to_mp4_'.$this->cfg['convert_mp4'];
return $this->$function($src, $dst, $short, $watermark);
}
public function convert_to_mp4_ffmpeg($src, $dst, $short, $watermark)
{
if (!file_exists($this->vcfg['ffmpeg_path'])) {
return FALSE;
}
$options = null;
if ($short === true) {
$options .= ' -t '.$this->vcfg['view_limit'];
}
if ($this->vcfg['mp4_resize'] && RESIZE_METHOD == 'filter') {
$format = ($watermark) ? 'mp4' : false;
if ($filter = $this->get_filter($this->vcfg['mp4_width'], $this->vcfg['mp4_height'], $format)) {
$options .= $filter;
}
}
$options .= ' -c:v libx264 ';
$options_audio = ' -c:a '.$this->vcfg['mp4_audio_codec'].' -b:a '.$this->vcfg['mp4_audio_bitrate'].'k -ar '.$this->vcfg['mp4_audio_samplerate'];
if ($this->vcfg['mp4_audio_codec'] == 'aac') {
$options_audio .= ' -strict experimental';
}
if ($this->vcfg['mp4_resize'] && RESIZE_METHOD != 'filter') {
$dimensions = $this->get_dimensions($this->vcfg['mp4_width'], $this->vcfg['mp4_height']);
$aspect = $this->get_aspect();
$options .= ' -aspect '.$aspect.' -s '.$dimensions['width'].'x'.$dimensions['height'];
}
$options .= ' -crf '.$this->vcfg['mp4_crf'];
if ($this->vcfg['mp4_maxrate'] > 0) {
$options .= ' -maxrate '.$this->vcfg['mp4_maxrate'].'k -bufsize 1000k';
}
$options .= ' -preset '.$this->vcfg['mp4_preset'].' -profile:v '.$this->vcfg['mp4_profile'].' -level '.$this->vcfg['mp4_level'];
$options .= ' -keyint_min 25 -movflags +faststart';
$cmd = $this->nice().$this->vcfg['ffmpeg_path'].' -y -i '.escapeshellarg($src).$options.$options_audio.' '.escapeshellarg($dst);
$this->log($cmd);
exec($cmd.' 2>&1', $output);
$this->log(implode("n", $output));
if (file_exists($dst) && is_file($dst) && filesize($dst) > 1000) {
return TRUE;
}
return FALSE;
}
public function convert_to_mp4_hd($src, $dst, $short = false, $watermark = false)
{
return $this->convert_to_mp4_hd_ffmpeg($src, $dst, $short, $watermark);
}
public function convert_to_mp4_hd_ffmpeg($src, $dst, $short = false, $watermark = false)
{
if (!file_exists($this->vcfg['ffmpeg_path'])) {
return false;
}
$options = null;
if ($this->vcfg['mp4_hd_resize'] && RESIZE_METHOD == 'filter') {
$format = ($watermark) ? 'mp4_hd' : false;
if ($filter = $this->get_filter($this->vcfg['mp4_hd_width'], $this->vcfg['mp4_hd_height'], $format)) {
$options .= $filter;
}
}
$options .= ' -c:v libx264';
$options_audio = ' -c:a '.$this->vcfg['mp4_hd_audio_codec'].' -b:a '.$this->vcfg['mp4_hd_audio_bitrate'].'k -ar '.$this->vcfg['mp4_hd_audio_samplerate'];
if ($this->vcfg['mp4_hd_audio_codec'] == 'aac') {
$options_audio .= ' -strict experimental';
}
if ($this->vcfg['mp4_hd_resize'] && RESIZE_METHOD != 'filter') {
$dimensions = $this->get_dimensions($this->vcfg['mp4_hd_width'], $this->vcfg['mp4_hd_height']);
$aspect = $this->get_aspect();
$options .= ' -aspect '.$aspect.' -s '.$dimensions['width'].'x'.$dimensions['height'];
}
$options .= ' -crf '.$this->vcfg['mp4_hd_crf'];
if ($this->vcfg['mp4_hd_maxrate'] > 0) {
$options .= ' -maxrate '.$this->vcfg['mp4_hd_maxrate'].'k -bufsize 1000k';
}
$options .= ' -preset '.$this->vcfg['mp4_hd_preset'].' -profile:v '.$this->vcfg['mp4_hd_profile'].' -level '.$this->vcfg['mp4_hd_level'];
$options .= ' -keyint_min 25 -movflags +faststart';
$cmd = $this->nice().$this->vcfg['ffmpeg_path'].' -y -i '.escapeshellarg($src).$options.$options_audio.' '.escapeshellarg($dst);
$this->log($cmd);
exec($cmd.' 2>&1', $output);
$this->log(implode("n", $output));
if (file_exists($dst) && is_file($dst) && filesize($dst) > 1000) {
return true;
}
return false;
}
public function convert_to_mobile($src, $dst, $short = false, $watermark = false)
{
$function = 'convert_to_mobile_'.$this->cfg['convert_mobile'];
return $this->$function($src, $dst, $short, $watermark);
}
public function convert_to_mobile_ffmpeg($src, $dst, $short, $watermark)
{
if (!file_exists($this->vcfg['ffmpeg_path'])) {
return FALSE;
}
$options = null;
if ($this->vcfg['mobile_resize'] && RESIZE_METHOD == 'filter') {
$format = ($watermark) ? 'mobile' : false;
if ($filter = $this->get_filter($this->vcfg['mobile_width'], $this->vcfg['mobile_height'], $format)) {
$options .= $filter;
}
}
$options .= ' -c:v libx264 -threads 0 -crf '.$this->vcfg['mobile_crf'];
$options_audio = ' -c:a '.$this->vcfg['mobile_audio_codec'].' -ac 2 -b:a '.$this->vcfg['mobile_audio_bitrate'].'k -ar '.$this->vcfg['mobile_audio_samplerate'];
if ($this->vcfg['mobile_audio_codec'] == 'aac') {
$options_audio .= ' -strict experimental';
}
if ($this->vcfg['mobile_resize'] && RESIZE_METHOD != 'filter') {
$dimensions = $this->get_dimensions($this->vcfg['mobile_width'], $this->vcfg['mobile_height'], true);
$aspect = $this->get_aspect();
$options .= ' -aspect '.$aspect.' -s '.$dimensions['width'].'x'.$dimensions['height'];
}
$options .= ' -preset '.$this->vcfg['mobile_preset'].' -profile:v '.$this->vcfg['mobile_profile'].' -level '.$this->vcfg['mobile_level'];
if ($this->vcfg['mobile_maxrate'] > 0) {
$options .= ' -maxrate '.$this->vcfg['mobile_maxrate'].'k -bufsize 1000k';
}
$options .= ' -keyint_min 25 -movflags +faststart';
$cmd = $this->nice().$this->vcfg['ffmpeg_path'].' -y -i '.escapeshellarg($src).$options.$options_audio.' '.escapeshellarg($dst);
$this->log($cmd);
exec($cmd.' 2>&1', $output);
$this->log(implode("n", $output));
if (file_exists($dst) && is_file($dst) && filesize($dst) > 1000) {
return TRUE;
}
return FALSE;
}
public function extract_thumbs($file, $video_id, $frames=array())
{
if (!file_exists($file) OR !is_file($file)) {
return FALSE;
}
if (!$frames) {
$frames = $this->generate_frames($this->data['duration_seconds']);
}
$dst_dir = MEDIA_DIR.'/videos/tmb/'.path($video_id).'/';
$tmp_dir = TMP_DIR.'/thumbs/'.$video_id.'/';
if (!VFolder::create($dst_dir, 0777) OR
!VFolder::create($tmp_dir)) {
return FALSE;
}
$def_size = $this->vcfg['thumb_width'].'x'.$this->vcfg['thumb_height'];
$sizes = array_flip($this->vcfg['thumb_sizes']);
if (isset($sizes[$def_size])) {
unset($sizes[$def_size]);
}
$sizes[$def_size] = 1;
$opts = ($this->vcfg['thumb_extr'] == 'direct') ? ' -vf "scale=#SIZE#"' : '';
$cmd_line = $this->nice().$this->vcfg['ffmpeg_path'].' -ss #SECONDS# -i '.escapeshellarg($file).' -f image2'.$opts.' -an -vframes 2 -y '.$tmp_dir.'%03d.jpg';
foreach ($sizes as $size => $value) {
$i = 1;
$d = 1;
$expl = explode('x', $size);
$width = $expl['0'];
$height = $expl['1'];
foreach ($frames as $key => $seconds) {
$cmd = str_replace('#SECONDS#', $seconds, $cmd_line);
$cmd = str_replace('#SIZE#', $width.':'.$height, $cmd);
$this->log($cmd);
exec($cmd.' 2>&1', $output);
if (THUMB_DEBUG) {
$this->log(implode("n", $output));
}
if (file_exists($tmp_dir.'002.jpg')) {
$src = $tmp_dir.'002.jpg';
} elseif (file_exists($tmp_dir.'001.jpg')) {
$src = $tmp_dir.'001.jpg';
} else {
$this->log('Failed to extract thumb!');
continue;
}
$dst = ($size == $def_size) ? $dst_dir.$i.'.jpg' : $dst_dir.$i.'.'.$size.'.jpg';
if (isset($src)) {
if ($this->save_thumb($src, $dst, $width, $height, $size)) {
if ($size == $def_size) {
++$d;
}
++$i;
}
}
}
}
$secs = (int) floor($this->data['duration_seconds']/2);
$cmd = $this->nice().$this->vcfg['ffmpeg_path'].' -ss '.$secs.' -i '.escapeshellarg($file).' -filter:v select="eq(pict_type,I)" -f image2 -an -vframes 1 -y '.$tmp_dir.'%03d.jpg';
$this->log($cmd);
exec($cmd.' 2>&1', $output);
if (THUMB_DEBUG) {
$this->log(implode("n", $output));
}
if (file_exists($tmp_dir.'001.jpg')) {
$src = $tmp_dir.'001.jpg';
} else {
$this->log('Failed to extract player thumb!');
continue;
}
if (isset($src)) {
if ($this->save_thumb($src, $dst_dir.'player.jpg', 0, 0, 0, false)) {
++$d;
}
}
// we upload thumbs to separate server if enabled
if ($d >= 2 && $this->vcfg['thumb_server'] != '0') {
VHelper::load('module.video.thumb');
VHelper_video_thumb::upload($video_id, ($i-1), $sizes, $def_size);
}
$this->log('Extracted '.$d.' thumbs!');
VFolder::delete($tmp_dir);
return ($d === 1) ? 0 : ($d - 1);
}
public function extract_thumb($file, $random=NULL, $duration=NULL)
{
if (!file_exists($file) OR !is_file($file)) {
return FALSE;
}
$random = (empty($random)) ? VText::random() : $random;
$tmp_dir = TMP_DIR.'/thumbs/'.$random.'/';
if (!VFolder::create($tmp_dir)) {
return FALSE;
}
// we need this chmod
@chmod($tmp_dir, 0777);
if (!$duration && !isset($this->data['duration_seconds'])) {
return FALSE;
}
if (!$duration) {
$duration = (int) $this->data['duration_seconds'];
}
$size = $this->vcfg['thumb_width'].'x'.$this->vcfg['thumb_height'];
$cmd = $this->vcfg['ffmpeg_path'].' -ss '.floor($duration/2).' -i '.escapeshellarg($file).' -f image2 -s '.$size.' -an -vframes 2 -y '.$tmp_dir.'%03d.jpg';
$this->log($cmd);
exec($cmd.' 2>&1', $output);
if (THUMB_DEBUG) {
$this->log(implode("n", $output));
}
if (file_exists($tmp_dir.'002.jpg')) {
return BASE_URL.'/tmp/thumbs/'.$random.'/002.jpg';
} elseif (file_exists($tmp_dir.'001.jpg')) {
return BASE_URL.'/tmp/thumbs/'.$random.'/001.jpg';
} else {
return false;
}
}
public function extract_player_thumb($file, $video_id, $duration = null, $seconds = null)
{
if (!file_exists($file) OR !is_file($file)) {
return FALSE;
}
$dst_dir = MEDIA_DIR.'/videos/tmb/'.path($video_id).'/';
$tmp_dir = TMP_DIR.'/thumbs/'.$video_id.'/';
if (!VFolder::create($dst_dir, 0777) OR
!VFolder::create($tmp_dir, 0777)) {
return FALSE;
}
if (!$duration && !isset($this->data['duration_seconds'])) {
return false;
}
if (!$duration) {
$duration = (int) $this->data['duration_seconds'];
}
$success = true;
$seconds = ($seconds) ? $seconds : floor($duration/2);
$cmd = $this->nice().$this->vcfg['ffmpeg_path'].' -ss '.$seconds.' -i '.escapeshellarg($file).' -filter:v select="eq(pict_type,I)" -f image2 -an -vframes 1 -y '.$tmp_dir.'%03d.jpg';
$this->log($cmd);
exec($cmd.' 2>&1', $output);
if (THUMB_DEBUG) {
$this->log(implode("n", $output));
}
if (file_exists($tmp_dir.'001.jpg')) {
$src = $tmp_dir.'001.jpg';
} else {
$this->log('Failed to extract thumb!');
}
if (isset($src)) {
if (!$this->save_thumb($src, $dst_dir.'player.jpg', $this->data['width'], $this->data['height'], $this->data['width'].'x'.$this->data['height'], false)) {
$success = false;
}
}
if ($success && $this->vcfg['thumb_server'] != '0') {
VHelper::load('module.video.thumb');
if (!VHelper_video_thumb::upload_player($video_id)) {
$success = false;
}
}
VFolder::delete($tmp_dir);
return $success;
}
public function extract_slide($file, $video_id)
{
if (!VFile::exists($file)) {
return false;
}
$w = 128;
$h = 72;
$version = 2;
$max_total = 23;
$max_width1 = 2880;
$max_width2 = 2800;
$max_y = 2700;
$ceil = 22;
if($this->data['dar']=='4:3') {
$w = 100;
$h = 76;
$version = 1;
$max_total = 28;
$max_width1 = 2700;
$max_width2 = 2600;
$max_y = 2670;
$ceil = 27;
}
$dst_dir = MEDIA_DIR.'/videos/tmb/'.path($video_id).'/';
$tmp_dir = TMP_DIR.'/thumbs/'.$video_id.'/';
if (!VFolder::create($dst_dir) OR !VFolder::create($tmp_dir)) {
return false;
}
$done = array();
if (!isset($this->data['duration_seconds'])) {
return false;
}
$duration = (int) $this->data['duration_seconds'];
if (intval($duration) > 0) {
$freq=3;
if ($duration>180) {
$freq=3;
}
if ($duration>300) {
$freq=5;
}
if ($duration>600) {
$freq=10;
}
if ($duration>1200) {
$freq=15;
}
if ($duration>1800) {
$freq=20;
}
$images = array();
for ($i=1; $i<$duration; $i+=$freq) {
$tmb = $tmp_dir.$i.".jpg";
$cmd = $this->vcfg['ffmpeg_path'].' -ss '.$i.' -i '.escapeshellarg($file).' -f image2 -s '.$w.'x'.$h.' -an -vframes 1 -y '.$tmb;
@exec($cmd.' 2>&1', $output);
$images[] = $tmb;
}
$total = count($images);
if ($total < $max_total) {
$width = $total*$w;
$height = $h;
} else {
$width = $max_width1;
$rows = ceil($total/$ceil);
$height = $rows*$h;
}
$image = @imagecreatetruecolor($width,$height);
$j=0;$y=0;$x=0;$num=0;
foreach($images as $img) {
$src_img = @imagecreatefromjpeg($img);
if ($x>$max_width2) {
$x = 0;
$y = $y+$h;
}
if ($y<$max_y) {
@imagecopyresampled($image, $src_img, $x, $y, 0, 0, $w, $h, $w, $h);
@imagedestroy($src_img);
$j = $j+1;
$x = $x+$w;
$num = $num+1;
}
}
$dest_file = $dst_dir .'slide.jpg';
@unlink($dest_file);
@imagejpeg($image, $dest_file, 90);
@chmod($dest_file, 0777);
@imagedestroy($image);
$size = @getimagesize($dest_file);
if ($size && intval($num)>0) {
$done[] = $num;
$done[] = $freq;
foreach ($images as $img) {
@unlink($img);
}
}
}
VFolder::delete($tmp_dir);
$done[] = $version;
return $done;
}
public function generate_frames($duration, $nr=FALSE)
{
if ($nr === FALSE) {
$nr = $this->vcfg['thumbs'];
}
$frames = array();
$step = floor($duration/$nr);
if ($step <= 0) {
$step = 1;
}
$i = 1;
while ($i <= $nr) {
$frames[] = $i*$step;
++$i;
}
return $frames;
}
private function save_thumb($src, $dst, $width, $height, $size, $resize = true)
{
if ($this->vcfg['thumb_extr'] == 'imagick') {
$this->log('Resizing/Optimizing thumb '.$src.' -> '.$dst.' ('.$size.')!');
$opts = null;
if ($this->vcfg['thumb_optimize'] == '1') {
$opts .= ' -enhance -strip -unsharp 1.0x1.0+0.5 -unsharp 1.0x1.0+0.5 -modulate 110,102,100 -unsharp 1.0x1.0+0.5 -contrast -gamma 1.2';
}
if ($resize) {
if ($this->vcfg['thumb_resize'] == 'preserve') {
$opts .= ' -resize '.$size.' -background black -gravity center -extent '.$size;
} elseif ($this->vcfg['thumb_resize'] == 'crop') {
$opts .= ' -resize '.$size.'^ -gravity center -crop '.$size.'+0+0 +repage';
} elseif ($this->vcfg['thumb_resize'] == 'adjust') {
$opts .= ' -resize '.$size.'!';
}
}
$cmd = $this->nice().$this->vcfg['convert_path'].' '.$src.$opts.' -filter Lanczos -filter Blackman -quality 95 '.$dst;
$this->log($cmd);
exec($cmd.' 2>&1', $output);
} elseif ($this->vcfg['thumb_extr'] == 'gd') {
$this->log('Resizing thumb '.$src.' -> '.$dst.' ('.$size.')!');
if ($resize) {
$image = VF::factory('image');
if (!$image->load($src) or
!$image->resize($width, $height, 'EXACT', $dst)) {
return false;
}
} else {
$this->log('Copying thumb '.$src.' -> '.$dst.'!');
if (!copy($src, $dst)) {
return false;
}
}
} elseif ($this->vcfg['thumb_extr'] == 'direct') {
$this->log('Copying thumb '.$src.' -> '.$dst.'!');
if (!copy($src, $dst)) {
return false;
}
}
if (file_exists($dst) && filesize($dst) > 100) {
@chmod($dst, 0777);
VFile::delete($src);
return true;
}
return false;
}
public function update_meta($src, $dst)
{
if (!file_exists($this->vcfg['yamdi_path'])) {
return FALSE;
}
$version = VF::cfg('library.version');
$creator = $version['name'].'-'.$version['major'].'.'.$version['minor'];
$cmd = $this->nice().$this->vcfg['yamdi_path'].' -i '.escapeshellarg($src).' -o '.escapeshellarg($dst).' -c '.$creator;
$this->log($cmd);
exec($cmd.' 2>&1', $output);
$this->log(implode("n", $output));
if (file_exists($dst) && is_file($dst) && filesize($dst) > 1000) {
VFile::delete($src);
return TRUE;
}
return FALSE;
}
public function fix_moov_atom($src, $dst)
{
$cmd = $this->nice().$this->vcfg['qtfaststart_path'].' '.escapeshellarg($src).' '.escapeshellarg($dst);
$this->log($cmd);
exec($cmd.' 2>&1', $output);
$this->log(implode("n", $output));
if (file_exists($dst) && is_file($dst) && filesize($dst) > 1000) {
VFile::delete($src);
return TRUE;
}
return FALSE;
}
public function log_setup($video_id, $log=TRUE)
{
$this->log = ($log === TRUE) ? TRUE : FALSE;
$this->log_file = TMP_DIR.'/logs/'.$video_id.'.log';
}
public function log($data)
{
if ($this->log !== false) {
VFile::write($this->log_file, $data."n", TRUE);
@chmod($this->log_file, 0777);
}
}
public function clean()
{
$this->data = array();
if ($this->log_file) {
// VFile::delete($this->log_file);
}
$this->log_file = '';
}
public function identify()
{
if (!$this->data) {
return FALSE;
}
if (!isset($this->data['format']) OR
!isset($this->data['audio'])) {
return FALSE;
}
$format = strtolower($this->data['format']);
if (strpos($format, ' ')) {
$format = substr($format, 0, strpos($format, ' '));
}
$audio = strtolower($this->data['audio']);
if (strpos($audio, ' ')) {
$audio = substr($audio, 0, strpos($audio, ' '));
}
if (in_array($format, $this->flv_formats)) {
return 'flv';
} elseif ($format == 'h263' && $audio == 'mp3') {
return 'flv';
} elseif ($format == 'h264' && $audio == 'mp3') {
if (isset($this->data['container']) && $this->data['container'] == 'flv') {
return 'flv';
}
return 'mp4';
} elseif ($format == 'h264' && $audio == 'aac') {
if (isset($this->data['container']) && $this->data['container'] == 'flv') {
return 'flv';
}
return 'mp4';
}
return FALSE;
}
public function duration()
{
return isset($this->data['duration_seconds'])
? (int) $this->data['duration_seconds']
: 0;
}
private function plugin($name)
{
$plugin_file = LIBRARY_DIR.'/framework/video/'.$name.'.php';
if (VFile::exists($plugin_file)) {
$plugin_name = 'video_plugin_'.$name;
if (!function_exists($plugin_name)) {
require $plugin_file;
}
return $plugin_name($this->data);
}
}
private function rotation()
{
if (!isset($this->data['rotation'])) {
return;
}
if ($this->data['rotation'] == '90') {
return ' -strict experimental -vf "hflip,format=yuv420p" -metadata:s:v rotate=0';
}
}
private function nice()
{
if ($this->vcfg['nice_level'] > 0) {
return 'nice -n '.$this->vcfg['nice_level'].' ';
}
}
}
?>