Java视频转码

参考:

http://outofmemory.cn/code-snippet/4079/java-usage-Xuggler-get-video-shichang-fen-bianlv-high-kuan-kind-information
http://blog.csdn.net/kissdeath/article/details/6062277
http://www.oschina.net/code/snippet_220255_7784

主函数,开启线程转码:

package com.main;
public class Conver {
        public static void main (String args[]) {
            //开启新线程转码视频(参数是要转码的文件)
            threadPool pool = new threadPool("D:\\video\\old\\test.avi");
//          threadPool pool2 = new threadPool();
            pool.start();
//          pool2.start();
        }
}

线程方法:

package com.main;
public class threadPool extends Thread{
     private String PATH;
     public threadPool( String PATH)
        {
            this.PATH = PATH;
        }
    @Override 
      public void run() { 
            ConverVideo cv = new ConverVideo();
            cv.process(PATH);
      }
}

转码函数:

package com.main;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class ConverVideo {

        private String flvfolder = "D:\\video\\old\\"; // 视频的目录
        private String ffmpegpath = "D:\\video\\FFmpeg\\bin\\ffmpeg.exe"; // ffmpeg.exe的目录,转码需要的文件
        public boolean process(String PATH) {
            //调用VedioInfoUtil方法得到视频信息
            VedioInfoUtil viu = new VedioInfoUtil();
            int width = viu.getwidth(PATH);
            int hight = viu.gethight(PATH);
            File fi = new File(PATH);
            String filename = fi.getName();
            //获得文件名
            filename = filename.substring(0, filename.lastIndexOf("."))
                    .toLowerCase();
            boolean status = true;
            //根据视频的分辨率向下转码
            if(width==1280){
                boolean statu1 = FWVGA(PATH,filename);
                boolean statu2 = nHD(PATH,filename);
                boolean statu3 = PAL(PATH,filename);
                boolean statu4 = VGA(PATH,filename);
                if(statu1==statu2==statu3==statu4==true)
                    status = true;
            }else if(width==854){
                 boolean statu4 = VGA(PATH,filename);
                 boolean statu3 = PAL(PATH,filename);
                 boolean statu2 = nHD(PATH,filename);
                 if(statu2==statu3==statu4==true)
                        status = true; 
            }else if(width==720){
                 boolean statu4 = VGA(PATH,filename);
                 boolean statu2 = nHD(PATH,filename);
                 if(statu2==statu4==true)
                        status = true; 
            }else if(width==640&&hight==480){
                 boolean statu2 = nHD(PATH,filename);
                        status = statu2; 
            }
            return status;
        }


        private boolean checkfile(String path) {
            File file = new File(path);
            if (!file.isFile()) {
                return false;
            } else {
                return true;
            }
        }
        /***
         * 854x480视频
         * @param p
         * @return
         */
        private boolean FWVGA(String PATH,String filename) {

            if (!checkfile(PATH)) {
                System.out.println(PATH + "不存在");
                return false;
            }
            int i = PATH.indexOf(".");
            //视屏类型
            String videoType = PATH.substring(i);

            List commend = new java.util.ArrayList();
            commend.add(ffmpegpath);
            commend.add("-i");
            commend.add(PATH);
            commend.add("-s");//指定分辨率
            commend.add("854x480");

            commend.add("-r");//桢速率(可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
            commend.add("25");

            commend.add("-b");// 指定压缩比特率,似乎ffmpeg是自动VBR的,指定了就大概是平均比特率,比如768,1500这样的 
            //就是原来默认项目中有的
            commend.add("1400");

            commend.add("-ab");//设定声音比特率,前面-ac设为立体声时要以一半比特率来设置,比如192kbps的就设成96,转换 
           // 君默认比特率都较小,要听到较高品质声音的话建议设到160kbps(80)以上 
            commend.add("128");




            commend.add("-acodec");//设定声音编码
            commend.add("libmp3lame");

            commend.add("-ac");//设定声道数,1就是单声道,2就是立体声
            commend.add("2");

            commend.add("-y");
            commend.add(flvfolder + filename +"854x480"+videoType);

            try {
                ProcessBuilder builder = new ProcessBuilder();
                builder.command(commend);
                Process p = builder.start();
                doWaitFor(p);
                p.destroy();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }



        /***
         * 640X360视频
         * @param p
         * @return
         */
        private boolean nHD(String PATH,String filename) {

            if (!checkfile(PATH)) {
                System.out.println(PATH + "不存在");
                return false;
            }
            int i = PATH.indexOf(".");
            //视屏类型
            String videoType = PATH.substring(i);

            List commend = new java.util.ArrayList();
            commend.add(ffmpegpath);
            commend.add("-i");
            commend.add(PATH);

            commend.add("-s");//指定分辨率
            commend.add("640X360");

            commend.add("-r");//桢速率(可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
            commend.add("25");

            commend.add("-b");// 指定压缩比特率,似乎ffmpeg是自动VBR的,指定了就大概是平均比特率,比如768,1500这样的 
            //就是原来默认项目中有的
            commend.add("800");

            commend.add("-ab");//设定声音比特率,前面-ac设为立体声时要以一半比特率来设置,比如192kbps的就设成96,转换 
           // 君默认比特率都较小,要听到较高品质声音的话建议设到160kbps(80)以上 
            commend.add("128");


            commend.add("-acodec");//设定声音编码
            commend.add("libmp3lame");

            commend.add("-ac");//设定声道数,1就是单声道,2就是立体声
            commend.add("2");


            commend.add("-y");
            commend.add(flvfolder + filename + "640X360"+videoType);

            try {
                ProcessBuilder builder = new ProcessBuilder();
                builder.command(commend);
                Process p = builder.start();
                doWaitFor(p);
                p.destroy();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }

        /***
         *720x576视频
         * @param p
         * @return
         */
        private boolean PAL(String PATH,String filename) {

            if (!checkfile(PATH)) {
                System.out.println(PATH + "不存在");
                return false;
            }
            int i = PATH.indexOf(".");
            //视屏类型
            String videoType = PATH.substring(i);

            List commend = new java.util.ArrayList();
            commend.add(ffmpegpath);
            commend.add("-i");
            commend.add(PATH);

            commend.add("-s");//指定分辨率
            commend.add("720x576");

            commend.add("-r");//桢速率(可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
            commend.add("25");

            commend.add("-b");// 指定压缩比特率,似乎ffmpeg是自动VBR的,指定了就大概是平均比特率,比如768,1500这样的 
            //就是原来默认项目中有的
            commend.add("1500");

            commend.add("-ab");//设定声音比特率,前面-ac设为立体声时要以一半比特率来设置,比如192kbps的就设成96,转换 
           // 君默认比特率都较小,要听到较高品质声音的话建议设到160kbps(80)以上 
            commend.add("128");

            commend.add("-acodec");//设定声音编码
            commend.add("libmp3lame");

            commend.add("-ac");//设定声道数,1就是单声道,2就是立体声
            commend.add("2");

            commend.add("-y");
            commend.add(flvfolder + filename + "720x576"+videoType);



            try {
                ProcessBuilder builder = new ProcessBuilder();
                builder.command(commend);
                Process p = builder.start();
                doWaitFor(p);
                p.destroy();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }




        /***
         *640x480视频
         * @param p
         * @return
         */
        private boolean VGA(String PATH,String filename) {

            if (!checkfile(PATH)) {
                System.out.println(PATH + "不存在");
                return false;
            }
            int i = PATH.indexOf(".");
            //视屏类型
            String videoType = PATH.substring(i);

            List commend = new java.util.ArrayList();
            commend.add(ffmpegpath);
            commend.add("-i");
            commend.add(PATH);

            commend.add("-s");//指定分辨率
            commend.add("640x480");

            commend.add("-r");//桢速率(可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
            commend.add("25");

            commend.add("-b");// 指定压缩比特率,似乎ffmpeg是自动VBR的,指定了就大概是平均比特率,比如768,1500这样的 
            //就是原来默认项目中有的
            commend.add("1000");

            commend.add("-ab");//设定声音比特率,前面-ac设为立体声时要以一半比特率来设置,比如192kbps的就设成96,转换 
           // 君默认比特率都较小,要听到较高品质声音的话建议设到160kbps(80)以上 
            commend.add("128");

            commend.add("-acodec");//设定声音编码
            commend.add("libmp3lame");

            commend.add("-ac");//设定声道数,1就是单声道,2就是立体声
            commend.add("2");

            commend.add("-y");
            commend.add(flvfolder + filename + "640x480"+videoType);


            try {
                ProcessBuilder builder = new ProcessBuilder();
                builder.command(commend);
                Process p = builder.start();
                doWaitFor(p);
                p.destroy();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }


        @SuppressWarnings("static-access")
        public int doWaitFor(Process p) {
            InputStream in = null;
            InputStream err = null;
            int exitValue = -1; // returned to caller when p is finished
            try {
                System.out.println("comeing");
                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());
                            System.out.print(c);
                        }
                        while (err.available() > 0) {
                            Character c = new Character((char) err.read());
                            System.out.print(c);
                        }

                        exitValue = p.exitValue();
                        finished = true;

                    } catch (IllegalThreadStateException e) {
                        Thread.currentThread().sleep(500);
                    }
                }
            } catch (Exception e) {
                System.err.println("doWaitFor();: unexpected exception - "
                        + e.getMessage());
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }

                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
                if (err != null) {
                    try {
                        err.close();
                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    }
                }
            }
            return exitValue;
        }

}

