PHP使用ffmpeg壓縮視頻
視頻壓縮可以有一下方式:
1.壓縮分辨率
例如視頻的分辨率是720x1280,可以壓縮分辨率爲360x640
2.壓縮幀數
通過壓縮視頻的幀數來壓縮,可以壓縮視頻的幀數到1秒10幀甚至1秒5幀
3.壓縮比特率
即壓縮視頻的碼率,要求不高的話可以壓縮到700kb/s左右
4.壓縮音頻碼率
壓縮視頻的音頻碼率,一般可以壓縮到128kb/s或者64kb/s
5.修改視頻編碼方式
現在普遍是H.264編碼,已經是最優編碼
ffmpeg命令
1.查看視頻信息
ffmpeg -i video.mp4
bitrate:1724kb/s就是比特率,128kb/s就是音頻的碼率,720x1280就是分辨率
2.壓縮
我這邊壓縮視頻的做法是隻壓縮比特率和分辨率,這樣對視頻的影響最小
ffmpeg -i video.mp4 -s 360x640 -b:v 862k new.mp4
其中-s 360x640表示修改分辨率爲360x640
其中-b:v 862k表示修改比特率爲862kb/s
其中video.mp4爲原視頻
其中new.mp4爲壓縮後的視頻地址
其他壓縮命令:
1.壓縮幀數
ffmpeg -i video.mp4 -r 5 new.mp4
其中-r 5表示1秒5幀
2.壓縮音頻碼率
ffmpeg -i video.mp4 -b:a 64k new.mp4
其中-b:a 64k表示音頻碼率爲64k/s
3.修改編碼方式
ffmpeg -i video.mp4 -vcodec libx264 new.mp4
其中-vcodec libx264表示H.264編碼
上面的命令都是可以組合使用的,找到符合需求的命令組合壓縮視頻即可。
PHP代碼實現獲取視頻信息以及壓縮(壓縮的組合命令是分辨率和比特率):
/* 視頻壓縮 */
public function compressVideo($file, $file_name) {
$file_content = file_get_contents($file);
$compress_path = PUBLIC_PATH;
$compress_file = $compress_path . $file_name . '.mp4';
$compress_after_file = $compress_path . $file_name . '_compress.mp4';
try{
file_put_contents($compress_file, $file_content);
$video_info;
exec(FFMPEG_PATH . "ffmpeg -i {$compress_file} 2>&1", $video_info);
$video_info = implode(' ', $video_info);
$bitrate = ''; // 比特率
$resolution = ''; // 分辨率
if(preg_match("/Duration: (.*?), start: (.*?), bitrate: (\d*) kb\/s/", $video_info, $match)) {
$bitrate = $match[3];
}
if(preg_match("/Video: (.*?), (.*?), (.*?)[,\s]/", $video_info, $match)) {
$resolution = $match[3];
}
$file_size = filesize($compress_file);
$file_size = intval($file_size / 1048576);
if(empty($bitrate)) throwErr('找不到比特率信息');
if(empty($resolution)) throwErr('找不到分辨率信息');
if($file_size < 10) throwErr('視頻大小不足10M,不需要壓縮', null, 1100);
$resolution = explode('x', $resolution);
$bitrate_update = '';
$resolution_width_update = '';
$resolution_height_update = '';
$bitrate_update = $this->getVideoCompressBitrate($bitrate);
$resolution_percent = 0;
if($resolution[0] > $resolution[1]) {
if($resolution[1] > 320) {
$resolution_percent = $resolution[1] <= 520 ? 0.8 : 0.5;
}
}else {
if($resolution[0] > 320) {
$resolution_percent = $resolution[0] <= 520 ? 0.8 : 0.5;
}
}
if($resolution_percent > 0) {
$resolution_width_update = intval($resolution[0] * $resolution_percent);
$resolution_height_update = intval($resolution[1] * $resolution_percent);
}
if(empty($bitrate_update) && empty($resolution_width_update)) throwErr('比特率和分辨率同時不滿足壓縮條件', null, 1100);
$compress_bitrate = '';
$compress_resolution = '';
if(!empty($bitrate_update)) {
$compress_bitrate = "-b:v {$bitrate_update}k";
}
if(!empty($resolution_width_update)) {
$compress_resolution = "-s {$resolution_width_update}x{$resolution_height_update}";
}
$compress_exec = FFMPEG_PATH . "ffmpeg -i {$compress_file} %s% %v% {$compress_after_file}";
$compress_exec = str_replace(array('%s%', '%v%'), array($compress_resolution, $compress_bitrate), $compress_exec);
exec($compress_exec);
unlink($compress_file);
return array('compress_file' => $compress_after_file);
}catch(\Exception $e) {
unlink($compress_file);
return array();
}
}
/* 獲取視頻壓縮比特率 */
public function getVideoCompressBitrate($bitrate, $query_count = 0) {
$bitrate_update = '';
if($bitrate >= 700) {
if($bitrate <= 1000) {
$bitrate_update = intval($bitrate * 0.8);
}else {
$bitrate_update = intval($bitrate * 0.5);
}
}
if(empty($bitrate_update)) {
return $query_count == 0 ? $bitrate_update : $bitrate;
}else {
return $this->getVideoCompressBitrate($bitrate_update, ++$query_count);
}
}
這裏提供PHP獲取視頻的所有信息代碼:
$info = '';
exec(FFMPEG_PATH . "ffmpeg -i {$compress_file} 2>&1", $info);
$data = array();
if (preg_match("/Duration: (.*?), start: (.*?), bitrate: (\d*) kb\/s/", $info, $match)) {
$data['duration'] = $match[1]; //播放時間
$arr_duration = explode(':', $match[1]);
$data['seconds'] = $arr_duration[0] * 3600 + $arr_duration[1] * 60 + $arr_duration[2]; //轉換播放時間爲秒數
$data['start'] = $match[2]; //開始時間
$data['bitrate'] = $match[3]; //碼率(kb)
}
if (preg_match("/Video: (.*?), (.*?), (.*?)[,\s]/", $info, $match)) {
$data['vcodec'] = $match[1]; //視頻編碼格式
$data['vformat'] = $match[2]; //視頻格式
$data['resolution'] = $match[3]; //視頻分辨率
$arr_resolution = explode('x', $match[3]);
$data['width'] = $arr_resolution[0];
$data['height'] = $arr_resolution[1];
}
if (preg_match("/Audio: (\w*), (\d*) Hz/", $info, $match)) {
$data['acodec'] = $match[1]; //音頻編碼
$data['asamplerate'] = $match[2]; //音頻採樣頻率
}
if (isset($data['seconds']) && isset($data['start'])) {
$data['play_time'] = $data['seconds'] + $data['start']; //實際播放時間
}
return $data;