<?php 
 
    /** 
     * This is a pure php emulation of the PHP module FFmpeg-PHP. 
     * There is one extra function here. ffmpeg_animated_gif::saveNow(); 
     * @author Oliver Lillie (aka buggedcom) <[email protected]> 
     * @package PHPVideoToolkit 
     * @license BSD 
     * @copyright Copyright (c) 2008 Oliver Lillie <http://www.buggedcom.co.uk> 
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
     * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 
     * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
     * is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be 
     * included in all copies or substantial portions of the Software. 
     * 
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
     * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
     * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
     * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
     * @uses GifEncoder  
     *      - @link http://www.phpclasses.org/browse/package/3163.html 
     *      - @link http://phpclasses.gifs.hu/show.php?src=GIFEncoder.class.php 
     *      - @author László Zsidi 
     *      - @license Freeware. 
     * @see ffmpeg-php,  
     *      - @link http://ffmpeg-php.sourceforge.net/ 
     *      - @author Todd Kirby. 
     *      - all phpdoc documentation is lifted directly from the ffmpeg-php docs 
     */ 
     
    if(!defined('DS')) 
    { 
        define('DS', DIRECTORY_SEPARATOR); 
    } 
     
    class ffmpeg_animated_gif 
    { 
         
        private $_frames            = array(); 
        private $_width             = null; 
        private $_height            = null; 
        private $_frame_rate        = null; 
        private $_loop_count        = null; 
        private $_output_file_path  = null; 
        private $_toolkit_class     = null; 
        private $_unlink_files      = array(); 
        private $_saved             = false; 
         
        /** 
         * Class Constructor 
         * Create a new ffmpeg_animated_gif object. 
         * @param resource $output_file_path Location in the filesystem where the animated gif will be written. 
         * @param resource $width Width of the animated gif. 
         * @param resource $height Height of the animated gif. 
         * @param resource $frame_rate Frame rate of the animated gif in frames per second. 
         * @param resource $loop_count Number of times to loop the animation. Put a zero here to loop forever or omit this parameter to disable looping. 
         */ 
        function __construct($output_file_path, $width, $height, $frame_rate, $loop_count=false) 
        { 
            $this->_output_file_path    = $output_file_path; 
            $this->_width               = $width; 
            $this->_height              = $height; 
            $this->_frame_rate          = $frame_rate; 
            $this->_loop_count          = $loop_count; 
        } 
         
        /** 
         * Class Destructor 
         * saves the file 
         */ 
        function __destruct() 
        { 
//          save the output 
            $this->saveNow(); 
//          destroy all image resources 
            if(count($this->_frames)) 
            { 
                foreach($this->_frames as $key=>$frame) 
                { 
                    imagedestroy($frame->toGDImage()); 
                } 
            } 
//          loop through the temp files to remove  
            if(!empty($this->_unlink_files)) 
            { 
                foreach ($this->_unlink_files as $key=>$file) 
                { 
                    @unlink($file); 
                } 
                $this->_unlink_files = array(); 
            } 
        } 
         
        /** 
         * This function IS NOT PROVIDED IN FFMPEG-PHP as it creates the gif as frames are added. to save memory in 
         * php and practicality purposes this isn't really possible. It will overwrite any file. 
         * @access public 
         * @uses GifEncoder 
         *      - @link http://www.phpclasses.org/browse/package/3163.html 
         *      - @link http://phpclasses.gifs.hu/show.php?src=GIFEncoder.class.php 
         *      - @author László Zsidi 
         *      - @license Freeware. 
         * @param string $tmp_directory The temp directory to work with. (remember the trailing slash) 
         * @return boolean 
         */ 
        public function saveNow($tmp_directory='/tmp/') 
        { 
            if($this->_saved === false) 
            { 
                $this->_saved = true; 
//              check there are frames to make a gif 
                if(!count($this->_frames)) 
                { 
                    return false; 
                } 
                if(!class_exists('GIFEncoder')) 
                { 
                    require_once dirname(__FILE__).DS.'gifencoder'.DS.'GIFEncoder.class.phpvideotoolkit.php'; 
                } 
//              save all the images from the ffmpeg_frames 
                $files = array(); 
                $delays = array(); 
                $delay = (1/$this->_frame_rate)*100; 
                foreach($this->_frames as $key=>$frame) 
                { 
                    $file = $tmp_directory.'fag-'.uniqid(time().'-').'.gif'; 
                    if(!imagegif($frame->toGDImage(), $file)) 
                    { 
                        return false; 
                    } 
//                  add file to array so it out deletes on close 
                    array_push($this->_unlink_files, $file); 
                    array_push($files, $file); 
                    array_push($delays, $delay); 
                } 
//              convert the images 
                $gif = new GIFEncoder($files, $delays, $this->_loop_count, 2, 0, 0, 0, 0, 'url'); 
                $gif_data = $gif->GetAnimation(); 
                if(!$gif_data) 
                { 
                    return false; 
                } 
//              write the gif 
                if (!$handle = fopen($this->_output_file_path, 'w')) 
                { 
                    return false; 
                } 
                if (fwrite($handle, $gif_data) === false) 
                { 
                    return false; 
                } 
                fclose($handle); 
                return true; 
            } 
            return false; 
        } 
         
        /** 
         * Add a frame to the end of the animated gif. 
         * @access public 
         * @param resource $output_file_path The ffmpeg_frame object to add to the end of the animated gif. 
         * @param boolean $save If true the gif will save after the frame has been added.  
         *      NOTE: this param does not feature in the actuall ffmpeg-php module. 
         * @return boolean 
         */ 
        public function addFrame($frame_to_add, $save=false) 
        { 
            if(get_class($frame_to_add) == 'ffmpeg_frame' && $frame_to_add->hasValidResource()) 
            { 
                array_push($this->_frames, $frame_to_add); 
                $this->_saved = false; 
                return $save === true ? $this->saveNow() : true; 
            } 
            return false; 
        } 
         
    } 
 
 |