&1'; $cmd = sprintf($cmd, escapeshellarg($from), escapeshellarg($to)); $proc = proc_open($cmd, [1 => ['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, [1 => ['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 = []; $data = []; preg_match_all('/Duration: (.*)/', $buffer, $matches); if (count($matches) > 0) { $parts = explode(', ', trim($matches[1][0])); $data['duration'] = []; $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'] = []; $data['duration']['timecode']['rounded'] = substr($timecode, 0, 8); $data['duration']['timecode']['seconds'] = []; $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'] = []; preg_match('/([0-9]{1,5})x([0-9]{1,5})/', $matches[2], $dimensions_matches); $dimensions_value = $dimensions_matches[0]; $data['video']['dimensions'] = [ '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'] = []; $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 = [$dimensions_value, $fps_value]; $formats = []; 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; } }