使用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. 可以根据返回信息判断视频是否转码成功
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章