使用jave進行視頻轉碼

最近在做項目的時候發現,使用jwplayer播放視頻會出現只有聲音沒有畫面的情況,經過調查發現是視頻的編碼格式問題造成的,簡單的解決方式是下載一個格式工廠,將視頻格式設置爲h264就可以正常播放了。如何想實現在上傳的時候進行轉碼,請往下看。

  1. 首先是判斷上傳的視頻編碼格式是否是h264
    1. 需要使用我們的工具類jave,詳細的介紹請看http://www.sauronsoftware.it/projects/jave/
    2. 下載地址http://www.sauronsoftware.it/projects/jave/download.php
    3. 下載完成後,我們對源碼進行進一步的擴展,在it.sauronsoftware.jave.Encoder中重載了getInfo方法,具體功能是獲取視頻的編碼格式
public MultimediaInfo getInfo(File source, File desc) throws InputFormatException, EncoderException {
        FFMPEGExecutor ffmpeg = this.locator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(source.getAbsolutePath());
        String imagePath = "";
        if (desc != null && (desc.getPath().endsWith(".jpg") || desc.getPath().endsWith(".jpeg"))) {
            ffmpeg.addArgument("-y");
            ffmpeg.addArgument("-f");
            ffmpeg.addArgument("image2");
            ffmpeg.addArgument("-ss");
            ffmpeg.addArgument("1");
            ffmpeg.addArgument("-t");
            ffmpeg.addArgument("0.001");
            ffmpeg.addArgument(desc.getAbsolutePath());
            imagePath = desc.getPath();
        }

        try {
            ffmpeg.execute();
        } catch (IOException var12) {
            imagePath = "";
            throw new EncoderException(var12);
        }

        MultimediaInfo var7;
        try {
            RBufferedReader reader = null;
            reader = new RBufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
            MultimediaInfo info = this.parseMultimediaInfo(source, reader);
            info.setImagePath(imagePath);
            var7 = info;
        } finally {
            ffmpeg.destroy();
        }

        return var7;
    }

 

  1. 然後調用改方法, sourceVideoPath指視頻文件的位置
 Encoder encoder = new Encoder();
 String fileName = sourceVideoPath.substring(sourceVideoPath.lastIndexOf("/"));
 String videoCover = fileName.substring(0, fileName.lastIndexOf("."))+".jpg";
 try {
    MultimediaInfo info = encoder.getInfo(new File(sourceVideoPath), new File(sourceVideoPath.substring(0, sourceVideoPath.lastIndexOf("/")) +"/changeToH264/"+videoCover));
    if(info.getVideo() == null || info.getVideo().getDecoder().indexOf("h264") == -1){
         System.out.println("info.getVideo().getDecoder(): "+info.getVideo().getDecoder());
    }
 } catch (EncoderException e) {
    e.printStackTrace();
 }

 

  1. 如果是h264文件,不需要轉碼
  2. 然後如果不是,進行轉碼
    1. 轉碼前要判斷一下當前視頻的類型是否支持轉碼,參數是視頻文件的路徑,如果返回值爲0,代表支持轉碼,否則不支持,需要先將文件轉爲支持的類型,此處暫時沒有做處理,因爲項目要求只能上傳MP4格式的視頻
private int checkContentType(String sourceVideoPath) {
        String type = sourceVideoPath.substring(sourceVideoPath.lastIndexOf(".") + 1).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;
    }

 

  1. 如果視頻支持轉碼,,調用process方法開始進行轉碼,傳入視頻文件和轉碼後的目錄文件,返回轉碼後文件路徑
    private static final String FORMAT = "mp4";
    private static final String VIDEO_CODE = "libx264";//視頻編碼格式
    private static final String AUDIO_CODE = "libmp3lame";//音頻編碼格式

private String process(File sourceFile, File targetFile) {
        int type = checkContentType(sourceFile.getPath());
        if (type == 0) {

            VideoAttributes videoAttributes = new VideoAttributes();
            videoAttributes.setCodec(VIDEO_CODE);
            videoAttributes.setBitRate(new Integer(180000));
            videoAttributes.setFrameRate(new Integer(1));

            AudioAttributes audio = new AudioAttributes();
            audio.setCodec(AUDIO_CODE);
            audio.setBitRate(new Integer(64000));
            audio.setChannels(new Integer(1));
            audio.setSamplingRate(new Integer(22050));

            EncodingAttributes attrs1 = new EncodingAttributes();
            attrs1.setVideoAttributes(videoAttributes);
            attrs1.setAudioAttributes(audio);
            attrs1.setFormat(FORMAT);
            Encoder encoder = new Encoder();

            try {
                String path = targetFile.getPath();
                targetFile = new File(path + File.separator + sourceFile.getName());
                encoder.encode(sourceFile, targetFile, attrs1);

                if (targetFile.exists()) {
                    return targetFile.getAbsolutePath();
                }
            } catch (EncoderException e) {
                e.printStackTrace();

            }

        }

        return "";
    }

 

  1. 具體轉碼時可以設置的參數,請詳見http://www.sauronsoftware.it/projects/jave/manual.php
  2. 可以根據返回信息判斷視頻是否轉碼成功
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章