. */ require('components.php'); // set default transcoding commands if(!defined('OB_TRANSCODE_AUDIO_MP3')) define('OB_TRANSCODE_AUDIO_MP3', 'avconv -i {infile} -q 9 -ac 1 -ar 22050 {outfile}'); if(!defined('OB_TRANSCODE_AUDIO_OGG')) define('OB_TRANSCODE_AUDIO_OGG', 'avconv -i {infile} -acodec libvorbis -q 0 -ac 1 -ar 22050 {outfile}'); if(!defined('OB_TRANSCODE_VIDEO_MP4')) define('OB_TRANSCODE_VIDEO_MP4', 'avconv -i {infile} -crf 40 -vcodec libx264 -s {width}x{height} -ac 1 -ar 22050 {outfile}'); if(!defined('OB_TRANSCODE_VIDEO_OGV')) define('OB_TRANSCODE_VIDEO_OGV', 'avconv -i {infile} -q 0 -s {width}x{height} -acodec libvorbis -ac 1 -ar 22050 {outfile}'); // Sanity check on ID if(!empty($_GET['id']) && preg_match('/^[0-9]+$/',$_GET['id'])) $media_id = $_GET['id']; else die(); // COMPLETE AUTHENTICATION, usually handled by api.php $user = OBFUser::get_instance(); $auth_id = null; $auth_key = null; // try to get an ID/key pair for user authorization. if(!empty($_POST['i']) && !empty($_POST['k'])) { $auth_id = $_POST['i']; $auth_key = $_POST['k']; } // if not in post, try fetching from cookie. elseif(!empty($_COOKIE['ob_auth_id']) && !empty($_COOKIE['ob_auth_key'])) { $auth_id = $_COOKIE['ob_auth_id']; $auth_key = $_COOKIE['ob_auth_key']; } // authorize our user (from post data, cookie data, whatever.) $user->auth($auth_id,$auth_key); class MediaPreview extends OBFController { public function output($id,$download,$version=false) { global $user; $media_model = $this->load->model('Media'); $media_model('get_init'); $this->db->where('media.id',$id); $media = $this->db->get_one('media'); if(!$media) die(); if($version!==false) { $this->db->where('media_id',$id); $this->db->where('created',$version); $version = $this->db->get_one('media_versions'); if(!$version) die(); } $type = strtolower($media['type']); $format = strtolower($media['format']); if(!preg_match('/^[a-z0-9_-]+\.[a-z0-9]+$/i',$media['filename'])) die(); if(!preg_match('/^[A-Z0-9]{2}$/',$media['file_location'])) die(); // check permissions $is_media_owner = $media['owner_id']==$user->param('id'); // preview/download both require manage_media if private media and not owner if($media['status']=='private' && !$is_media_owner) $user->require_permission('manage_media'); // download requires download_media if this is not the media owner if($download && !$is_media_owner && !$version) $user->require_permission('download_media'); // any version download requires manage_media_versions if($version) $user->require_permission('manage_media_versions'); // version download if not owner requires manage_media if($version && !$is_media_owner) $user->require_permission('manage_media'); // set media location for preview/download if(!$version) { if($media['is_archived']==1) $media_location = OB_MEDIA_ARCHIVE; elseif($media['is_approved']==0) $media_location = OB_MEDIA_UPLOADS; else $media_location = OB_MEDIA; $media_location.='/'.$media['file_location'][0].'/'.$media['file_location'][1].'/'; $media_file = $media_location.$media['filename']; $download_filename = $media['filename']; } else { $media_file = (defined('OB_MEDIA_VERSIONS') ? OB_MEDIA_VERSIONS : OB_MEDIA.'/versions') . '/' . $media['file_location'][0] . '/' . $media['file_location'][1] . '/' . $version['media_id'] . '-' . $version['created'] . '.' . $version['format']; $download_filename = $version['media_id'] . '-' . $version['created'] . '.' . $version['format']; } // get our cached data directory ready if we don't already have it. if(!file_exists(OB_CACHE.'/media')) mkdir(OB_CACHE.'/media'); if(!file_exists(OB_CACHE.'/media/'.$media['file_location'][0])) mkdir(OB_CACHE.'/media/'.$media['file_location'][0]); if(!file_exists(OB_CACHE.'/media/'.$media['file_location'][0].'/'.$media['file_location'][1])) mkdir(OB_CACHE.'/media/'.$media['file_location'][0].'/'.$media['file_location'][1]); $cache_dir = OB_CACHE.'/media/'.$media['file_location'][0].'/'.$media['file_location'][1]; if($type=='audio') { // download mode if($download) { header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename='.$download_filename); header('Content-Type: application/octet-stream'); header('Content-Length: '.filesize($media_file)); $fp = fopen($media_file,'rb'); fpassthru($fp); exit(); } if(!empty($_GET['format']) && $_GET['format']=='mp3') $audio_format = 'mp3'; else $audio_format = 'ogg'; $cache_file = $cache_dir.'/'.$media['id'].'_audio.'.$audio_format; if(!file_exists($cache_file)) { $strtr_array = array('{infile}'=>$media_file, '{outfile}'=>$cache_file); if($audio_format == 'mp3') exec(strtr(OB_TRANSCODE_AUDIO_MP3,$strtr_array)); else exec(strtr(OB_TRANSCODE_AUDIO_OGG,$strtr_array)); } // temporary header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past if($audio_format == 'mp3') header('Content-Type: audio/mpeg'); else header("Content-Type: audio/ogg"); header('Content-Length: '.filesize($cache_file)); $fp = fopen($cache_file,'rb'); fpassthru($fp); } elseif($type=='video') { // download mode if($download) { header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename='.$download_filename); header('Content-Type: application/octet-stream'); header('Content-Length: '.filesize($media_file)); $fp = fopen($media_file,'rb'); fpassthru($fp); exit(); } if(!empty($_GET['w']) && !empty($_GET['h']) && preg_match('/^[0-9]+$/',$_GET['w']) && preg_match('/^[0-9]+$/',$_GET['h'])) { $dest_width=$_GET['w']; $dest_height=$_GET['h']; } else { $dest_width = 320; $dest_height = 240; } // we could use half resolution, then zoom by 200%. (faster encoding, lower birate) ... // $dest_width = round($dest_width/2); // $dest_height = round($dest_height/2); if(!empty($_GET['format']) && $_GET['format']=='mp4') $video_format = 'mp4'; else $video_format = 'ogv'; $cache_file = $cache_dir.'/'.$media['id'].'_'.$dest_width.'x'.$dest_height.'.'.$video_format; if(!file_exists($cache_file)) { $strtr_array = array('{infile}'=>$media_file, '{outfile}'=>$cache_file, '{width}'=>$dest_width, '{height}'=>$dest_height); if($video_format == 'mp4') { // resolution apparently needs to be divisible by 2. $dest_width = round($dest_width/2)*2; $dest_height = round($dest_height/2)*2; exec(strtr(OB_TRANSCODE_VIDEO_MP4, $strtr_array)); } else exec(strtr(OB_TRANSCODE_VIDEO_OGV, $strtr_array)); } if($video_format == 'mp4') header('Content-Type: video/mp4'); else header("Content-Type: video/ogg"); header('Content-Length: '.filesize($cache_file)); $fp = fopen($cache_file,'rb'); fpassthru($fp); } elseif($type=='image') { // download mode if($download) { header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename='.$download_filename); if($format=='png') header('Content-Type: image/png'); elseif($format=='jpg') header('Content-Type: image/jpeg'); elseif($format=='gif') header('Content-Type: image/gif'); elseif($format=='svg') header('Content-Type: image/svg+xml'); else die(); header('Content-Length: '.filesize($media_file)); $fp = fopen($media_file,'rb'); fpassthru($fp); exit(); } if(!empty($_GET['w']) && !empty($_GET['h']) && preg_match('/^[0-9]+$/',$_GET['w']) && preg_match('/^[0-9]+$/',$_GET['h'])) { $dest_width=$_GET['w']; $dest_height=$_GET['h']; } else { $dest_width = 320; $dest_height = 240; } $cache_file = $cache_dir.'/'.$media['id'].'_'.$dest_width.'x'.$dest_height.'.jpg'; if(!file_exists($cache_file)) { // TODO better error reporting back to user needed. // SVG preview requires imagick extension. if($format=='svg' && !extension_loaded('imagick')) die(); if($format=='svg') { $im = new Imagick(); $svg = file_get_contents($media_file); $im->readImageBlob($svg); $source_width = $im->getImageWidth(); $source_height = $im->getImageHeight(); $source_ratio = $source_width/$source_height; $dest_ratio = $dest_width/$dest_height; if($dest_ratio > $source_ratio) $dest_width = $dest_height * $source_ratio; else $dest_height = $dest_width / $source_ratio; $im->setImageFormat("jpeg"); $im->adaptiveResizeImage($dest_width, $dest_height); $im->writeImage($cache_file); $im->clear(); $im->destroy(); } else { $image_data = getimagesize($media_file); list($source_width,$source_height) = $image_data; $source_ratio = $source_width/$source_height; $dest_ratio = $dest_width/$dest_height; if($dest_ratio > $source_ratio) $dest_width = $dest_height * $source_ratio; else $dest_height = $dest_width / $source_ratio; if($image_data[2]==IMAGETYPE_PNG) $image_source = imagecreatefrompng($media_file); elseif($image_data[2]==IMAGETYPE_JPEG) $image_source = imagecreatefromjpeg($media_file); elseif($image_data[2]==IMAGETYPE_GIF) $image_source = imagecreatefromgif($media_file); else die(); $image_dest = imagecreatetruecolor($dest_width,$dest_height); imagecopyresampled($image_dest,$image_source,0,0,0,0,$dest_width,$dest_height,$source_width,$source_height); imagejpeg($image_dest,$cache_file); imagedestroy($image_dest); imagedestroy($image_source); } } header('Content-type: image/jpeg'); header('Content-Length: '.filesize($cache_file)); $fp = fopen($cache_file,'rb'); fpassthru($fp); } exit(); } } // default is to preview active media file $download_mode = false; $version = false; // if version set, we are also downloading if(isset($_GET['v'])) { $download_mode = true; $version = (int) $_GET['v']; } // or just downloading active media file elseif(isset($_GET['dl']) && $_GET['dl']==1) { $download_mode = true; } $preview = new MediaPreview(); $preview->output($_GET['id'],$download_mode,$version);