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.视频截图

思路:

配置文件中定义各转换工具的路径:(相关工具去官网下载)

  1. <!-- ################配置系统用到的转换工具相关参数   开始....-->
  2. <!-- ##ffmpeg.so文件路径 -->
  3. <param name="ffmpegPath" value="D:\conver\ffmpeg-win.exe" />
  4. <!-- ##memcoder.so文件路径 -->
  5. <param name="mencoderPath" value="D:\conver\mencoder.exe" />
  6. <!-- ##给视频加水印的shell脚本路径 -->
  7. <param name="shellPath" value="D:\conver\coverVideo.bat" />
  8. <!-- ##定义MP4Box工具路径 -->
  9. <param name="mp4BoxPath" value="D:\conver\MP4Box" />
  10. <!-- ##定义图片转换工具路径 -->
  11. <param name="imgConverPath" value="C:/Program Files/ImageMagick-6.3.9-Q16/convert.exe" />
  12. <!-- ################配置系统用到的转换工具相关参数   结束-->

2.获取视频音频的各项属性帮助类

  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.util.List;
  4. import org.apache.commons.lang.StringUtils;
  5. import org.apache.log4j.Logger;
  6. import org.apache.oro.text.regex.MalformedPatternException;
  7. import org.apache.oro.text.regex.MatchResult;
  8. import org.apache.oro.text.regex.Pattern;
  9. import org.apache.oro.text.regex.PatternCompiler;
  10. import org.apache.oro.text.regex.PatternMatcher;
  11. import org.apache.oro.text.regex.Perl5Compiler;
  12. import org.apache.oro.text.regex.Perl5Matcher;
  13. import com.brainsoon.bsrcm.common.utils.BaseCommonUtil;
  14. import com.brainsoon.bsrcm.system.support.CacConver;
  15. /**
  16. * 获取视频音频的各项属性帮助类
  17. * 如果需要修改或者添加属性,只要扩展下面的二维数组和修改下面getVideoInfo()方法
  18. * @author tanghui
  19. *
  20. */
  21. public class VideoInfoHelps {
  22. protected static final Logger logger = Logger.getLogger(VideoInfoHelps.class);
  23. public static final String ffmpegPath; // ffmpeg.exe的目录
  24. static{
  25. ffmpegPath = BaseCommonUtil.getProRealPath("ffmpegPath");
  26. }
  27. /**
  28. * 根据属性获取视频信息
  29. * @param videoPath
  30. * @return
  31. */
  32. public static VideoInfo getVideoInfo(String videoPath) {
  33. VideoInfo videoInfo  = new VideoInfo();
  34. if(CacConver.exitFile(videoPath)){
  35. String videoType = videoPath.substring(videoPath.lastIndexOf(".")+1, videoPath.length());
  36. if(CacConver.isNeedVideoFormat(videoType)){
  37. String result =   processVideo(videoPath);
  38. if(StringUtils.isNotEmpty(result)){
  39. PatternCompiler compiler =new Perl5Compiler();
  40. try {
  41. String regexDuration ="Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
  42. String regexVideo ="Video: (.*?), (.*?), (.*?)[,\\s]";
  43. String regexAudio ="Audio: (\\w*), (\\d*) Hz";
  44. Pattern patternDuration = compiler.compile(regexDuration,Perl5Compiler.CASE_INSENSITIVE_MASK);
  45. PatternMatcher matcherDuration = new Perl5Matcher();
  46. if(matcherDuration.contains(result, patternDuration)){
  47. MatchResult re = matcherDuration.getMatch();
  48. videoInfo.setPlayingAllTime( re.group(1));
  49. videoInfo.setPlayingStartTime( re.group(2));
  50. videoInfo.setBitrateSize( re.group(3));
  51. }
  52. Pattern patternVideo = compiler.compile(regexVideo,Perl5Compiler.CASE_INSENSITIVE_MASK);
  53. PatternMatcher matcherVideo = new Perl5Matcher();
  54. if(matcherVideo.contains(result, patternVideo)){
  55. MatchResult re = matcherVideo.getMatch();
  56. videoInfo.setCodeFormat( re.group(1));
  57. videoInfo.setVideoFormat( re.group(2));
  58. videoInfo.setResolution( re.group(3));
  59. }
  60. Pattern patternAudio = compiler.compile(regexAudio,Perl5Compiler.CASE_INSENSITIVE_MASK);
  61. PatternMatcher matcherAudio = new Perl5Matcher();
  62. if(matcherAudio.contains(result, patternAudio)){
  63. MatchResult re = matcherAudio.getMatch();
  64. videoInfo.setAudioCoding(re.group(1));
  65. videoInfo.setAudioFrequency( re.group(2));
  66. }
  67. } catch (MalformedPatternException e) {
  68. logger.error("获取【" + videoPath +"】视频信息失败!");
  69. }
  70. logger.info("获取【" + videoPath +"】视频信息成功!");
  71. }else{
  72. logger.info("执行成功!但未获取到【" + videoPath +"】视频信息!");
  73. }
  74. }else{
  75. logger.debug("【" + videoPath + "】文件格式不支持!");
  76. }
  77. }
  78. return videoInfo ;
  79. }
  80. /**
  81. *  ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
  82. * @param inputPath
  83. * @return
  84. */
  85. private static String processVideo(String filePath) {
  86. List<String> commend=new java.util.ArrayList<String>();
  87. commend.add(ffmpegPath);//可以设置环境变量从而省去这行
  88. commend.add("-i");
  89. commend.add(filePath);
  90. try {
  91. ProcessBuilder builder = new ProcessBuilder();
  92. builder.command(commend);
  93. builder.redirectErrorStream(true);
  94. Process p= builder.start();
  95. BufferedReader buf = null; // 保存ffmpeg的输出结果流
  96. String line = null;
  97. buf = new BufferedReader(new InputStreamReader(p.getInputStream()));
  98. StringBuffer sb= new StringBuffer();
  99. while ((line = buf.readLine()) != null) {
  100. sb.append(line);
  101. continue;
  102. }
  103. p.waitFor();//这里线程阻塞,将等待外部转换进程运行成功运行结束后,才往下执行
  104. return sb.toString();
  105. } catch (Exception e) {
  106. logger.error("ffmpeg解析视频文件【" + filePath +"】失败!");
  107. return null;
  108. }
  109. }
  110. }

