当前位置:   article > 正文

视频转码(Java)_java video audio encoder

java video audio encoder

通过Java实现视频转码如下两个方案:

1.利用国外一个大佬写的jar包jave,里面集成了ffmpeg,目前源码应该是更新到1.0.2,看了下源码应该发现,这个功能还是非常强大的,如果不需要转码,只需要获取下图片,视频信息,更是方便= = 。

    JAVE(Java Audio Video Encoder),是一个包涵ffmpeg项目库。开发这可以运用它去实现音频(Audio)与视频(Video)文件的转码。例如你要把AVI格式文件转为MPEG文件、WAV格式文件转为MP3格式文件,同时你还能调整文件大小与比例。JAVE兼容和支持很多格式之间的转码……

转码的方法:

  1. public void encode(java.io.File source, java.io.File target, it.sauronsoftware.jave.EncodingAttributes attributes) throws java.lang.IllegalArgumentException, it.sauronsoftware.jave.InputFormatException, it.sauronsoftware.jave.EncoderException {
  2. File source = new File("source.avi");  
  3. File target = new File("target.mp4");  
  4. AudioAttributes audio = new AudioAttributes();  
  5. audio.setCodec("libmp3lame");  
  6. audio.setBitRate(new Integer(56000));  
  7. audio.setChannels(new Integer(1));  
  8. audio.setSamplingRate(new Integer(22050));  
  9. VideoAttributes video = new VideoAttributes();  
  10. video.setCodec("libx264");  
  11. EncodingAttributes attrs = new EncodingAttributes();  
  12. attrs.setFormat("mp4");  //h264编码
  13. attrs.setAudioAttributes(audio);  
  14. attrs.setVideoAttributes(video);  
  15. Encoder encoder = new Encoder();  
  16. encoder.encode(source, target, attrs);  
  17. }

借鉴的这篇博客:https://blog.csdn.net/qllinhongyu/article/details/29817297  里面介绍jave更详细点


2.利用FFmpeg进行转码,有坏处:

 windows服务器还比较简单,直接下载ffmpeg可以直接进行转码了,但是linux服务器的ffmpeg的安装真的挺麻烦的。。我用了3个小时装好。
需要调用java执行外部程序Runtime类或者ProcessBuilder去构建Process,据说调用多了,非常损耗性能。

  1. Runtime runtime = Runtime.getRuntime();
  2. Process p = runtime.exec(cmd);

 

Process p=new ProcessBuilder(cmd).start();


这里有一点需要注意,runtime执行执行命令,processBuilder需要具体的文件

runtime的cmd:  String copy="cp -rf "+source+" "+target;

processBuilder的cmd:  这里读的是配置文件中的

  1. video.ffmpeg.linux.path=/usr/local/ffmpegRedHat/bin/./ffmpeg
  2. video.ffmpeg.windows.path=D:\\project\\solr\\changToH264\\src\\ffmpeg.exe

开头不太一样。。

