&1'; $cmd = sprintf($cmd, escapeshellarg($from), escapeshellarg($to)); $proc = proc_open($cmd, array(1 => array('pipe', 'w')), $pipes); $stdout = ''; $i = 0; while (!feof($pipes[1])) { $stdout .= fread($pipes[1], 256); $i++; } fclose($pipes[1]); $return = proc_close($proc); Qs_Ffmpeg::logMessage($stdout, (boolean) $return); if (strpos($stdout, 'lame: output buffer too small') !== false) { return true; } return !(boolean) $return; } public static function createThumbnail($video, $thumb, $size = null, $time = '0:00:05') { $pipes = null; $cmd = 'ffmpeg -y -i %s -vframes 1 -ss ' . $time . ((null === $size) ? '' : ' -s ' . $size) . ' -f mjpeg %s 2>&1'; $cmd = sprintf($cmd, escapeshellarg($video), escapeshellarg($thumb)); $proc = proc_open( $cmd, array(1 => array('pipe', 'w')), $pipes ); $stdout = ''; $i = 0; while (!feof($pipes[1])) { $stdout .= fread($pipes[1], 256); $i++; } fclose($pipes[1]); $return = proc_close($proc); Qs_Ffmpeg::logMessage($stdout, (boolean) $return); return !(boolean) $return; } public static function logMessage($message, $error = false) { if (Qs_Ffmpeg::$_debug) { $hFile = fopen(BASE_PATH . '/tmp/#ffmpeg.log', 'a+'); fwrite( $hFile, sprintf( "[%s] (%s) %s\n", $error ? 'ERROR' : 'DEBUG', date('r'), $message ), FILE_APPEND ); fclose($hFile); } } public static function getFileInfo($file) { $buffer = ''; exec('ffmpeg -i ' . escapeshellarg($file) . ' 2>&1', $buffer); $buffer = implode("\n", $buffer); $matches = array(); $data = array(); preg_match_all('/Duration: (.*)/', $buffer, $matches); if(count($matches) > 0) { $parts = explode(', ', trim($matches[1][0])); $data['duration'] = array(); $timecode = $parts[0]; //$data['duration']['seconds'] = Qs_Ffmpeg::timecodeToSeconds($timecode); $data['bitrate'] = intval(ltrim($parts[2], 'bitrate: ')); $data['duration']['start'] = ltrim($parts[1], 'start: '); $data['duration']['timecode'] = array(); $data['duration']['timecode']['rounded'] = substr($timecode, 0, 8); $data['duration']['timecode']['seconds'] = array(); $data['duration']['timecode']['seconds']['exact'] = $timecode; $data['duration']['timecode']['seconds']['excess'] = intval(substr($timecode, 9)); } // match the video stream info preg_match('/Stream(.*): Video: (.*)/', $buffer, $matches); if(count($matches) > 0) { $data['video'] = array(); preg_match('/([0-9]{1,5})x([0-9]{1,5})/', $matches[2], $dimensions_matches); $dimensions_value = $dimensions_matches[0]; $data['video']['dimensions'] = array( 'width' => floatval($dimensions_matches[1]), 'height' => floatval($dimensions_matches[2]) ); // get the framerate preg_match('/([0-9\.]+) (fps|tb)\(r\)/', $matches[0], $fps_matches); $data['video']['frame_rate'] = floatval($fps_matches[1]); $fps_value = $fps_matches[0]; // get the ratios preg_match('/\[PAR ([0-9\:\.]+) DAR ([0-9\:\.]+)\]/', $matches[0], $ratio_matches); if(count($ratio_matches)) { $data['video']['pixel_aspect_ratio'] = $ratio_matches[1]; $data['video']['display_aspect_ratio'] = $ratio_matches[2]; } // work out the number of frames if(isset($data['duration']) && isset($data['video'])) { // set the total frame count for the video $data['video']['frame_count'] = ceil($data['duration']['seconds'] * $data['video']['frame_rate']); // set the framecode $frames = ceil($data['video']['frame_rate']*($data['duration']['timecode']['seconds']['excess']/10)); $data['duration']['timecode']['frames'] = array(); $data['duration']['timecode']['frames']['exact'] = $data['duration']['timecode']['rounded'].'.'.$frames; $data['duration']['timecode']['frames']['excess'] = $frames; $data['duration']['timecode']['frames']['total'] = $data['video']['frame_count']; } // formats should be anything left over, let me know if anything else exists $parts = explode(',', $matches[2]); $other_parts = array($dimensions_value, $fps_value); $formats = array(); foreach($parts as $key=>$part) { $part = trim($part); if(!in_array($part, $other_parts)) { array_push($formats, $part); } } $data['video']['pixel_format'] = $formats[1]; $data['video']['codec'] = $formats[0]; } return $data; } }