获得视频信息函数:

package com.main;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;

/**
 * 视频操作类
 * @author Administrator
 *
 */
public class VedioInfoUtil {
    /**
     * 获取视频的时长,分辨率、大小
     * @param filename
     * @return
     */
    public int getwidth(String filename){
        int width = 0;

         // first we create a Xuggler container object
        IContainer container = IContainer.make();

        // we attempt to open up the container
        int result = container.open(filename, IContainer.Type.READ, null);

        // check if the operation was successful
        if (result<0)
            return 0;

        // query how many streams the call to open found
        int numStreams = container.getNumStreams();
        // query for the total duration
        long duration = container.getDuration();
        // query for the file size
        long fileSize = container.getFileSize();
        long secondDuration = duration/1000000;
        System.out.println("时长:"+secondDuration+"秒");
        System.out.println("文件大小:"+fileSize+"M");
        for (int i=0; i<numStreams; i++) {
            IStream stream = container.getStream(i);
            IStreamCoder coder = stream.getStreamCoder();
            if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
                 System.out.println("视频宽度:"+coder.getWidth());
                 System.out.println("视频高度:"+coder.getHeight());
                 width = coder.getWidth() ;
            }
        }
        return width;
    }

    public int gethight(String filename){

        int hight = 0;
        IContainer container = IContainer.make();
        int result = container.open(filename, IContainer.Type.READ, null);

        // check if the operation was successful
        if (result<0)
            return 0;
        int numStreams = container.getNumStreams();
        long duration = container.getDuration();
        long fileSize = container.getFileSize();
        long secondDuration = duration/1000000;

        System.out.println("时长:"+secondDuration+"秒");
        System.out.println("文件大小:"+fileSize+"M");
        for (int i=0; i<numStreams; i++) {
            IStream stream = container.getStream(i);
            IStreamCoder coder = stream.getStreamCoder();
            if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
                 System.out.println("视频宽度:"+coder.getWidth());
                 System.out.println("视频高度:"+coder.getHeight());
                 hight = coder.getHeight() ;
            }
        }
        return hight;
}

}

案例下载:

http://pan.baidu.com/s/1geVK8Qv 密码:hsgd

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值