diff --git a/README.md b/README.md index 0152061..d37ebd2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ PictShare is an multi lingual, open source image hosting service with a simple r UPDATES ======== +- Nov. 23: Added support for MP4 uploads and conversion from gif to mp4 - Nov. 12: Created new git project: [Pictshare stats](https://github.com/chrisiaut/pictshare_stats) - Nov. 07: Added 9 new (instagram-like) filters - Nov. 06: Master delete code. One code to delete them all @@ -48,6 +49,8 @@ If there is some option that's not recognized by PictShare it's simply ignored, **Resizing** | | | <width>**x**<height> | -none- | https://pictshare.net/20x20/b260e36b60.jpg | ![Resized](https://pictshare.net/20x20/b260e36b60.jpg) forcesize | -none- | https://pictshare.net/100x400/forcesize/b260e36b60.jpg | ![Forced size](https://pictshare.net/100x400/forcesize/b260e36b60.jpg) +**GIF to mp4** | | | +mp4 | -none- | https://www.pictshare.net/mp4/102687fe65.gif | Converts gif to mp4 and displays as that. Note that you can't include that mp4 in an img tag **Rotating** | | | left | -none- | https://pictshare.net/left/b260e36b60.jpg | ![Rotated left](https://pictshare.net/200/left/b260e36b60.jpg) right | -none- | https://pictshare.net/right/b260e36b60.jpg | ![Rotated right](https://pictshare.net/200/right/b260e36b60.jpg) @@ -137,6 +140,7 @@ If you access the image with the code like this: ```https://www.pictshare.net/ch - Make sure you have PHP5 GD libraries installed: ```apt-get install php5-gd``` - Unpack the [PictShare zip](https://github.com/chrisiaut/pictshare/archive/master.zip) - Rename /inc/example.config.inc.php to /inc/config.inc.php +- ```chmod +x bin/ffmpeg``` if you want to be able to use mp4 uploads - (optional) You can and should put a [nginx](https://www.nginx.com/) proxy before the Apache server. That thing is just insanely fast with static content like images. - (optional) To secure your traffic I'd highly recommend getting an [SSL Cert](https://letsencrypt.org/) for your server if you don't already have one. @@ -166,7 +170,7 @@ server { fastcgi_param PATH_INFO $fastcgi_script_name; } - location ~ /(upload|tmp) { + location ~ /(upload|tmp|bin) { deny all; return 404; } diff --git a/bin/ffmpeg b/bin/ffmpeg new file mode 100644 index 0000000..c6bdf90 Binary files /dev/null and b/bin/ffmpeg differ diff --git a/inc/core.php b/inc/core.php index 02feada..58a46cb 100644 --- a/inc/core.php +++ b/inc/core.php @@ -150,8 +150,22 @@ function renderImage($data) imagepng($im); break; case 'gif': - header ("Content-type: image/gif"); - $im = imagecreatefromgif($path); + + if($data['mp4']) + { + header("Content-Type: video/mp4"); + readfile($pm->gifToMP4($path)); + } + + else + { + header ("Content-type: image/gif"); + readfile($path); + } + + break; + case 'mp4': + header("Content-Type: video/mp4"); readfile($path); break; } diff --git a/models/pictsharemodel.php b/models/pictsharemodel.php index b1ca483..2b562a8 100644 --- a/models/pictsharemodel.php +++ b/models/pictsharemodel.php @@ -44,6 +44,8 @@ class PictshareModel extends Model if($this->isImage($el)) $data['hash']=$el; + else if($el=='mp4') + $data['mp4'] = 1; else if($this->isSize($el)) $data['size'] = $el; else if($this->isRotation($el)) @@ -68,6 +70,12 @@ class PictshareModel extends Model return false; } + if($data['mp4']) + { + $hash = $data['hash']; + if(!$hash || $this->getTypeOfHash($hash)!='gif') + unset($data['mp4']); + } return $data; } @@ -257,10 +265,20 @@ class PictshareModel extends Model if(count($arr)>1) { $a2 = explode('/', $arr[0]); - return $a2[1]; + $type = $a2[1]; } - $a2 = explode('/', $type); - return $a2[1]; + else + { + $a2 = explode('/', $type); + $type = $a2[1]; + } + + if($type=='mp4' && !$this->isProperMP4($url)) + return false; + + + return $type; + } function isTypeAllowed($type) @@ -278,19 +296,19 @@ class PictshareModel extends Model case 'image/gif': return 'gif'; case 'gif': return 'gif'; + + case 'mp4': return 'mp4'; + default: return false; } } function uploadImageFromURL($url) { - - $type = $this->getTypeOfFile($url); $type = $this->isTypeAllowed($type); - - $dup_id = $this->isDuplicate($url); + $dup_id = $this->isDuplicate($url); if($dup_id) { $hash = $dup_id; @@ -400,7 +418,10 @@ class PictshareModel extends Model if($data['status']=='OK') { - $o.= '

'.$this->translate(4).' '.++$i.'


'; + if($data['type']=='mp4') + $o.= '

'.$this->translate(4).' '.++$i.'

'.$data['hash'].'
'; + else + $o.= '

'.$this->translate(4).' '.++$i.'


'; } } } @@ -571,4 +592,51 @@ class PictshareModel extends Model return $type; } + + function getTypeOfHash($hash) + { + $base_path = ROOT.DS.'upload'.DS.$hash.DS; + $path = $base_path.$hash; + $type = $this->isTypeAllowed($this->getTypeOfFile($path)); + + return $type; + } + + function isProperMP4($filename) + { + $filename = '/var/www/outfile.mp4'; + $file = escapeshellarg($filename); + $tmp = ROOT.DS.'tmp'.DS.md5(time()+rand(1,10000)).'.'.rand(1,10000).'.log'; + $bin = escapeshellcmd(ROOT.DS.'bin'.DS.'ffmpeg'); + + $cmd = "$bin -i $file > $tmp 2>> $tmp"; + + system($cmd); + + $answer = file($tmp); + unlink($tmp); + $ismp4 = false; + if(is_array($answer)) + foreach($answer as $line) + { + $line = trim($line); + if(strpos($line,'Duration: 00:00:00')) return false; + if(strpos($line, 'Video: h264')) + $ismp4 = true; + } + + return $ismp4; + } + + function gifToMP4($gifpath) + { + $bin = escapeshellcmd(ROOT.DS.'bin'.DS.'ffmpeg'); + $file = escapeshellarg($gifpath); + $mp4file = $gifpath.'.mp4'; + $cmd = "$bin -f gif -i $file $file.mp4"; + + system($cmd); + + return $mp4file; + } }