设为首页 收藏本站
查看: 724|回复: 0

[经验分享] php工具类之【视频转换类】

[复制链接]

尚未签到

发表于 2017-4-6 11:54:00 | 显示全部楼层 |阅读模式
  在这里简要介绍一下搭建视频网站所需要的软件,这些软件包括ffmpeg、mplayer。它们主要用来负责视频的转码工作,ffmpeg基本上对所有格式的视频文件都可以处理,但是对rmvb和rm格式的视频无法转码,这个时候,就需要通过MPlayer转码工具的协助,完成转码任务。
  如果要在网页上播放,就需要转码。如果采用flash播放器播放视频,这个时候就需要转码出flv格式的视频;如果采用html5或者pad播放,就需要转码出MP4格式的视频。在转码的处理中,我们通常会分别转码出两种视频,分别是高清和流畅视频,方便不同网速的用户观看。

class VideoConvert{
//视频的原始文件
var $src;
//后缀名
var $suffix;
//视频实际类型
var $format;
//视频md5value: 在tester中主要用于生成同级目录下的缩略图的初始位置
var $md5value;
//视频长度
var $ori_length;
//视频信息
var $src_identify = array();
//错误日志
var $err_log = array();
//指令地址
var $system_mencoder = '/usr/bin/mencoder ';
var $system_ffmpeg = '/usr/local/bin/ffmpeg ';
var $system_mplayer = '/usr/bin/mplayer ';
var $system_yamdi = '/usr/local/bin/yamdi ';
var $system_qtfaststart = '/usr/local/bin/qt-faststart ';
function __construct($filePath) {
$this->src = $filePath;
//源文件不存在
if (!file_exists($this->src)) {
print_r("the file[$this->src] not exists.\r\n<br>");
} else {
print_r("the file[$this->src] exists.\r\n<br>");
}
}
function init() {
//截取后缀名
$this->suffix = strtolower(substr($this->src, strrpos($this->src, '.')));
//读取文件内容的前3个字节,判断真实文件格式
$handle = fopen($this->src, 'r');
$this->format = strtolower(fread($handle, 3));
fclose($handle);
//视频的md5值
$this->md5value = md5_file( $this->src );
//inentify
$this->src_identify =$this->getIdentify($this->src);
//视频长度
$this->ori_length = $this->src_identify['id_length'];
$this->ori_length = empty($this->ori_length)?0:$this->ori_length;
}
function showInfo() {
$this->pr("后缀类型:$this->suffix");
$this->pr("实际类型:$this->format");
$this->pr("md5value:$this->md5value");
$this->pr("ori_length:$this->ori_length");
$this->pr("id_demuxer:".$this->src_identify['id_demuxer']);
$this->pr("id_video_format:".$this->src_identify['id_video_format']);
}
function rmvb2avi($src, $dst, $identify) {
//$cmd = $this->system_mencoder." $src -o ".$src."_ -of avi -oac mp3lame -ovc xvid -xvidencopts bitrate=$datarate";
if($identify['id_video_format'] == 'WMV3') {
$cmd = $this->system_mencoder." $src -o $dst -of avi -oac mp3lame -ovc copy";
} else {
$cmd = $this->system_mencoder." $src -o $dst -of avi -oac mp3lame -ovc xvid -xvidencopts fixed_quant=11";
}
$this->pr($cmd);
$handle = @popen($cmd, 'r');
while (!feof($handle)) {
$line = fgets($handle, 1024);
}
@pclose($handle);
return true;
}
function video2f4v($src, $dst, $datarate) {
$cmd = $this->system_ffmpeg." -i ".$src."  -f flv -acodec libfaac -ab 16k -vcodec libx264 -coder 1 -g 250 -keyint_min 25 -sc_threshold 40 -bf 3 -b_strategy 1 -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -directpred 1 -flags +loop -deblockalpha 0 -deblockbeta 0 -flags2 +fastpskip+wpred-dct8x8 -me_method hex -me_range 16 -subq 6 -trellis 1 -b ".$datarate."k -qcomp 1 -i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 -r 29.97 -y ".$dst;//." 2>&1";
$this->pr($cmd);
$handle = @popen($cmd, 'r');
while(!feof($handle)) {
$line = fgets($handle, 1024);
}
@pclose($handle);
return true;
}
function video2flv($src, $dst) {
$cmd = $this->system_ffmpeg." -i $src -f flv -vcodec flv -ar 22050 -acodec libmp3lame -y $dst";
// 2>&1";
$this->pr($cmd);
$handle = @popen($cmd, 'r');
while(!feof($handle)) {
$line = fgets($handle, 1024);
}
@pclose($handle);
return true;
}
//转换mp4供iphone和ipad看
function video2mp4($src, $dst, $rate) {
file_exists($dst.".mp4")?@unlink($dst.".mp4"):'';
$cmd = $this->system_ffmpeg." -threads 4 -i ".$src." -r 29.97 -vcodec libx264 -flags +loop -cmp +chroma -deblockalpha 0 -crf 24 -bt ".$rate."k -refs 1 -coder 0 -subq 5 -partitions +parti4x4+parti8x8+partp8x8 -g 250 -keyint_min 25 -level 30 -qmin 10 -qmax 51 -trellis 2 -sc_threshold 40 -i_qfactor 0.71 -acodec libfaac -ab 128k -ar 48000 -f mp4 ".$dst.".mp4";
//2>&1";
$this->pr($cmd);
$handle = @popen($cmd, 'r');
while(!feof($handle)) {
$line = fgets($handle, 1024);
}
@pclose($handle);
$mp4identify = $this->getIdentify($dst.".mp4");
$mp4le = abs($mp4identify['id_length']);
if($mp4le>0) {
$cmd = $this->system_qtfaststart." ".$dst.".mp4 ".$dst.".mp4-new"." 2>&1";
$handle = @popen($cmd, 'r');
while(!feof($handle)) {
$line = fgets($handle, 1024);
}
@pclose($handle);
$mp4identify = $this->getIdentify($dst.".mp4-new");
$mp4le = abs($mp4identify['id_length']);
if ($mp4le>0) {
unlink($dst.".mp4");
rename($dst.".mp4-new",$dst.".mp4");
}
}
return true;
}
/**
* grabImage 抓图-ok
*
* @param string $src 源文件
* @param string $dst 目标文件
* @param int $length 时长
* @param int $pic_count 截图数量
* @access public
* @return void
*/
function grabImage($src, $dst, $length,$pic_count) {
$grabRes = $this->grabImageFfmpeg($src, $dst, $length,$pic_count);
if (@!filesize($dst)) {
return false;
}
return $grabRes;
}
/**
* grabImageFfmpeg 通过ffmpeg抓图-ok
*
* @param string $src 源文件
* @param string $dst 目标文件
* @access public
* @return void
*/
function grabImageFfmpeg($src, $dst, $length,$pic_count) {
//在视频中间截图
$ss = $length/2;
$cmd = $this->system_ffmpeg ." -y -i $src -vframes 1 -ss $ss -an -vcodec mjpeg -f rawvideo $dst 2>&1";
$fd = @popen($cmd, 'r');
while (!feof($fd)) {
$line = fgets($fd, 1024);
}
@pclose($fd);
$count = $pic_count+1;
if ($length>$count) {
$s = $length/$count;
for ($i=1;$i<$count;$i++) {
$dstpic = $dst.'.'.$i.'.jpg';
$cmd = $this->system_ffmpeg ." -y -i $src -vframes 1 -ss ".($i*$s)." -an -vcodec mjpeg -f rawvideo $dstpic 2>&1";
$fd = @popen($cmd, 'r');
while (!feof($fd)) {
$line = fgets($fd, 1024);
}
fclose($fd);
}
}
return true;
}
/**
* resizeImage从一个已有图片建立一个新的图片-ok
* @param string $src 源文件
* @param string $obj 目标文件
* @param string $width 目标文件宽
* @param string $height 目标文件高
* @access public
*/
function resizeImage($src, $obj, $width, $height) {
list($width_orig, $height_orig, $type_orig) = getimagesize($src);
if ($width && ($width_orig < $height_orig)) {
$width = ($height / $height_orig) * $width_orig;
} else {
$height = ($width / $width_orig) * $height_orig;
}
switch($type_orig) {
case 1:
$image = imagecreatefromgif($src);
break;
case 2:
$image = imagecreatefromjpeg($src);
break;
case 3:
$image = imagecreatefrompng($src);
break;
default:
return false;
}
$image_p = imagecreatetruecolor($width, $height);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($image_p, $obj);
return true;
}
/**
* injectMetaData 向flv文件添加元数据-ok
* 以支持播放器的拖放
* 返回flv时长
* @param string $file
* @access public
* @return init or false, if failed
*/
function injectMetaData($file) {
$info = array('code'=>false, 'msg'=>'未开始');
//文件是否存在
if (!file_exists($file)) {
$info['msg'] = '文件不存在。';
return $info;
}
$cmd = $this->system_yamdi . " -i $file -o ".$file."_ | grep lasttimestamp";
$fd = @popen($cmd, 'r');
$lasttimestamp = 0;
while (!feof($fd)) {
$line = fgets($fd, 1024);
if (strpos($line, ':')) {
$lasttimestamp = substr($line, strpos($line, ':') + 1);
}
}
pclose($fd);
$l = $this->getIdentify($file.'_');
if ($l['id_length']) {
unlink($file);
rename($file.'_',$file);
}
//Logger::trace(sprintf('lasttimestamp: %s', $lasttimestamp));
//Logger::debug('Inject End');
if ($lasttimestamp == '' || $lasttimestamp == 0){
$lasttimestamp = $this->getIdentify($file);
}
return $lasttimestamp['id_length'];
}

function pr($msg) {
echo "$msg\r\n<br>";
}
/**
* getIdentify 获取视频信息-ok
* @access public
* @return void
*/
function getIdentify($file) {
$identify = array();
if (!is_readable($file)) {
return false;
}
$cmd = $this->system_mplayer . " -msglevel all=0 -identify -vc dummy -endpos 00:00:00 $file 2>&1";
$fd = @popen($cmd, 'r');
while (!feof($fd)) {
$line = fgets($fd);
if (strpos($line, 'ID_') === 0) {
$line = explode('=', $line);
$line[0] = strtolower($line[0]);
$identify[$line[0]] = trim($line[1]);
}
}
@pclose($fd);
//假如mplayer没有获取到视频长度就用ffmpeg再次获取
//视频长度
$return = $identify['id_length'];
if ($return == '' || !is_numeric($return)){
//再次获取
$cmd = $this->system_ffmpeg . " -i $file 2>&1";
$fd = @popen($cmd, 'r');
while (!feof($fd)) {
$line = fgets($fd);
$line = trim($line);
$line = strtolower($line);
if (strpos($line, 'duration:') === 0) {
$line = explode(',', $line);
$line = explode(':', $line[0]);
$identify['id_length'] = abs($line[1])*3600+abs($line[2])*60+abs(((int)$line[3]));
break;
}
}
}
return $identify;
}
function log($key, $value) {
}
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-361050-1-1.html 上篇帖子: php工具类之【String处理类】 下篇帖子: php数组与字符串转换
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表