diff --git a/src/PHPVideoToolkit/AudioFormat.php b/src/PHPVideoToolkit/AudioFormat.php index d80c91c..cf1c78c 100644 --- a/src/PHPVideoToolkit/AudioFormat.php +++ b/src/PHPVideoToolkit/AudioFormat.php @@ -71,7 +71,7 @@ public function __construct($input_output_type=Format::OUTPUT, Config $config=nu 'input' => '-request_channels ', 'output' => '-ac ', ), - 'audio_volume' => '-af "volume="', + 'audio_volume' => '-af volume=', )); $this->_restricted_audio_bitrates = null; @@ -211,7 +211,7 @@ public function setAudioCodec($audio_codec) if($codecs_in_preference_order !== false){ $audio_codec = array_shift($codecs_in_preference_order); while(in_array($audio_codec, $codecs) === false && count($codecs_in_preference_order) > 0){ - $audio_codec = array_shift($codecs_in_preference_order); + array_push($codecs, $audio_codec); } } } @@ -270,6 +270,7 @@ public function setAudioBitrate($bitrate) } $this->_format['audio_bitrate'] = $bitrate; + $this->setQualityVsStreamabilityBalanceRatio(NULL); return $this; } @@ -351,7 +352,7 @@ public function setAudioChannels($channels) * @author Oliver Lillie * @param integer $volume The level of the volumn. Must be higher than or euqal to 0. * @return PHPVideoToolkit\AudioFormat Returns the current object. - * @throws \InvalidArgumentException If $volume value is not an integer. + * @throws \InvalidArgumentException If $volume value neither ends in 'dB' nor is an integer or float. * @throws \InvalidArgumentException If $volume is less than 0. */ public function setVolume($volume) @@ -362,16 +363,18 @@ public function setVolume($volume) return $this; } - if(is_int($volume) === false) + //Volume can also end in dB, and can be float as well as integer + if(preg_match('/db$/i', $volume) === false && is_numeric($volume) === false) { - throw new \InvalidArgumentException('The volumne value must be an integer.'); + throw new \InvalidArgumentException('The volume value must be an integer or float or end in "dB".'); } - else if($volume < 0) + //Make sure that volume is not less than 0 even if it ends in dB + else if(preg_replace('/db$/i',"",$volume) < 0) { throw new \InvalidArgumentException('Unrecognised volume value "'.$volume.'" set in \\PHPVideoToolkit\\'.get_class($this).'::setVolume. The value must be higher than or equal to 0.'); } - $this->_format['audio_volume'] = $volume; + $this->_format['audio_volume'] = str_replace('db', 'dB', $volume); return $this; } @@ -396,7 +399,7 @@ public function setAudioQuality($quality) } else if (is_int($quality) === false && is_float($quality) === false) { - throw new \InvalidArgumentException('The volume value must be an integer or float value.'); + throw new \InvalidArgumentException('Audio quality value must be an integer or float value.'); } // interpret quality into ffmpeg value diff --git a/src/PHPVideoToolkit/ExecBuffer.php b/src/PHPVideoToolkit/ExecBuffer.php index 7d1d798..912a759 100644 --- a/src/PHPVideoToolkit/ExecBuffer.php +++ b/src/PHPVideoToolkit/ExecBuffer.php @@ -944,7 +944,7 @@ public function setBufferOutput($buffer_output) { if(in_array($buffer_output, array(null, self::DEV_NULL, self::TEMP)) === false) { - $dir = dirname($buffer_ouput); + $dir = dirname($buffer_output); if(is_dir($dir) === false) { throw new \InvalidArgumentException('Buffer output parent directory "'.$dir.'" is not a directory.'); diff --git a/src/PHPVideoToolkit/Media.php b/src/PHPVideoToolkit/Media.php index c035889..b4ae1d9 100644 --- a/src/PHPVideoToolkit/Media.php +++ b/src/PHPVideoToolkit/Media.php @@ -1260,6 +1260,19 @@ public function readVideoComponent($read_from_cache=true) { return parent::getFileVideoComponent($this->_media_file_path, $read_from_cache); } + + /** + * Returns mean and max volume information of the file. + * + * @access public + * @author Samar Rizvi + * @param boolean $read_from_cache + * @return mixed Returns an array of found data, otherwise returns null. + */ + public function readVolumeComponent($read_from_cache=true) + { + return parent::getFileVolumeComponent($this->_media_file_path, $read_from_cache); + } /** * Returns any audio information about the file if available. diff --git a/src/PHPVideoToolkit/MediaParser.php b/src/PHPVideoToolkit/MediaParser.php index e02e40f..a494866 100644 --- a/src/PHPVideoToolkit/MediaParser.php +++ b/src/PHPVideoToolkit/MediaParser.php @@ -57,6 +57,7 @@ public function getFileInformation($file_path, $read_from_cache=true) 'container' => $this->getFileContainerFormat($file_path, $read_from_cache), 'duration' => $this->getFileDuration($file_path, $read_from_cache), 'bitrate' => $this->getFileBitrate($file_path, $read_from_cache), + 'volume' => $this->getFileVolumeComponent($file_path, $read_from_cache), 'start' => $this->getFileStart($file_path, $read_from_cache), 'video' => $this->getFileVideoComponent($file_path, $read_from_cache), 'audio' => $this->getFileAudioComponent($file_path, $read_from_cache), @@ -249,6 +250,55 @@ public function getFileType($file_path, $read_from_cache=true) $this->_cacheSet($cache_key, $data); return $data; } + + /** + * Returns the files mean volume and max volume if available, otherwise returns null. + * + * @access public + * @author Samar Rizvi + * @param string $file_path + * @param boolean $read_from_cache + * @return mixed Returns an array of found data, otherwise returns null. + */ + public function getFileVolumeComponent($file_path, $read_from_cache=true) + { + $cache_key = 'media_parser/'.md5(realpath($file_path)).'_parsed_volume'; + if($read_from_cache === true && ($data = $this->_cacheGet($cache_key, -1)) !== -1) + { + return $data; + } + +// get the raw data + $raw_data = $this->getFileRawInformation($file_path, $read_from_cache); + +// grab the volume + $data = null; + + if(preg_match_all ('/^.*(mean_volume)(:)(\s+)([+-]?\d*\.\d+)(?![-+0-9\.])( )(dB)/im', $raw_data, $matches) > 0) + { + $data = array(); + + $float1=$matches[4][0]; + $word_unit=$matches[6][0]; + + $data['mean_volume'] = $float1 . $word_unit; + } + + if(preg_match_all ('/^.*(max_volume)(:)(\s+)([+-]?\d*\.\d+)(?![-+0-9\.])( )(dB)/im', $raw_data, $matches) > 0) + { + if(!is_array($data)) { + $data = array(); + } + + $float1=$matches[4][0]; + $word_unit=$matches[6][0]; + + $data['max_volume'] = $float1 . $word_unit; + } + + $this->_cacheSet($cache_key, $data); + return $data; + } /** * Returns any video information about the file if available. @@ -687,11 +737,22 @@ public function getFileRawInformation($file_path, $read_from_cache=true) return $data; } + $isWindowsPlatform = defined('PHP_WINDOWS_VERSION_BUILD'); + // execute the ffmpeg lookup $exec = new FfmpegProcess('ffmpeg', $this->_config); - $raw_data = $exec->setInputPath($real_file_path) - ->execute() - ->getBuffer(); + $exec_cmd = $exec->setInputPath($real_file_path) + ->addCommand('-af', 'volumedetect') + ->addCommand('-f', 'NULL'); + + if($isWindowsPlatform) { + $exec_cmd = $exec_cmd->addCommand('NUL'); + } else { + $exec_cmd = $exec_cmd->addCommand('/dev/null'); + } + + $raw_data = $exec_cmd->execute() + ->getBuffer(); // check the process for any errors. if($exec->hasError() === true && ($last_line = $exec->getLastLine()) !== 'At least one output file must be specified') diff --git a/src/PHPVideoToolkit/VideoFormat.php b/src/PHPVideoToolkit/VideoFormat.php index d508762..bd1d72b 100644 --- a/src/PHPVideoToolkit/VideoFormat.php +++ b/src/PHPVideoToolkit/VideoFormat.php @@ -605,6 +605,7 @@ public function setVideoBitrate($bitrate) } $this->_format['video_bitrate'] = $bitrate; + $this->setQualityVsStreamabilityBalanceRatio(NULL); return $this; //throw new Exception('Unrecognised video bitrate "'.$bitrate.'" set in \\PHPVideoToolkit\\'.get_class($this).'::setVideoBitrate');