3.其他的工具类

    1. /**
    2. * 等待进程处理
    3. * @param p
    4. * @return
    5. */
    6. @SuppressWarnings("unused")
    7. public static int doWaitFor(Process p) {
    8. InputStream in = null;
    9. InputStream err = null;
    10. int exitValue = -1; // returned to caller when p is finished
    11. try {
    12. in = p.getInputStream();
    13. err = p.getErrorStream();
    14. boolean finished = false; // Set to true when p is finished
    15. while (!finished) {
    16. try {
    17. while (in.available() > 0) {
    18. Character c = new Character((char) in.read());
    19. }
    20. while (err.available() > 0) {
    21. Character c = new Character((char) err.read());
    22. }
    23. exitValue = p.exitValue();
    24. finished = true;
    25. } catch (IllegalThreadStateException e) {
    26. Thread.currentThread();
    27. Thread.sleep(500);
    28. }
    29. }
    30. } catch (Exception e) {
    31. logger.error("doWaitFor();: unexpected exception - "
    32. + e.getMessage());
    33. } finally {
    34. try {
    35. if (in != null) {
    36. in.close();
    37. }
    38. } catch (IOException e) {
    39. logger.error("等待进程处理错误");
    40. }
    41. if (err != null) {
    42. try {
    43. err.close();
    44. } catch (IOException e) {
    45. logger.error("等待进程处理错误");
    46. }
    47. }
    48. }
    49. return exitValue;
    50. }
    51. /**
    52. * 删除文件
    53. * @param filepath
    54. */
    55. public static void deleteFile(String filepath) {
    56. File file = new File(filepath);
    57. if (file.exists()) {
    58. if (file.delete()) {
    59. logger.info("文件【" + filepath + "】已删除");
    60. }
    61. }
    62. }
    63. /**
    64. * 根据时间返回总秒数 形如:(00:12:12)
    65. * @param timeStr
    66. * @return
    67. */
    68. public static String getSplitStr(String timeStr){
    69. String secStr="0";//返回秒
    70. if(timeStr != null && !timeStr.equals("") ){
    71. String[] str = timeStr.split(":");
    72. int subInt0 = Integer.parseInt(str[0]);
    73. int subInt1 = Integer.parseInt(str[1]);
    74. String str2s = "";
    75. if(str[2].length() >2&&str[2].indexOf(".")>0){
    76. str2s = str[2].substring(0,str[2].indexOf("."));
    77. }else{
    78. str2s =  str[2];
    79. }
    80. int subInt2 = Integer.parseInt(str2s);
    81. Long countNum = subInt0 * 3600L + subInt1 * 60 + subInt2;
    82. secStr = countNum + "";
    83. }
    84. return secStr;
    85. }
    86. /**
    87. * 计算两个字符串时间相减 如:("00:22:22")
    88. *
    89. * @param time1
    90. * @param time2
    91. * @return
    92. */
    93. public static String calTime(String time1, String time2){
    94. Long time1Long = Long.parseLong(time1);
    95. Long time2Long = Long.parseLong(time2);
    96. Long timeLong = time2Long-time1Long;
    97. StringBuffer sbuffer = null;
    98. if(timeLong > 0){
    99. int hour = (int) (timeLong/3600);
    100. int minute = (int) ((timeLong-hour*3600)/60);
    101. int second =(int) ((timeLong-hour*3600-minute*60)%60);
    102. sbuffer = new StringBuffer();
    103. if(hour<10){
    104. sbuffer.append("0");
    105. }
    106. sbuffer.append(Integer.toString(hour));
    107. sbuffer.append(":");
    108. if(minute<10){
    109. sbuffer.append("0");
    110. }
    111. sbuffer.append(Integer.toString(minute));
    112. sbuffer.append(":");
    113. if(second<10){
    114. sbuffer.append("0");
    115. }
    116. sbuffer.append(Integer.toString(second));
    117. return sbuffer.toString();
    118. }else{
    119. logger.error("时间不能为负数!可能原因是传入的时间位置不对!");
    120. return "";
    121. }
    122. }

