/** * Saves the animated gif. * * @access public * @author Oliver Lillie * @param string $save_path The path to save the animated gif to. * @return PHPVideoToolkit\Image Returns a new instance of PHPVideoToolkit\Image with the new animated gif as the src. * @throws PHPVideoToolkit\AnimatedGifException If the convert process encounters an error. */ public function save($save_path) { $save_path = parent::save($save_path); // build the gifsicle process $process = new ProcessBuilder('convert', $this->_config); // set the frame duration $process->add('-delay')->add($this->_frame_delay * 100); $process->add('-loop')->add($this->_loop_count === AnimatedGif::UNLIMITED_LOOPS ? '0' : $this->_loop_count + 1); // add in all the frames foreach ($this->_frames as $path) { $process->add($path); } if ($this->_config->gif_transcoder_convert_use_dither === true) { $process->add('-ordered-dither')->add($this->_config->gif_transcoder_convert_dither_order); } if ($this->_config->gif_transcoder_convert_use_coalesce === true) { $process->add('-coalesce'); } $process->add('-layers')->add('OptimizeTransparency'); if ($this->_config->gif_transcoder_convert_use_map === true) { $process->add('+map'); } // add the output path $process->add($save_path); // execute the process. $exec = $process->getExecBuffer(); $exec->setBlocking(true)->execute(); // check for any gifsicle errors if ($exec->hasError() === true) { throw new AnimatedGifException('AnimatedGif save using `convert` "' . $save_path . '" failed. Any additional convert message follows: ' . $exec->getBuffer()); } return new Image($save_path, $this->_config); }
/** * Specifically for creating fast starting files. * however it can also be used as a standalone function call from the H264Format object. * * @access public * @author Oliver Lillie * @param Media $media * @return Media */ public function postProcessFastStart(Media $media) { // TODO possibly look at setting -movflags faststart options on ffmpeg instead of this. // set the yamdi input and output options. $output = $media->getMediaPath(); $temp_output = $output . '.qtfaststart.' . pathinfo($output, PATHINFO_EXTENSION); // build the qtfaststart process $qtfaststart_process = new ProcessBuilder('qtfaststart', $this->_config); $exec = $qtfaststart_process->add($output)->add($temp_output)->getExecBuffer(); // execute the process. $exec->setBlocking(true)->execute(); // check for any qt-faststart errors if ($exec->hasError() === true) { if (is_file($temp_output) === true) { //@unlink($temp_output); } if ($this->_enforce_qt_faststart_success === true) { //@unlink($output); throw new FfmpegProcessPostProcessException('qt-faststart post processing of "' . $output . '" failed. The output file has been removed. Any additional qt-faststart message follows: ' . $exec->getExecutedCommand() . ' ' . $exec->getBuffer()); } // TODO, log or exception not sure as the original file is ok. } else { // nope everything went ok. so delete ffmpeg file, and then rename yamdi file to that of the original. unlink($output); rename($temp_output, $output); } return $media; }
/** * Process a file, executing Compass executable. * * Execute the Compass executable, overriding the no-op function inside * WordlessPreprocessor. */ protected function process_file($file_path, $temp_path) { $this->validate_executable_or_throw($this->preference("css.compass_path")); // On cache miss, we build the file from scratch $pb = new ProcessBuilder(array($this->preference("css.compass_path"), 'compile', $temp_path)); $config = array("http_path" => "./", "http_images_dir" => "../images", "images_dir" => "../assets/images", "http_fonts_dir" => "../fonts", "fonts_dir" => "../assets/fonts", "css_path" => $temp_path, "relative_assets" => false, "output_style" => ":" . $this->preference("css.output_style"), "environment" => ":production", "sass_path" => dirname($file_path)); $ruby_config = array(); foreach ($this->preference("css.require_libs") as $lib) { $ruby_config[] = sprintf('require "%s"', $lib); } foreach ($config as $name => $value) { if (strpos($value, ":") === 0) { $ruby_config[] = sprintf('%s = %s', $name, $value); } else { if (is_bool($value)) { $ruby_config[] = sprintf('%s = %s', $name, $value ? "true" : "false"); } else { $ruby_config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\')); } } } $config_path = tempnam($temp_path, 'compass_config'); file_put_contents($config_path, implode("\n", $ruby_config) . "\n"); $pb->add("--config")->add($config_path); $output = $temp_path . "/" . basename($file_path, pathinfo($file_path, PATHINFO_EXTENSION)) . 'css'; $proc = $pb->getProcess(); $code = $proc->run(); if (0 < $code) { unlink($config_path); throw new WordlessCompileException("Failed to run the following command: " . $proc->getCommandLine() . "\n" . "Generated config:\n" . implode("\n", $ruby_config), $proc->getErrorOutput()); } unlink($config_path); return file_get_contents($output); }
/** * Process a file, executing Compass executable. * * Execute the Compass executable, overriding the no-op function inside * WordlessPreprocessor. */ protected function process_file($file_path, $result_path, $temp_path) { $this->validate_executable_or_die($this->preference("compass.compass_path")); // On cache miss, we build the file from scratch $pb = new ProcessBuilder(array($this->preference("compass.compass_path"), 'compile', $temp_path)); $config = array("http_path" => Wordless::theme_url(), "images_dir" => "assets/images", "css_path" => $temp_path, "relative_assets" => false, "output_style" => ":" . $this->preference("compass.output_style"), "environment" => ":production", "sass_path" => dirname($file_path)); $ruby_config = array(); foreach ($config as $name => $value) { if (strpos($value, ":") === 0) { $ruby_config[] = sprintf('%s = %s', $name, $value); } else { if (is_bool($value)) { $ruby_config[] = sprintf('%s = %s', $name, $value ? "true" : "false"); } else { $ruby_config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\')); } } } $config_path = tempnam($temp_path, 'compass_config'); file_put_contents($config_path, implode("\n", $ruby_config) . "\n"); $pb->add("--config")->add($config_path); $output = $temp_path . "/" . basename($file_path, pathinfo($file_path, PATHINFO_EXTENSION)) . 'css'; $proc = $pb->getProcess(); $code = $proc->run(); if (0 < $code) { unlink($config_path); $this->die_with_error($proc->getErrorOutput()); } unlink($config_path); return file_get_contents($output); }
public function __construct(array $arguments = array()) { $this->arguments = $arguments; if (null === self::$isWindows) { self::$isWindows = defined('PHP_WINDOWS_VERSION_MAJOR'); } }
/** * Process a file, executing lessc executable. * * Execute the lessc executable, overriding the no-op function inside * WordlessPreprocessor. * * If using php-fpm, remember to pass the PATH environment variable * in php-fpm.ini (e.g. env[PATH]=/usr/local/bin:/usr/bin:/bin) */ protected function process_file($file_path, $result_path, $temp_path) { $this->validate_executable_or_die($this->preference("css.lessc_path")); // On cache miss, we build the file from scratch $pb = new ProcessBuilder(array($this->preference("css.lessc_path"), $file_path)); // Since the official lessc executable relies on node.js, we need to // inherit env to get access to $PATH so we can find the node executable $pb->inheritEnvironmentVariables(); if ($this->preference("css.compress")) { $pb->add("-compress"); } $proc = $pb->getProcess(); $code = $proc->run(); if (0 < $code) { throw new WordlessCompileException("Failed to run the following command: " . $proc->getCommandLine(), $proc->getErrorOutput()); } return $proc->getOutput(); }
/** * Overrides WordlessPreprocessor::process_file() */ protected function process_file($file_path, $temp_path) { $this->validate_executable_or_throw($this->preference("js.ruby_path")); // On cache miss, we build the JS file from scratch $pb = new ProcessBuilder(array($this->preference("js.ruby_path"), Wordless::join_paths(dirname(__FILE__), "sprockets_preprocessor.rb"), "compile")); // Fix for MAMP environments, see http://goo.gl/S5KFe for details $pb->setEnv("DYLD_LIBRARY_PATH", ""); $pb->add($file_path); $pb->add("--paths"); $pb->add(Wordless::theme_static_javascripts_path()); $pb->add(Wordless::theme_javascripts_path()); if ($this->preference("js.yui_compress")) { $pb->add("--compress"); } if ($this->preference("js.yui_munge")) { $pb->add("--munge"); } $proc = $pb->getProcess(); $code = $proc->run(); if ($code != 0) { throw new WordlessCompileException("Failed to run the following command: " . $proc->getCommandLine(), $proc->getErrorOutput()); } return $proc->getOutput(); }
/** * Overrides WordlessPreprocessor::process_file() */ protected function process_file($file_path, $result_path, $temp_path) { $this->validate_executable_or_die($this->preference("sprockets.ruby_path")); // On cache miss, we build the JS file from scratch $pb = new ProcessBuilder(array($this->preference("sprockets.ruby_path"), Wordless::join_paths(dirname(__FILE__), "sprockets_preprocessor.rb"))); // Fix for MAMP environments, see http://goo.gl/S5KFe for details $pb->setEnv("DYLD_LIBRARY_PATH", ""); $pb->add(Wordless::theme_static_javascripts_path()); $pb->add(Wordless::theme_javascripts_path()); $pb->add($file_path); $proc = $pb->getProcess(); $code = $proc->run(); if ($code != 0) { $this->die_with_error($proc->getErrorOutput()); } return $proc->getOutput(); }
/** * Saves the animated gif. * * @access public * @author Oliver Lillie * @param string $save_path * @param float $frame_delay The delay of each frame. * @return Image */ public function save($save_path, $frame_delay = 0.1) { parent::save($save_path, $frame_delay); // build the gifsicle process $process = new ProcessBuilder('convert', $this->_config); // set the frame duration $process->add('-delay')->add($frame_delay * 100); $process->add('-loop')->add($this->_loop_count === AnimatedGif::UNLIMITED_LOOPS ? '0' : $this->_loop_count + 1); // add in all the frames foreach ($this->_frames as $path) { $process->add($path); } // add the output path $process->add($save_path); // execute the process. $exec = $process->getExecBuffer(); $exec->setBlocking(true)->execute(); // check for any gifsicle errors if ($exec->hasError() === true) { throw new FfmpegProcessPostProcessException('AnimatedGif save using `convert` "' . $save_path . '" failed. Any additional convert message follows: ' . $exec->getBuffer()); } return new Image($save_path, $this->_config); }
/** * Specifically for authomatic post processing of FLV output to inject metadata, * however it can also be used as a standalone function call from the FLVFormat object. * * @access public * @author Oliver Lillie * @param Media $media * @return Media */ public function postProcessMetaData(Media $media) { // set the yamdi input and output options. $output = $media->getMediaPath(); $temp_output = $output . '.yamdi.flv'; // build the yamdi process $yamdi_process = new ProcessBuilder('yamdi', $this->_config); $exec = $yamdi_process->add('-i')->add($output)->add('-o')->add($temp_output)->add('-s')->add('-k')->getExecBuffer(); // execute the process. $exec->setBlocking(true)->execute(); // check for any yamdi errors if ($exec->hasError() === true) { if (is_file($temp_output) === true) { @unlink($temp_output); } if ($this->_enforce_meta_data_success === true) { @unlink($output); throw new FfmpegProcessPostProcessException('Yamdi post processing of "' . $output . '" failed. The output file has been removed. Any additional Yamdi message follows: ' . $exec->getBuffer()); } // TODO, log or exception not sure as the original file is ok. } else { // nope everything went ok. so delete ffmpeg file, and then rename yamdi file to that of the original. unlink($output); rename($temp_output, $output); } return $media; }
/** * Get the ExecBuffer object by combining the commands the creating in the buffer. * * @access protected * @author Oliver Lillie * @return ExecBuffer */ protected function _getExecBuffer() { $this->_combineCommands(); return parent::getExecBuffer(); }
/** * Saves the animated gif. * * @access public * @author Oliver Lillie * @param string $save_path * @param float $frame_delay The delay of each frame. * @return Image */ public function save($save_path, $frame_delay = 0.1) { parent::save($save_path, $frame_delay); // build the gifsicle process $gifsicle_process = new ProcessBuilder('gifsicle', $this->_config); // add in all the frames foreach ($this->_frames as $path) { $gifsicle_process->add($path); } // set the looping count if ($this->_loop_count === AnimatedGif::UNLIMITED_LOOPS) { $gifsicle_process->add('-l'); } else { $gifsicle_process->add('-l')->add($this->_loop_count); } // set the frame duration //$gifsicle_process->add('-d')->add($frame_delay*1000); // add the output path $gifsicle_process->add('-o')->add($save_path); // execute the process. $exec = $gifsicle_process->getExecBuffer(); $exec->setBlocking(true)->execute(); $this->__destruct(); // check for any gifsicle errors if ($exec->hasError() === true) { throw new FfmpegProcessPostProcessException('AnimatedGif save using `gifsicle` save "' . $save_path . '" failed. Any additional gifsicle message follows: ' . $exec->getBuffer()); } return new Image($save_path, $this->_config); }