<?php
//https://www.ffmpeg.org/ffmpeg.html
/**
* 注:
* 1.其实php有相关ffmpeg-php 扩展的 不一定要命令去执行
* 2.有些视频没有转换 估计是文件名有空白
* 3.文件不是递归的 只做了2层
* 4.分割视频的时候是根据时间而不是根据文件的大小来分割
* 5.当你关闭了执行程序的浏览器时 其实程序还是在运行着的
**/
set_time_limit(0);
header("Content-type: text/html; charset=gbk");
define('FFMPEG_PATH', 'ffmpeg -i "%s" 2>&1');
function getVideoInfo($file) {
$command = sprintf(FFMPEG_PATH, $file);
ob_start();
passthru($command);
$info = ob_get_contents();
ob_end_clean();
$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']; //实际播放时间
}
$data['size'] = filesize($file); //文件大小
return $data;
}
//ffmpeg -i input.mp4 output.avi
$ffmpegCommand1 = 'ffmpeg -i %s %s';//视频转换
//ffmpeg -ss 00:00:00 -i input.mp4 -c copy -avoid_negative_ts 1 -t 60 output.mp4
$ffmpegCommand2 = 'ffmpeg -ss %s:%s:00 -i %s -c copy -avoid_negative_ts 1 -t %d %s';//视频分割
$root = './video';
$files = scandir($root);
$saveRoot = './handler';
foreach ($files as $k => $v)
{
if($v == '..' || $v == '.')
{
continue;
}
$tmp1 = $v;
$dir = $root.'/'.$tmp1;
if(is_dir($dir))
{
$savePath = $saveRoot.'/'.$tmp1;
if(!file_exists($savePath))
{
mkdir($savePath);
}
$files2 = scandir($dir);
foreach ($files2 as $key => $value) {
if($value == '.' || $value == '..')
continue;
$tmp2 = $value;
$dir2 = $dir.'/'.$tmp2;
if(is_file($dir2))
{
$fileInfo = pathinfo($dir2);
$filename = basename($dir2,'.'.$fileInfo['extension']);
// $filename = mb_substr($filename, 0,strripos($filename, '.')-1);
$filePath = $savePath.'/'.$filename.'.mp4';
if(file_exists($filePath))
{
continue;
}
//echo $filePath;exit;
$command = sprintf($ffmpegCommand1,$dir2,$filePath);
//echo $command;
if(system($command))
{
echo '压缩失败';exit;
}else
{
echo $dir2."压缩成功<br />";
ob_flush();
flush();
}
}
}
}
//echo "filename:" . $v . "<br>";
}
//分割视频
$maxSize = 30 * 1024 * 1024;
$offset = 3 * 1024 * 1024;//允许偏移
$files = scandir($saveRoot);
foreach ($files as $k => $v)
{
if($v == '.' || $v == '..')
{
continue;
}
$tmp1 = $v;
$dir = $saveRoot.'/'.$tmp1;
if(is_dir($dir) )
{
$files2 = scandir($dir);
foreach ($files2 as $key => $value)
{
$times = 600;//截取十分钟
$minute = $times/60;
$divisionSavePath = '';//分割视频保存路径
$tmp2 = $value;
$dir2 = $dir.'/'.$tmp2;
if(is_file($dir2))
{
//echo $dir2;
$videoInfo = getVideoInfo($dir2);
//print_r($videoInfo);exit;
if($videoInfo['size'] > $maxSize + $offset)
{
$timeLast = 0;//截取最后视频
$startMinute = 0;//分割开始分钟
$startHour = 0;//分割开始小时
$filename = basename($dir2,'.mp4');
$divisionSavePath = $dir.'/'.$filename;
//echo $divisionSavePath;exit;
if(!file_exists($divisionSavePath))
{
if(!mkdir($divisionSavePath))
{
echo '文件夹创建失败';exit;
}
}
$seconds = $videoInfo['seconds'];
$count = (int)($seconds/$times);
$last = $seconds%$times;
//末尾视频不到10分钟
if($last >0)
{
//大于20秒独立剪切一份
if($last > 180)
{
$timeLast = $last;
$count++;
}
else
{
$timeLast = $times + $last;
}
}
for ($i=0; $i < $count; $i++)
{
$num = $i+1;
if($num < 10)
{
$num = '0'.$num;
}
//最后一次不够3分钟
if($num == $count)
{
$times = $timeLast;
}
if($startMinute < 10)
{
$startMinute = '0'.(int)$startMinute;
}
if($startMinute >= 60)
{
$startHour += 1;
$startMinute = 0;
}
if($startHour < 10)
{
$startHour = '0'.(int)$startHour;
}
$divisionVideo = $divisionSavePath.'/'.$num.$filename.'.mp4';
if(file_exists($divisionVideo))
{
continue;
}
$command = sprintf($ffmpegCommand2,$startHour,$startMinute,$dir2,$times,$divisionVideo);
if(system($command))//失败返回非0
{
echo '转换失败';exit;
}
$startMinute += $minute;
}
//ffmpeg -ss %s:%s:00 -i %s -c copy -avoid_negative_ts 1 -t %d %s
}
//@unlink($dir2);
}
}
}
}
exit;