java 实现视频转换通用工具类:获取视频元数据信息(一)
java 做视频转换主要用到开源的ffmpeg或者mencoder,还要有MP4Box。
注:由于平时都没有时间写博客,所以思路我就不写了,有问题问我,不一定马上回复。
详细介绍:
ffmpeg:http://www.ffmpeg.org/
mencoder:http://en.wikipedia.org/wiki/MEncoder
MP4Box:http://gpac.wp.mines-telecom.fr/mp4box/mp4box-documentation/
主要实现:
1.获取视频元数据信息
2.视频相互转换
3.视频加文字及图片水印
4.视频截图
思路:
配置文件中定义各转换工具的路径:(相关工具去官网下载)
- <!-- ################配置系统用到的转换工具相关参数 开始....-->
- <!-- ##ffmpeg.so文件路径 -->
- <param name="ffmpegPath" value="D:\conver\ffmpeg-win.exe" />
- <!-- ##memcoder.so文件路径 -->
- <param name="mencoderPath" value="D:\conver\mencoder.exe" />
- <!-- ##给视频加水印的shell脚本路径 -->
- <param name="shellPath" value="D:\conver\coverVideo.bat" />
- <!-- ##定义MP4Box工具路径 -->
- <param name="mp4BoxPath" value="D:\conver\MP4Box" />
- <!-- ##定义图片转换工具路径 -->
- <param name="imgConverPath" value="C:/Program Files/ImageMagick-6.3.9-Q16/convert.exe" />
- <!-- ################配置系统用到的转换工具相关参数 结束-->
2.获取视频音频的各项属性帮助类
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.util.List;
- import org.apache.commons.lang.StringUtils;
- import org.apache.log4j.Logger;
- import org.apache.oro.text.regex.MalformedPatternException;
- import org.apache.oro.text.regex.MatchResult;
- import org.apache.oro.text.regex.Pattern;
- import org.apache.oro.text.regex.PatternCompiler;
- import org.apache.oro.text.regex.PatternMatcher;
- import org.apache.oro.text.regex.Perl5Compiler;
- import org.apache.oro.text.regex.Perl5Matcher;
- import com.brainsoon.bsrcm.common.utils.BaseCommonUtil;
- import com.brainsoon.bsrcm.system.support.CacConver;
- /**
- * 获取视频音频的各项属性帮助类
- * 如果需要修改或者添加属性,只要扩展下面的二维数组和修改下面getVideoInfo()方法
- * @author tanghui
- *
- */
- public class VideoInfoHelps {
- protected static final Logger logger = Logger.getLogger(VideoInfoHelps.class);
- public static final String ffmpegPath; // ffmpeg.exe的目录
- static{
- ffmpegPath = BaseCommonUtil.getProRealPath("ffmpegPath");
- }
- /**
- * 根据属性获取视频信息
- * @param videoPath
- * @return
- */
- public static VideoInfo getVideoInfo(String videoPath) {
- VideoInfo videoInfo = new VideoInfo();
- if(CacConver.exitFile(videoPath)){
- String videoType = videoPath.substring(videoPath.lastIndexOf(".")+1, videoPath.length());
- if(CacConver.isNeedVideoFormat(videoType)){
- String result = processVideo(videoPath);
- if(StringUtils.isNotEmpty(result)){
- PatternCompiler compiler =new Perl5Compiler();
- try {
- String regexDuration ="Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
- String regexVideo ="Video: (.*?), (.*?), (.*?)[,\\s]";
- String regexAudio ="Audio: (\\w*), (\\d*) Hz";
- Pattern patternDuration = compiler.compile(regexDuration,Perl5Compiler.CASE_INSENSITIVE_MASK);
- PatternMatcher matcherDuration = new Perl5Matcher();
- if(matcherDuration.contains(result, patternDuration)){
- MatchResult re = matcherDuration.getMatch();
- videoInfo.setPlayingAllTime( re.group(1));
- videoInfo.setPlayingStartTime( re.group(2));
- videoInfo.setBitrateSize( re.group(3));
- }
- Pattern patternVideo = compiler.compile(regexVideo,Perl5Compiler.CASE_INSENSITIVE_MASK);
- PatternMatcher matcherVideo = new Perl5Matcher();
- if(matcherVideo.contains(result, patternVideo)){
- MatchResult re = matcherVideo.getMatch();
- videoInfo.setCodeFormat( re.group(1));
- videoInfo.setVideoFormat( re.group(2));
- videoInfo.setResolution( re.group(3));
- }
- Pattern patternAudio = compiler.compile(regexAudio,Perl5Compiler.CASE_INSENSITIVE_MASK);
- PatternMatcher matcherAudio = new Perl5Matcher();
- if(matcherAudio.contains(result, patternAudio)){
- MatchResult re = matcherAudio.getMatch();
- videoInfo.setAudioCoding(re.group(1));
- videoInfo.setAudioFrequency( re.group(2));
- }
- } catch (MalformedPatternException e) {
- logger.error("获取【" + videoPath +"】视频信息失败!");
- }
- logger.info("获取【" + videoPath +"】视频信息成功!");
- }else{
- logger.info("执行成功!但未获取到【" + videoPath +"】视频信息!");
- }
- }else{
- logger.debug("【" + videoPath + "】文件格式不支持!");
- }
- }
- return videoInfo ;
- }
- /**
- * ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
- * @param inputPath
- * @return
- */
- private static String processVideo(String filePath) {
- List<String> commend=new java.util.ArrayList<String>();
- commend.add(ffmpegPath);//可以设置环境变量从而省去这行
- commend.add("-i");
- commend.add(filePath);
- try {
- ProcessBuilder builder = new ProcessBuilder();
- builder.command(commend);
- builder.redirectErrorStream(true);
- Process p= builder.start();
- BufferedReader buf = null; // 保存ffmpeg的输出结果流
- String line = null;
- buf = new BufferedReader(new InputStreamReader(p.getInputStream()));
- StringBuffer sb= new StringBuffer();
- while ((line = buf.readLine()) != null) {
- sb.append(line);
- continue;
- }
- p.waitFor();//这里线程阻塞,将等待外部转换进程运行成功运行结束后,才往下执行
- return sb.toString();
- } catch (Exception e) {
- logger.error("ffmpeg解析视频文件【" + filePath +"】失败!");
- return null;
- }
- }
- }
3.其他的工具类
- /**
- * 等待进程处理
- * @param p
- * @return
- */
- @SuppressWarnings("unused")
- public static int doWaitFor(Process p) {
- InputStream in = null;
- InputStream err = null;
- int exitValue = -1; // returned to caller when p is finished
- try {
- in = p.getInputStream();
- err = p.getErrorStream();
- boolean finished = false; // Set to true when p is finished
- while (!finished) {
- try {
- while (in.available() > 0) {
- Character c = new Character((char) in.read());
- }
- while (err.available() > 0) {
- Character c = new Character((char) err.read());
- }
- exitValue = p.exitValue();
- finished = true;
- } catch (IllegalThreadStateException e) {
- Thread.currentThread();
- Thread.sleep(500);
- }
- }
- } catch (Exception e) {
- logger.error("doWaitFor();: unexpected exception - "
- + e.getMessage());
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException e) {
- logger.error("等待进程处理错误");
- }
- if (err != null) {
- try {
- err.close();
- } catch (IOException e) {
- logger.error("等待进程处理错误");
- }
- }
- }
- return exitValue;
- }
- /**
- * 删除文件
- * @param filepath
- */
- public static void deleteFile(String filepath) {
- File file = new File(filepath);
- if (file.exists()) {
- if (file.delete()) {
- logger.info("文件【" + filepath + "】已删除");
- }
- }
- }
- /**
- * 根据时间返回总秒数 形如:(00:12:12)
- * @param timeStr
- * @return
- */
- public static String getSplitStr(String timeStr){
- String secStr="0";//返回秒
- if(timeStr != null && !timeStr.equals("") ){
- String[] str = timeStr.split(":");
- int subInt0 = Integer.parseInt(str[0]);
- int subInt1 = Integer.parseInt(str[1]);
- String str2s = "";
- if(str[2].length() >2&&str[2].indexOf(".")>0){
- str2s = str[2].substring(0,str[2].indexOf("."));
- }else{
- str2s = str[2];
- }
- int subInt2 = Integer.parseInt(str2s);
- Long countNum = subInt0 * 3600L + subInt1 * 60 + subInt2;
- secStr = countNum + "";
- }
- return secStr;
- }
- /**
- * 计算两个字符串时间相减 如:("00:22:22")
- *
- * @param time1
- * @param time2
- * @return
- */
- public static String calTime(String time1, String time2){
- Long time1Long = Long.parseLong(time1);
- Long time2Long = Long.parseLong(time2);
- Long timeLong = time2Long-time1Long;
- StringBuffer sbuffer = null;
- if(timeLong > 0){
- int hour = (int) (timeLong/3600);
- int minute = (int) ((timeLong-hour*3600)/60);
- int second =(int) ((timeLong-hour*3600-minute*60)%60);
- sbuffer = new StringBuffer();
- if(hour<10){
- sbuffer.append("0");
- }
- sbuffer.append(Integer.toString(hour));
- sbuffer.append(":");
- if(minute<10){
- sbuffer.append("0");
- }
- sbuffer.append(Integer.toString(minute));
- sbuffer.append(":");
- if(second<10){
- sbuffer.append("0");
- }
- sbuffer.append(Integer.toString(second));
- return sbuffer.toString();
- }else{
- logger.error("时间不能为负数!可能原因是传入的时间位置不对!");
- return "";
- }
- }
java 实现视频转换通用工具类:获取视频元数据信息(一)的更多相关文章
- java 实现视频转换通用工具类:视频截图-Ffmpeg(四)
java 实现视频转换通用工具类:获取视频元数据信息(一) java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二) java 实现视频转换通用工具类:视频相互转换-Ffmpeg ...
- java 实现视频转换通用工具类:视频相互转换-Ffmpeg(三)
java 实现视频转换通用工具类:获取视频元数据信息(一) java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二) 这节主要是ffmpeg的相关方法封装,在实际调用中主要使用f ...
- java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二)
1.自动判断格式并调用相应的转换工具,默认方法 /** * 自动判断格式并调用相应的转换工具,默认方法 * @param srcVideoPath * @param tarVideoPath * @r ...
- Android之使用MediaMetadataRetriever类获取视频第一帧
一.首先,来介绍一下MediaMetadataRetriever类,此类位于android.media包下,这里,先附上可查看此类的API地址:MediaMetadataRetriever类.大家能够 ...
- C#调用mmpeg进行各种视频转换的类实例
本文实例讲述了C#调用mmpeg进行各种视频转换的类.分享给大家供大家参考.具体如下: 这个C#类封装了视频转换所需的各种方法,基本上是围绕着如何通过mmpeg工具来进行视频转换 using Syst ...
- 在java poi导入Excel通用工具类示例详解
转: 在java poi导入Excel通用工具类示例详解 更新时间:2017年09月10日 14:21:36 作者:daochuwenziyao 我要评论 这篇文章主要给大家介绍了关于在j ...
- java 二进制数字符串转换工具类
java 二进制数字符串转换工具类 将二进制转换成八进制 将二进制转换成十进制 将二进制转换成十六进制 将十进制转换成二进制 package com.iteye.injavawetrust.ad; i ...
- C# 利用ffmpeg 对视频转换系类操作 (1) 基本分析
最近公司做一个项目,开发一个视频站点.项目需求中有很多视频转换的需求,如:格式转换(flv,Mp4),视频水印,视频截图,视频合成,获取视频的基本信息(时间戳,视频大小等).经过网络的收集资料以及自己 ...
- 我的Android进阶之旅------>使用ThumbnailUtils类获取视频的缩略图
今天看了一段代码,是关于获取视频的缩略图的,让我认识了一个ThumbnailUtils类,代码如下. Bitmap bitmap = ThumbnailUtils.createVideoThumbna ...
随机推荐
- Windows 2008 故障转移群集介绍
转载:http://dufei.blog.51cto.com/382644/902026 今天有客户问起Windows 群集的相关内容,毕竟Windows Server2008所支持的群集技术和Win ...
- 关于CPU亲和性的测试
今天看到运维的同事在配置nginx的CPU亲和性时候,运维同事说他在所有的机器上都是按照8核的方式来配置worker进程的CPU亲和性的. 但我觉得就是有点不太对劲,就查了一下nginx的处理work ...
- iOS,Android网络抓包教程之tcpdump
现在的移动端应用几乎都会通过网络请求来和服务器交互,通过抓包来诊断和网络相关的bug是程序员的重要技能之一.抓包的手段有很多:针对http和https可以使用Charles设置代理来做,对于更广泛的协 ...
- dojo 图表制作教程
http://www.sitepen.com/labs/code/charting/tutorial/tutorial1.html http://www.sitepen.com/labs/code/c ...
- .Net remoting, Webservice,WCF,Socket区别
传统上,我们把计算机后台程序(Daemon)提供的功能,称为"服务"(service).比如,让一个杀毒软件在后台运行,它会自动监控系统,那么这种自动监控就是一个"服务& ...
- 【HDOJ】1009 FatMouse' Trade
这道题目是一道非常简单的贪心,但是我却修改了1h+.原因就是qsort的comp有bug.其实还是题目中的数据可以为0.除数为0真的要慎重啊.后来改为结构体,加一层循环选取最大值,果然ac啊.wa了几 ...
- BZOJ_1010_[HNOI2008]_玩具装箱toy_(斜率优化动态规划+单调队列)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 给出\(n\)和\(l\).有\(n\)个玩具,第\(i\)个玩具的长度是\(c[i]\ ...
- DedeCMS 5.7 config.php 跨站脚本漏洞
漏洞版本: DedeCMS 5.7 漏洞描述: DeDeCMS v5.7 在/include/dialog/config.php文件中存在XSS漏洞,攻击者可以利用该漏洞盗取用户Cookie.挂马等. ...
- find和findstr
find与findstr 例“ 在文件中搜索字符串. 1.findstr . 2.txt 或 Findstr "." 2.txt 从文件2.txt中查找任意字符,不包括空字符或空行 ...
- cmd find命令
find 作用:从文件中收索字符串 格式:find 参数 "字符串" 路径\文件名 参数: /V 显示所有未包含指定字符串的行. /C 仅显示包含字符串的行数. /N 显示行号. ...