我目前直接用的ffmpeg,这里粘一下我的源码,可以做一下参考

  1. @Override
  2. public boolean startChangeToH264(String inputPath, String outPath) throws Exception{
  3.     // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
  4.     if (!checkfile(inputPath)) {
  5.         System.out.println(inputPath + " is not file");
  6.         throw new Exception("文件不存在");
  7.     }
  8.     if(checkContentType(inputPath)!=0){
  9.         throw new Exception("文件类型无法解析");
  10.     }
  11.     VideoFormatToH264 videoFormatToH264=new VideoFormatToH264(inputPath,outPath);
  12.     videoFormatToH264.run();
  13.     return true;
  14. }
  15.  
  16.  
  17. private static boolean checkfile(String path) {
  18.     File file = new File(path);
  19.     if (!file.isFile() || (!file.exists())) {
  20.         return false;
  21.     }
  22.     return true;
  23. }
  24.  
  25. private static int checkContentType(String inputPath) {
  26.     String type = inputPath.substring(inputPath.lastIndexOf(".") + 1, inputPath.length())
  27.             .toLowerCase();
  28.     // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
  29.     if (type.equals("avi")) {
  30.         return 0;
  31.     } else if (type.equals("mpg")) {
  32.         return 0;
  33.     } else if (type.equals("wmv")) {
  34.         return 0;
  35.     } else if (type.equals("3gp")) {
  36.         return 0;
  37.     } else if (type.equals("mov")) {
  38.         return 0;
  39.     } else if (type.equals("mp4")) {
  40.         return 0;
  41.     } else if (type.equals("asf")) {
  42.         return 0;
  43.     } else if (type.equals("asx")) {
  44.         return 0;
  45.     } else if (type.equals("flv")) {
  46.         return 0;
  47.     }
  48.     // 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),
  49.     // 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
  50.     else if (type.equals("wmv9")) {
  51.         return 1;
  52.     } else if (type.equals("rm")) {
  53.         return 1;
  54.     } else if (type.equals("rmvb")) {
  55.         return 1;
  56.     }
  57.     return 9;
  58. }
  59. /**
  60.  * Created by zhangluyao on 2018/6/12.
  61.  */
  62. public class VideoFormatToH264 {
  63.     private String filePath;
  64.     private String OutfilePath;
  65.     private List<String> command;
  66.     public VideoFormatToH264(String filePath,String OutfilePath){
  67.         this.OutfilePath=OutfilePath;
  68.         this.filePath=filePath;
  69.     }
  70.     public VideoFormatToH264(String filePath,String OutfilePath, List<String> command){
  71.         this.OutfilePath=OutfilePath;
  72.         this.filePath=filePath;
  73.         this.command=command;
  74.     }
  75.  
  76.     public void run(){
  77.         ThreadPoolTaskExecutor threadPoolTaskExecutor=(ThreadPoolTaskExecutor)SpringUtil.getBean("threadPoolTaskExecutor");
  78.         ChangeVideoTask changeVideoTask=new ChangeVideoTask(this.getFilePath(),this.getOutfilePath());
  79.         threadPoolTaskExecutor.execute(changeVideoTask);
  80.     }
  81.     public void runCommand()throws Exception{
  82.         if(this.command!=null){
  83.             ThreadPoolTaskExecutor threadPoolTaskExecutor=(ThreadPoolTaskExecutor)SpringUtil.getBean("threadPoolTaskExecutor");
  84.             ChangeVideoTask changeVideoTask=new ChangeVideoTask(this.getFilePath(),this.getOutfilePath(),this.command);
  85.             threadPoolTaskExecutor.execute(changeVideoTask);
  86.         }else{
  87.             System.out.print("command为空");
  88.             throw new Exception("command为空");
  89.         }
  90.     }
  91.     private class ChangeVideoTask implements Runnable{
  92.         private String filePath;
  93.         private String outFilePath;
  94.         private List<String> command;
  95.         ChangeVideoTask(String path,String outFilePath){
  96.             this.outFilePath=outFilePath;
  97.             this.filePath=path;
  98.         }
  99.         ChangeVideoTask(String path,String outFilePath,List<String> command){
  100.             this.outFilePath=outFilePath;
  101.             this.filePath=path;
  102.             this.command=command;
  103.         }
  104.         @Override
  105.         public  void run() {
  106.             try {
  107.                 //命令是空时,执行视频转换成H264
  108.                 if(CollectionUtils.isEmpty(command)){
  109.                     command=new ArrayList<String>();
  110.                     command.add(Const.getFFMPEGPath());
  111.                     command.add("-i");
  112.                     command.add(filePath);
  113.                     command.add("-y");
  114.                     command.add("-vcodec");
  115.                     command.add("h264");
  116.                     command.add("-preset");
  117.                     command.add("ultrafast");
  118.                     command.add("-profile:v");
  119.                     command.add("baseline");
  120.                     command.add("-acodec");
  121.                     command.add("aac");
  122.                     command.add("-strict");
  123.                     command.add("experimental");
  124.                     command.add("-s");
  125.                     command.add("640*480");
  126.                     command.add("-b");
  127.                     command.add("568k");
  128.                     command.add("-ab");
  129.                     command.add("128k");
  130.                     if(System.getProperty("os.name").toLowerCase().indexOf("windows")>-1){
  131.                         command.add(outFilePath.substring(1));
  132.                     }else{
  133.                         command.add(outFilePath);
  134.                     }
  135.                 }
  136.  
  137.                 System.out.println("开始转换");
  138.                 Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start();
  139.  
  140.                 new PrintStream(videoProcess.getErrorStream()).start();
  141.  
  142.                 new PrintStream(videoProcess.getInputStream()).start();
  143.  
  144.                 videoProcess.waitFor();//等待进程结束
  145.                 CacheService cacheService=(CacheService) SpringUtil.getBean("cacheService");
  146.                 String sourceName=filePath.substring(filePath.lastIndexOf("/")+1);
  147.                 //转换成功,去掉redis中的key
  148.                 cacheService.remove(sourceName);
  149.                 System.out.println("转换成功");
  150.                 FileUtils.delFile(filePath);
  151.             } catch (Exception e) {
  152.                 e.printStackTrace();
  153.             }
  154.         }
  155.  
  156.     }
  157.  
  158.  
  159.  
  160.     private class PrintStream extends Thread
  161.     {
  162.         java.io.InputStream __is = null;
  163.         public PrintStream(java.io.InputStream is)
  164.         {
  165.             __is = is;
  166.         }
  167.  
  168.         public void run()
  169.         {
  170.             try
  171.             {
  172.                 while(this != null)
  173.                 {
  174.                     int _ch = __is.read();
  175.                     if(_ch != -1)
  176.                         System.out.print((char)_ch);
  177.                     else break;
  178.                 }
  179.             }
  180.             catch (Exception e)
  181.             {
  182.                 e.printStackTrace();
  183.             }
  184.         }
  185.     }
  186.     public String getFilePath() {
  187.         return filePath;
  188.     }
  189.  
  190.     public void setFilePath(String filePath) {
  191.         this.filePath = filePath;
  192.     }
  193.  
  194.     public String getOutfilePath() {
  195.         return OutfilePath;
  196.     }
  197.  
  198.     public void setOutfilePath(String outfilePath) {
  199.         OutfilePath = outfilePath;
  200.     }
  201.  
  202.     public List<String> getCommand() {
  203.         return command;
  204.     }
  205.  
  206.     public void setCommand(List<String> command) {
  207.         this.command = command;
  208.     }


加点东西。 

ffmpeg转换成mp4文件以后,视频的元数据在末尾,jwplayer播放的时候需要全部缓冲结束才能开始播放,用户体验及其的不好~~   更改后的代码先不贴上来了,就说下方法。

ffmpeg文件夹中,编译前的文件夹,tools下面有一个qt-faststart.c

执行下make qt-faststart   会生成一个qt-faststart 命令

然后代码中对文件 再执行一下  qt-faststart  inputPath outPath  命令 就可以了

会生成一个新的文件,这个文件的元数据在开头,可以直接播放的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/759578
推荐阅读
相关标签
  

闽ICP备14008679号