zoukankan      html  css  js  c++  java
  • java-FFmpeg(一) 实现视频的转码和截图功能

     

      FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行。

      在java开发中,FFmpeg也常被调用用来进行视频的转码,录播和直播,总的来说,FFmpeg是一款非常强大的,而且做与视频相关的业务平台开发人员必须要学会的工具,那具体怎么实习呢,第一章我们先从分别windows和linux下调用FFmpeg进行视频的转码,和对视频的截图做出说明解释。

          ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等),而对于ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),我们在下面采用了mencoder工具,先将视频转换成AVI格式再用ffmpeg进行转码;

          windows下:

            1.首先需要FFmpeg和mencoder的工具。一共五个文件,点此下载,将他解压放在你的D盘FFmpeg文件夹下。

        

      linux下:

    依次执行下面的指令

    1.下载yasm-1.3.0.tar.gz这个版本:
    yasm是一个完全重写的NASM汇编。目前,它支持x86和AMD64指令集,接受NASM和气体汇编语法,产出二进制, ELF32 , ELF64 , COFF , Mach - O的( 32和64 ) , RDOFF2 ,的Win32和Win64对象的格式,并生成STABS 调试信息的来源,DWARF 2 ,CodeView 8格式。之所以在FFmpeg中用这个,主要是支持编译ffmpeg-x264.
    wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
    tar xzvf yasm-1.3.0.tar.gz
    cd yasm-1.3.0
    ./configure
    make
    make install

    2.下载3.1.3 release ffmpeg
    wget http://ffmpeg.org/releases/ffmpeg-3.1.3.tar.gz
    tar -zxvf ffmpeg-3.1.3.tar.gz
    cd ffmpeg-3.1.3
    ./configure
    make
    make install
    第二步的时间可能会有点长,耐心等待~!安装完成之后输入  ffmpeg -version 可以看到版本说明安装成功
    下面直接上代码,都写好注释的,很清楚。
    package wordtopdf;
    
    import java.io.File;  
    import java.util.ArrayList;  
    import java.util.Calendar;  
    import java.util.List;  
      
    
    public class ConvertVideo {
         private final static String PATH = "【需要转码的视频路径】";  
          
            public static void main(String[] args) {  
                if (!checkfile(PATH)) {   //判断路径是不是一个文件
                    System.out.println(PATH + " is not file");  
                    return;  
                }  
                if (process()) {        //执行转码任务
                    System.out.println("ok");  
                }  
            }  
          
            private static boolean checkfile(String path) {  
                File file = new File(path);  
                if (!file.isFile()) {  
                    return false;  
                }  
                return true;  
            }  
            
            private static boolean process() { 
                // 判断视频的类型
                int type = checkContentType();  
                boolean status = false;  
                //如果是ffmpeg可以转换的类型直接转码,否则先用mencoder转码成AVI
                if (type == 0) {  
                    System.out.println("直接将文件转为flv文件");  
                    status = processFLV(PATH);// 直接将文件转为flv文件  
                } else if (type == 1) {  
                    String avifilepath = processAVI(type);  
                    if (avifilepath == null)  
                        return false;// avi文件没有得到  
                    status = processFLV(avifilepath);// 将avi转为flv  
                }  
                return status;  
            }  
          
            private static int checkContentType() {  
                String type = PATH.substring(PATH.lastIndexOf(".") + 1, PATH.length())  
                        .toLowerCase();  
                // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)  
                if (type.equals("avi")) {  
                    return 0;  
                } else if (type.equals("mpg")) {  
                    return 0;  
                } else if (type.equals("wmv")) {  
                    return 0;  
                } else if (type.equals("3gp")) {  
                    return 0;  
                } else if (type.equals("mov")) {  
                    return 0;  
                } else if (type.equals("mp4")) {  
                    return 0;  
                } else if (type.equals("asf")) {  
                    return 0;  
                } else if (type.equals("asx")) {  
                    return 0;  
                } else if (type.equals("flv")) {  
                    return 0;  
                }  
                // 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),  
                // 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.  
                else if (type.equals("wmv9")) {  
                    return 1;  
                } else if (type.equals("rm")) {  
                    return 1;  
                } else if (type.equals("rmvb")) {  
                    return 1;  
                }  
                return 9;  
            }  
               
          
            // 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.  
            private static String processAVI(int type) {  
                List<String> commend = new ArrayList<String>();  
                commend.add("D:\ffmpeg\mencoder");  
                commend.add(PATH);  
                commend.add("-oac");  
                commend.add("lavc");  
                commend.add("-lavcopts");  
                commend.add("acodec=mp3:abitrate=64");  
                commend.add("-ovc");  
                commend.add("xvid");  
                commend.add("-xvidencopts");  
                commend.add("bitrate=600");  
                commend.add("-of");  
                commend.add("avi");  
                commend.add("-o");  
                commend.add("【存放转码后视频的路径,记住一定是.avi后缀的文件名】");  
                try {  
                    //调用线程命令启动转码
                    ProcessBuilder builder = new ProcessBuilder();  
                    builder.command(commend);  
                    builder.start();  
                    return "【存放转码后视频的路径,记住一定是.avi后缀的文件名】";  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    return null;  
                }  
            }  
          
            // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)  
            private static boolean processFLV(String oldfilepath) {  
          
                if (!checkfile(PATH)) {  
                    System.out.println(oldfilepath + " is not file");  
                    return false;  
                }  
                  
                // 文件命名  
                Calendar c = Calendar.getInstance();  
                String savename = String.valueOf(c.getTimeInMillis())+ Math.round(Math.random() * 100000);  
                List<String> commend = new ArrayList<String>();  
                commend.add("D:\ffmpeg\ffmpeg");  
                commend.add("-i");  
                commend.add(oldfilepath);  
                commend.add("-ab");  
                commend.add("56");  
                commend.add("-ar");  
                commend.add("22050");  
                commend.add("-qscale");  
                commend.add("8");  
                commend.add("-r");  
                commend.add("15");  
                commend.add("-s");  
                commend.add("600x500");  
                commend.add("【存放转码后视频的路径,记住一定是.flv后缀的文件名】");  
          
                try {  
                    Runtime runtime = Runtime.getRuntime();  
                    Process proce = null; 
                    //视频截图命令,封面图。  8是代表第8秒的时候截图
                    String cmd = "";  
                    String cut = "     c:\ffmpeg\ffmpeg.exe   -i   "  
                            + oldfilepath  
                            + "   -y   -f   image2   -ss   8   -t   0.001   -s   600x500   c:\ffmpeg\output\"  
                            + "a.jpg";  
                    String cutCmd = cmd + cut;  
                    proce = runtime.exec(cutCmd);  
                    //调用线程命令进行转码
                    ProcessBuilder builder = new ProcessBuilder(commend);                 
                     builder.command(commend);  
                    builder.start();  
          
                    return true;  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    return false;  
                }  
            }  
    }
     注:ffmpeg的功能十分强大,但是命令也非常多,转换每种格式的命令都不相同!需要转换其他格式的,请写对命令。

           命令格式:

        普通转码:
        ffmpeg -i [输入文件名] [参数选项] -f [格式] [输出文件]
        比如:MP4转avi c:ffmpegffmpeg -i c:ffmpeginputc.mp4 -f avi c:ffmpegoutputa.avi

        参数:-an 去掉音频
        -b 1000K 压缩码率为1000K
        -s 800*500 压缩尺寸为800*500
        -aspect 宽高比,格式 16:9 或 1.778
        (当源尺寸是16:9,要压缩成非16:9的,一方面要设定 -s,另一方面要给出 -aspect)
        -ss 开始时间​
        -t 持续时长




  • 相关阅读:
    面向对象的三个基本特征
    OGRE启动过程详解(OGRE HelloWorld程序原理解析)
    Bullet核心类介绍(Bullet 2.82 HelloWorld程序及其详解,附程序代码)
    windows下Bullet 2.82编译安装(Bullet Physics开发环境配置)
    1303: Decimal
    分组背包,每组最多选1个
    椒盐效果
    自我介绍
    题目1539:师弟
    upper_bound()
  • 原文地址:https://www.cnblogs.com/tohxyblog/p/6640786.html
Copyright © 2011-2022 走看看