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这个版本:
    1
    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 = "【需要转码的视频路径】";

        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {  
            </span><span style="color: #0000ff;">if</span> (!checkfile(PATH)) {   <span style="color: #008000;">//</span><span style="color: #008000;">判断路径是不是一个文件</span>
                System.out.println(PATH + " is not file"<span style="color: #000000;">);  
                </span><span style="color: #0000ff;">return</span><span style="color: #000000;">;  
            }  
            </span><span style="color: #0000ff;">if</span> (process()) {        <span style="color: #008000;">//</span><span style="color: #008000;">执行转码任务</span>
                System.out.println("ok"<span style="color: #000000;">);  
            }  
        }  
      
        </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> checkfile(String path) {  
            File file </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> File(path);  
            </span><span style="color: #0000ff;">if</span> (!<span style="color: #000000;">file.isFile()) {  
                </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;  
            }  
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;  
        }  
        
        </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> process() { 
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 判断视频的类型</span>
            <span style="color: #0000ff;">int</span> type =<span style="color: #000000;"> checkContentType();  
            </span><span style="color: #0000ff;">boolean</span> status = <span style="color: #0000ff;">false</span><span style="color: #000000;">;  
            </span><span style="color: #008000;">//</span><span style="color: #008000;">如果是ffmpeg可以转换的类型直接转码,否则先用mencoder转码成AVI</span>
            <span style="color: #0000ff;">if</span> (type == 0<span style="color: #000000;">) {  
                System.out.println(</span>"直接将文件转为flv文件"<span style="color: #000000;">);  
                status </span>= processFLV(PATH);<span style="color: #008000;">//</span><span style="color: #008000;"> 直接将文件转为flv文件  </span>
            } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type == 1<span style="color: #000000;">) {  
                String avifilepath </span>=<span style="color: #000000;"> processAVI(type);  
                </span><span style="color: #0000ff;">if</span> (avifilepath == <span style="color: #0000ff;">null</span><span style="color: #000000;">)  
                    </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;<span style="color: #008000;">//</span><span style="color: #008000;"> avi文件没有得到  </span>
                status = processFLV(avifilepath);<span style="color: #008000;">//</span><span style="color: #008000;"> 将avi转为flv  </span>
    

    }
    return status;
    }

        </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> checkContentType() {  
            String type </span>= PATH.substring(PATH.lastIndexOf(".") + 1<span style="color: #000000;">, PATH.length())  
                    .toLowerCase();  
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)  </span>
            <span style="color: #0000ff;">if</span> (type.equals("avi"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("mpg"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("wmv"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("3gp"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("mov"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("mp4"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("asf"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("asx"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("flv"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 0<span style="color: #000000;">;  
            }  
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),  
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.  </span>
            <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("wmv9"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 1<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("rm"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 1<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type.equals("rmvb"<span style="color: #000000;">)) {  
                </span><span style="color: #0000ff;">return</span> 1<span style="color: #000000;">;  
            }  
            </span><span style="color: #0000ff;">return</span> 9<span style="color: #000000;">;  
        }  
           
      
        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.  </span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> String processAVI(<span style="color: #0000ff;">int</span><span style="color: #000000;"> type) {  
            List</span>&lt;String&gt; commend = <span style="color: #0000ff;">new</span> ArrayList&lt;String&gt;<span style="color: #000000;">();  
            commend.add(</span>"D:\ffmpeg\mencoder"<span style="color: #000000;">);  
            commend.add(PATH);  
            commend.add(</span>"-oac"<span style="color: #000000;">);  
            commend.add(</span>"lavc"<span style="color: #000000;">);  
            commend.add(</span>"-lavcopts"<span style="color: #000000;">);  
            commend.add(</span>"acodec=mp3:abitrate=64"<span style="color: #000000;">);  
            commend.add(</span>"-ovc"<span style="color: #000000;">);  
            commend.add(</span>"xvid"<span style="color: #000000;">);  
            commend.add(</span>"-xvidencopts"<span style="color: #000000;">);  
            commend.add(</span>"bitrate=600"<span style="color: #000000;">);  
            commend.add(</span>"-of"<span style="color: #000000;">);  
            commend.add(</span>"avi"<span style="color: #000000;">);  
            commend.add(</span>"-o"<span style="color: #000000;">);  
            commend.add(</span>"【存放转码后视频的路径,记住一定是.avi后缀的文件名】"<span style="color: #000000;">);  
            </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {  
                </span><span style="color: #008000;">//</span><span style="color: #008000;">调用线程命令启动转码</span>
                ProcessBuilder builder = <span style="color: #0000ff;">new</span><span style="color: #000000;"> ProcessBuilder();  
                builder.command(commend);  
                builder.start();  
                </span><span style="color: #0000ff;">return</span> "【存放转码后视频的路径,记住一定是.avi后缀的文件名】"<span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {  
                e.printStackTrace();  
                </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;  
            }  
        }  
      
        </span><span style="color: #008000;">//</span><span style="color: #008000;"> ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)  </span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> processFLV(String oldfilepath) {  
      
            </span><span style="color: #0000ff;">if</span> (!<span style="color: #000000;">checkfile(PATH)) {  
                System.out.println(oldfilepath </span>+ " is not file"<span style="color: #000000;">);  
                </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;  
            }  
              
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 文件命名  </span>
            Calendar c =<span style="color: #000000;"> Calendar.getInstance();  
            String savename </span>= String.valueOf(c.getTimeInMillis())+ Math.round(Math.random() * 100000<span style="color: #000000;">);  
            List</span>&lt;String&gt; commend = <span style="color: #0000ff;">new</span> ArrayList&lt;String&gt;<span style="color: #000000;">();  
            commend.add(</span>"D:\ffmpeg\ffmpeg"<span style="color: #000000;">);  
            commend.add(</span>"-i"<span style="color: #000000;">);  
            commend.add(oldfilepath);  
            commend.add(</span>"-ab"<span style="color: #000000;">);  
            commend.add(</span>"56"<span style="color: #000000;">);  
            commend.add(</span>"-ar"<span style="color: #000000;">);  
            commend.add(</span>"22050"<span style="color: #000000;">);  
            commend.add(</span>"-qscale"<span style="color: #000000;">);  
            commend.add(</span>"8"<span style="color: #000000;">);  
            commend.add(</span>"-r"<span style="color: #000000;">);  
            commend.add(</span>"15"<span style="color: #000000;">);  
            commend.add(</span>"-s"<span style="color: #000000;">);  
            commend.add(</span>"600x500"<span style="color: #000000;">);  
            commend.add(</span>"【存放转码后视频的路径,记住一定是.flv后缀的文件名】"<span style="color: #000000;">);  
      
            </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {  
                Runtime runtime </span>=<span style="color: #000000;"> Runtime.getRuntime();  
                Process proce </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">; 
                </span><span style="color: #008000;">//</span><span style="color: #008000;">视频截图命令,封面图。  8是代表第8秒的时候截图</span>
                String cmd = ""<span style="color: #000000;">;  
                String cut </span>= "     c:\ffmpeg\ffmpeg.exe   -i   "  
                        +<span style="color: #000000;"> oldfilepath  
                        </span>+ "   -y   -f   image2   -ss   8   -t   0.001   -s   600x500   c:\ffmpeg\output\"  
                        + "a.jpg"<span style="color: #000000;">;  
                String cutCmd </span>= cmd +<span style="color: #000000;"> cut;  
                proce </span>=<span style="color: #000000;"> runtime.exec(cutCmd);  
                </span><span style="color: #008000;">//</span><span style="color: #008000;">调用线程命令进行转码</span>
                ProcessBuilder builder = <span style="color: #0000ff;">new</span><span style="color: #000000;"> ProcessBuilder(commend);                 
                 builder.command(commend);  
                builder.start();  
      
                </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;  
            } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {  
                e.printStackTrace();  
                </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;  
            }  
        }  
    

    }

    复制代码
     注: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 持续时长




  • 相关阅读:
    Swift3 重写一个带占位符的textView
    Swift3 使用系统UIAlertView方法做吐司效果
    Swift3 页面顶部实现拉伸效果代码
    Swift3 倒计时按钮扩展
    iOS 获取当前对象所在的VC
    SpringBoot在IDEA下使用JPA
    hibernate 异常a different object with the same identifier value was already associated with the session
    SpringCloud IDEA 教学 番外篇 后台运行Eureka服务注册中心
    SpringCloud IDEA 教学 (五) 断路器控制台(HystrixDashboard)
    SpringCloud IDEA 教学 (四) 断路器(Hystrix)
  • 原文地址:https://www.cnblogs.com/jpfss/p/10880553.html
Copyright © 2011-2022 走看看