java 实现视频转换通用工具类:获取视频元数据信息(一)的更多相关文章

  1. java 实现视频转换通用工具类:视频截图-Ffmpeg(四)

    java 实现视频转换通用工具类:获取视频元数据信息(一) java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二) java 实现视频转换通用工具类:视频相互转换-Ffmpeg ...

  2. java 实现视频转换通用工具类:视频相互转换-Ffmpeg(三)

    java 实现视频转换通用工具类:获取视频元数据信息(一) java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二) 这节主要是ffmpeg的相关方法封装,在实际调用中主要使用f ...

  3. java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二)

    1.自动判断格式并调用相应的转换工具,默认方法 /** * 自动判断格式并调用相应的转换工具,默认方法 * @param srcVideoPath * @param tarVideoPath * @r ...

  4. Android之使用MediaMetadataRetriever类获取视频第一帧

    一.首先,来介绍一下MediaMetadataRetriever类,此类位于android.media包下,这里,先附上可查看此类的API地址:MediaMetadataRetriever类.大家能够 ...

  5. C#调用mmpeg进行各种视频转换的类实例

    本文实例讲述了C#调用mmpeg进行各种视频转换的类.分享给大家供大家参考.具体如下: 这个C#类封装了视频转换所需的各种方法,基本上是围绕着如何通过mmpeg工具来进行视频转换 using Syst ...

  6. 在java poi导入Excel通用工具类示例详解

    转: 在java poi导入Excel通用工具类示例详解 更新时间:2017年09月10日 14:21:36   作者:daochuwenziyao   我要评论   这篇文章主要给大家介绍了关于在j ...

  7. java 二进制数字符串转换工具类

    java 二进制数字符串转换工具类 将二进制转换成八进制 将二进制转换成十进制 将二进制转换成十六进制 将十进制转换成二进制 package com.iteye.injavawetrust.ad; i ...

  8. C# 利用ffmpeg 对视频转换系类操作 (1) 基本分析

    最近公司做一个项目,开发一个视频站点.项目需求中有很多视频转换的需求,如:格式转换(flv,Mp4),视频水印,视频截图,视频合成,获取视频的基本信息(时间戳,视频大小等).经过网络的收集资料以及自己 ...

  9. 我的Android进阶之旅------>使用ThumbnailUtils类获取视频的缩略图

    今天看了一段代码,是关于获取视频的缩略图的,让我认识了一个ThumbnailUtils类,代码如下. Bitmap bitmap = ThumbnailUtils.createVideoThumbna ...

随机推荐

  1. Cloud Test 单页面即时监测功能上线!

    什么是即时监测? 即时监测,顾名思义是指输入 URL 后能够立即进行监测并展示结果,无需注册. 如下图,在输入框内输入需要监测的 URL,点击免费监测,即可展示网页监测结果: 图中我们可以看到页面各个 ...

  2. php获得当前日期时间 date函数

    time()得到从1970-01-01到现在共走了多少秒 要找出前一天的时间就是 time()-60*60*24; 要找出前一年的时间就是 time()*60*60*24*365 那么如何把这个数字换 ...

  3. [状压dp]POJ2686 Traveling by Stagecoach

    题意: m个城市, n张车票, 每张车票$t_i$匹马, 每张车票可以沿某条道路到相邻城市, 花费是路的长度除以马的数量. 求a到b的最小花费, 不能到达输出Impossible $1\le n\le ...

  4. UVA 10608 Friends

    题目大意:共有n个人,m对人为已知的朋友关系,而且这种关系具有传递性,也就是A与B,B与C是朋友,可以确定A与C是朋友,求一个人数最多的朋友团体. bfs就可以了,遇到未访问的结点,加入队列并且朋人数 ...

  5. 到底DAO是什么?为什么要有它的存在?

    Data Access Object   数据访问接口,就是访问数据库方法的 interface 1. DAO用来封装Data Source的..就比如,Connection conn = DAOFa ...

  6. php 中奖概率算法

    我们先完成后台PHP的流程,PHP的主要工作是负责配置奖项及对应的中奖概率,当前端页面点击翻动某个方块时会想后台PHP发送ajax请求,那么后台PHP根据配置的概率,通过概率算法给出中奖结果,同时将未 ...

  7. RxJava开发精要3-向响应式世界问好

    原文出自<RxJava Essentials> 原文作者 : Ivan Morgillo 译文出自 : 开发技术前线 www.devtf.cn 转载声明: 本译文已授权开发者头条享有独家转 ...

  8. Navicat 导入导出

    当我们对mysql数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出.导入操作了.Navicat工具正好给我们提供了一个数据表的导入导出功能. 1 ...

  9. Co-variant array conversion from x to y may cause run-time exception

    http://stackoverflow.com/questions/8704332/co-variant-array-conversion-from-x-to-y-may-cause-run-tim ...

  10. 升级yosemite后java出错的解决

    昨天升级mac os到yosemite后,因为是系统整体升级,有一些在设置会丢失,这是后话,先说说我在执行一个需要java参与的程序的时候得到如下错误: Error: JAVA_HOME is not ...