`
student_lp
  • 浏览: 437983 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

 

    在这里简要介绍一下搭建视频网站所需要的软件,这些软件包括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) {
	}
}

 

分享到:
评论

相关推荐

    微信公众号支付签名生成工具类和xml转换工具类和双向验证请求工具类

    微信公众号支付签名生成工具类和xml和map转换工具类和双向验证请求工具类

    php 使用ffmpeg 视频转换,截图,生成缩略图

    总结来说,这个PHP类提供了便捷的接口,让我们能够利用FFmpeg的强大功能,无需深入理解底层的视频处理技术,就可以在PHP项目中轻松实现视频转换、截图和生成缩略图。对于需要处理多媒体内容的Web应用程序,这无疑是...

    php封装一些常用的工具类

    一个php封装一些常用的工具类,将xml转换为数组,将数组转化成xml,PHP post请求之发送XML数据,PHP post请求之发送Json对象数据,PHP post请求之发送数组,接收xml数据并转化成数组,接收json数据并转化成数组,...

    php 编码相互转换类(gbk转换utf8)

    在IT行业中,编码转换是一个常见的需求,特别是在处理中文字符时。GBK和UTF-8是两种广泛使用的字符...总的来说,这个编码转换类对于处理中文字符集的PHP项目来说是一个有价值的工具,能够提高代码的健壮性和兼容性。

    PHP转换工具

    这类工具通常包含多种功能,如语法转换、代码格式化、编码转换等,以提高开发效率并确保代码在不同平台上的兼容性。 在PHP开发过程中,我们可能会遇到以下场景,需要使用PHP转换工具: 1. **版本升级**:当PHP从旧...

    php markdown与html相互转换工具类

    在 PHP 开发中,有时我们需要将 Markdown 格式转换为 HTML,或者反过来,这通常通过专门的工具类来实现。`parsedown-master` 这个压缩包很可能包含了一个名为 Parsedown 的 PHP 类库,用于处理 Markdown 与 HTML ...

    XV格式视频转换器

    XV格式视频转换器是一款专为处理迅雷特有的XV视频格式而设计的软件工具。在深入了解这个转换器之前,我们首先需要理解XV格式和FLV格式的本质。 XV格式是迅雷公司为了优化其下载服务而推出的一种私有视频格式。这种...

    php常用工具类

    工具类可以包含如`sanitizeHtml()`方法,它使用PHP的`htmlspecialchars()`函数将用户输入转换为安全的HTML实体,防止恶意脚本注入。 5. **数据库输入过滤** 数据库安全至关重要,避免SQL注入是必要的。PHP的PDO...

    php编写的中文繁简转换类

    `iconv`函数是PHP中的一个多字符集转换工具,可以用来进行繁简转换。例如: ```php $text = iconv('Big5', 'UTF-8//TRANSLIT', $traditionalText); ``` 这里,`'Big5'`代表繁体字编码,`'UTF-8'`是目标编码,`//...

    php调用ffmpeg.exe用于视频格式转换的类

    首先,`class.movie2flv.php`文件很可能包含了定义一个PHP类,这个类专门用于调用FFmpeg进行视频格式转换,例如将其他格式的视频转换为FLV格式。此类通常会封装FFmpeg的命令行参数,使得在PHP代码中调用更加便捷。 ...

    php video toolkit php视频转换代码

    总之,PHP Video Toolkit是一个强大的工具,可以帮助开发者轻松地处理和转换视频,提高网站或应用程序的功能性和用户体验。通过深入理解和实践,你可以掌握视频处理的技能,为你的项目带来更多的可能性。

    微信支付相关工具类

    本压缩包包含了一系列与微信支付相关的PHP工具类,这些工具类是开发者实现微信支付功能的重要支持,能帮助开发者高效地集成微信支付功能,并进行XML数据的处理。 1. **WxPay.Data.php**: 这个文件包含了处理数据...

    php的其他工具类.zip

    工具类可能包含一个函数,可以将PHP变量转换为JSON格式,并在浏览器控制台中输出,方便开发者快速检查和验证数据。 5. **类库的可扩展性**: 良好的工具类设计应考虑扩展性和复用性。这个“php的其他工具类”可能...

    (张高伟)非常好用emoji工具类推荐.zip

    "(张高伟)非常好用emoji工具类推荐.zip"这个压缩包文件提供了一个非常实用的工具,它包含了emoji表情的HTML代码和PHP处理代码,帮助开发者更方便地在项目中集成和管理emoji。 首先,我们来了解一下emoji。Emoji是...

    PHP常用工具类方法(珍藏版收集)

    以上只是PHP工具类方法的一小部分,实际的工具类可能包括更多的功能,如数据库操作、加密解密、HTTP请求、缓存处理等。在实际开发中,根据项目需求,可以创建自己的工具类库,方便快速调用和复用代码,提高开发效率...

    Discuz 提供的编码转换工具

    【标题】"Discuz 提供的编码转换工具"涉及到的是网站论坛系统Discuz!中的一种常见操作,即字符编码的转换。在互联网发展的初期,不同的字符编码标准(如GBK和UTF-8)导致了跨平台、跨语言交流时的数据不兼容问题。...

    php大批量文件编码转换 v1.0

    【PHP大批量文件编码转换 v1.0】是一款基于PHP编写的实用工具,主要用于处理大量文件的编码转换问题。在日常开发中,我们经常会遇到不同编码格式的文件,这可能会导致在读取或处理这些文件时出现乱码。此工具通过...

    PHP中文转换拼音的类

    在IT行业中,PHP是一种广泛应用的服务器端脚本语言...通过理解类的工作原理,结合具体的使用场景,我们可以有效地利用这类工具,提高项目的功能性和效率。记得在使用过程中,遵循最佳实践,确保代码的可维护性和性能。

    验证码工具类

    验证码工具类在IT行业中是常见的安全机制之一,主要用于防止自动化的机器人或恶意脚本进行非法操作,例如批量注册、频繁登录等。在 Laravel 框架中,我们可以自定义一个验证码服务来方便地集成到项目中。下面将详细...

    一个PHP 视频上传网站后台

    "class.movie2flv.php"应该是定义了一个处理视频转换和截图的类,它封装了上述操作,使得在PHP代码中调用更加简洁。类的构造函数可能接收视频文件路径,而方法如`convert()`和`captureScreenshot()`分别对应视频...

Global site tag (gtag.js) - Google Analytics