最近在做項目的時候發現,使用jwplayer播放視頻會出現只有聲音沒有畫面的情況,經過調查發現是視頻的編碼格式問題造成的,簡單的解決方式是下載一個格式工廠,將視頻格式設置爲h264就可以正常播放了。如何想實現在上傳的時候進行轉碼,請往下看。
- 首先是判斷上傳的視頻編碼格式是否是h264
- 需要使用我們的工具類jave,詳細的介紹請看http://www.sauronsoftware.it/projects/jave/
- 下載地址http://www.sauronsoftware.it/projects/jave/download.php
- 下載完成後,我們對源碼進行進一步的擴展,在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;
}
- 然後調用改方法, 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();
}
- 如果是h264文件,不需要轉碼
- 然後如果不是,進行轉碼
- 轉碼前要判斷一下當前視頻的類型是否支持轉碼,參數是視頻文件的路徑,如果返回值爲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;
}
- 如果視頻支持轉碼,,調用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 "";
}
- 具體轉碼時可以設置的參數,請詳見http://www.sauronsoftware.it/projects/jave/manual.php
- 可以根據返回信息判斷視頻是否轉碼成功