在这里简要介绍一下搭建视频网站所需要的软件,这些软件包括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) { } }
相关推荐
一个php封装一些常用的工具类,将xml转换为数组,将数组转化成xml,PHP post请求之发送XML数据,PHP post请求之发送Json对象数据,PHP post请求之发送数组,接收xml数据并转化成数组,接收json数据并转化成数组,...
php markdown与html相互转换工具类
介绍一个php封装一些常用的工具类,将xml转换为数组,将数组转化成xml,PHP post请求之发送XML数据,PHP post请求之发送Json对象数据,PHP post请求之发送数组,接收xml数据并转化成数组,接收json数据并转化成数组...
利用flashpaper工具,可以开发类似百度文库,豆丁网 这类文档分享网站。
NULL 博文链接:https://justcoding.iteye.com/blog/593782
此工具类经过代码实测(由于公司需要,我做了一个黄历app,用的就是这个)没有任何误差,可实现公历与农历日期的转换,获取节气,节日,生肖等各种黄历类app需要的时间数据等等
Bo-Blog 2.1.1 To Wordpress 3 搬家转换工具 本工具作者: Haierspi 作者博客:http://blog.diybeta.com 本工具的内容转换细节: 1。转换分类 2。转换TAG标签 3。转换日志 4。转换日志对应的留言 5。自动将...
Bo-Blog 2.1.1 To Wordpress 3 搬家转换工具 本工具作者: Haierspi 作者博客:http://blog.diybeta.com 本工具的内容转换细节: 1。转换分类 2。转换TAG标签 3。转换日志 4。转换日志对应的留言 5。自动...
php 字符编码转换类,支持ANSI、Unicode、Unicode big endian、UTF-8、UTF-8+Bom 互相转换。
[点微]同城分类信息同城分类信息平台点微插件链接转换工具设置教程第一步:复制 source/plugin/tom_link/ 目录下 indexa.php 文件
php类重命名php-class-rename是帮助重写PHP类名称的工具。 它可以用于将代码转换为使用,与PSR-4兼容或更一般地用于重命名类。这个怎么运作php-class-rename在目录中搜索php文件。 它会建立一个类名映射,然后从文件...
Namespacer该工具将帮助您获取较早的下划线/前缀分隔的代码,并将其命名为最佳名称,并使文件和类名与ZF / PEAR兼容。 这两个步骤的命令将首先扫描文件Namespacer。此工具将帮助您获取较早的下划线/前缀分隔的代码,...
NULL 博文链接:https://chembo.iteye.com/blog/905038
sfnt2woff是一个PHP类,用于将OTF / TTF文件转换为WOFF。要求PHP 5.4以上ZLIB扩展用法将字体转换为WOFF: $sfnt2woff = new \xenocrat\sfnt2woff();$sfnt = file_get_contents("font.ttf");$sfnt2woff->...
本文给大家推荐的是一款PHP的中文分词工具类,功能包括支持汉字转拼音、拼音分词、简繁互转。非常不错,有需要的小伙伴可以参考下
)2、UTF-8编码转换工具(UTF-8编码转换。)3、Unicode编码转换工具(Unicode编码转换。)4、友情链接(通过本工具可以批量查询指定网站的友情链接在百度的收录、百度快照、PR以及对方是否链接本站,可以识破骗链接...
包括了:菜单类,按钮类,工具条类,打印类,文件类,文本框类,时间类,EXCEL类,汉字转换类等。。 所有类,均有注释和详细的使用说明。欢迎大家提出宝贵的意见
where_am_i.php:用于查看文件绝对路径的小工具,把它放到指定目录下运行即可看到该目录的绝对路径; functions_login.php:修改后的 vBulletin 登陆函数文件,转换完毕后有详细说明; read_me.txt:...
方法和工具是很多的,主要有两类:第一类,找到字幕缓存文件,使用专用工具转换成st字幕,此类工具很多,有的还能自动搜索剪映草稿,提取字幕。第二类:捕捉识别结果,这类方法无需使用缓存文件,只需在识别文字时,...
本转换程序最后更新时间为:20091228 转换工具包中包含的子体有: pw75 - 70_20uch PHPWind7.5RC -> Discuz!7.0 UCenter Home2.0 pw73 - 70_20uch PHPWind7.3.x -> Discuz!7.0 UCenter Home2.0 pw73 - ...