赞
踩
通过Java实现视频转码如下两个方案:
1.利用国外一个大佬写的jar包jave,里面集成了ffmpeg,目前源码应该是更新到1.0.2,看了下源码应该发现,这个功能还是非常强大的,如果不需要转码,只需要获取下图片,视频信息,更是方便= = 。
JAVE(Java Audio Video Encoder),是一个包涵ffmpeg项目库。开发这可以运用它去实现音频(Audio)与视频(Video)文件的转码。例如你要把AVI格式文件转为MPEG文件、WAV格式文件转为MP3格式文件,同时你还能调整文件大小与比例。JAVE兼容和支持很多格式之间的转码……
转码的方法:
- public void encode(java.io.File source, java.io.File target, it.sauronsoftware.jave.EncodingAttributes attributes) throws java.lang.IllegalArgumentException, it.sauronsoftware.jave.InputFormatException, it.sauronsoftware.jave.EncoderException {
- File source = new File("source.avi");
- File target = new File("target.mp4");
-
- AudioAttributes audio = new AudioAttributes();
- audio.setCodec("libmp3lame");
- audio.setBitRate(new Integer(56000));
- audio.setChannels(new Integer(1));
- audio.setSamplingRate(new Integer(22050));
-
- VideoAttributes video = new VideoAttributes();
- video.setCodec("libx264");
-
- EncodingAttributes attrs = new EncodingAttributes();
- attrs.setFormat("mp4"); //h264编码
- attrs.setAudioAttributes(audio);
- attrs.setVideoAttributes(video);
- Encoder encoder = new Encoder();
- encoder.encode(source, target, attrs);
- }

借鉴的这篇博客:https://blog.csdn.net/qllinhongyu/article/details/29817297 里面介绍jave更详细点
2.利用FFmpeg进行转码,有坏处:
windows服务器还比较简单,直接下载ffmpeg可以直接进行转码了,但是linux服务器的ffmpeg的安装真的挺麻烦的。。我用了3个小时装好。
需要调用java执行外部程序Runtime类或者ProcessBuilder去构建Process,据说调用多了,非常损耗性能。
- Runtime runtime = Runtime.getRuntime();
- Process p = runtime.exec(cmd);
Process p=new ProcessBuilder(cmd).start();
这里有一点需要注意,runtime执行执行命令,processBuilder需要具体的文件
runtime的cmd: String copy="cp -rf "+source+" "+target;
processBuilder的cmd: 这里读的是配置文件中的
- video.ffmpeg.linux.path=/usr/local/ffmpegRedHat/bin/./ffmpeg
- video.ffmpeg.windows.path=D:\\project\\solr\\changToH264\\src\\ffmpeg.exe
开头不太一样。。
我目前直接用的ffmpeg,这里粘一下我的源码,可以做一下参考
- @Override
- public boolean startChangeToH264(String inputPath, String outPath) throws Exception{
- // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
- if (!checkfile(inputPath)) {
- System.out.println(inputPath + " is not file");
- throw new Exception("文件不存在");
- }
- if(checkContentType(inputPath)!=0){
- throw new Exception("文件类型无法解析");
- }
- VideoFormatToH264 videoFormatToH264=new VideoFormatToH264(inputPath,outPath);
- videoFormatToH264.run();
- return true;
- }
-
-
- private static boolean checkfile(String path) {
- File file = new File(path);
- if (!file.isFile() || (!file.exists())) {
- return false;
- }
- return true;
- }
-
- private static int checkContentType(String inputPath) {
- String type = inputPath.substring(inputPath.lastIndexOf(".") + 1, inputPath.length())
- .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;
- }
- /**
- * Created by zhangluyao on 2018/6/12.
- */
- public class VideoFormatToH264 {
- private String filePath;
- private String OutfilePath;
- private List<String> command;
- public VideoFormatToH264(String filePath,String OutfilePath){
- this.OutfilePath=OutfilePath;
- this.filePath=filePath;
- }
- public VideoFormatToH264(String filePath,String OutfilePath, List<String> command){
- this.OutfilePath=OutfilePath;
- this.filePath=filePath;
- this.command=command;
- }
-
- public void run(){
- ThreadPoolTaskExecutor threadPoolTaskExecutor=(ThreadPoolTaskExecutor)SpringUtil.getBean("threadPoolTaskExecutor");
- ChangeVideoTask changeVideoTask=new ChangeVideoTask(this.getFilePath(),this.getOutfilePath());
- threadPoolTaskExecutor.execute(changeVideoTask);
- }
- public void runCommand()throws Exception{
- if(this.command!=null){
- ThreadPoolTaskExecutor threadPoolTaskExecutor=(ThreadPoolTaskExecutor)SpringUtil.getBean("threadPoolTaskExecutor");
- ChangeVideoTask changeVideoTask=new ChangeVideoTask(this.getFilePath(),this.getOutfilePath(),this.command);
- threadPoolTaskExecutor.execute(changeVideoTask);
- }else{
- System.out.print("command为空");
- throw new Exception("command为空");
- }
- }
- private class ChangeVideoTask implements Runnable{
- private String filePath;
- private String outFilePath;
- private List<String> command;
- ChangeVideoTask(String path,String outFilePath){
- this.outFilePath=outFilePath;
- this.filePath=path;
- }
- ChangeVideoTask(String path,String outFilePath,List<String> command){
- this.outFilePath=outFilePath;
- this.filePath=path;
- this.command=command;
- }
- @Override
- public void run() {
- try {
- //命令是空时,执行视频转换成H264
- if(CollectionUtils.isEmpty(command)){
- command=new ArrayList<String>();
- command.add(Const.getFFMPEGPath());
- command.add("-i");
- command.add(filePath);
- command.add("-y");
- command.add("-vcodec");
- command.add("h264");
- command.add("-preset");
- command.add("ultrafast");
- command.add("-profile:v");
- command.add("baseline");
- command.add("-acodec");
- command.add("aac");
- command.add("-strict");
- command.add("experimental");
- command.add("-s");
- command.add("640*480");
- command.add("-b");
- command.add("568k");
- command.add("-ab");
- command.add("128k");
- if(System.getProperty("os.name").toLowerCase().indexOf("windows")>-1){
- command.add(outFilePath.substring(1));
- }else{
- command.add(outFilePath);
- }
- }
-
- System.out.println("开始转换");
- Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start();
-
- new PrintStream(videoProcess.getErrorStream()).start();
-
- new PrintStream(videoProcess.getInputStream()).start();
-
- videoProcess.waitFor();//等待进程结束
- CacheService cacheService=(CacheService) SpringUtil.getBean("cacheService");
- String sourceName=filePath.substring(filePath.lastIndexOf("/")+1);
- //转换成功,去掉redis中的key
- cacheService.remove(sourceName);
- System.out.println("转换成功");
- FileUtils.delFile(filePath);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- }
-
-
-
- private class PrintStream extends Thread
- {
- java.io.InputStream __is = null;
- public PrintStream(java.io.InputStream is)
- {
- __is = is;
- }
-
- public void run()
- {
- try
- {
- while(this != null)
- {
- int _ch = __is.read();
- if(_ch != -1)
- System.out.print((char)_ch);
- else break;
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }
- public String getFilePath() {
- return filePath;
- }
-
- public void setFilePath(String filePath) {
- this.filePath = filePath;
- }
-
- public String getOutfilePath() {
- return OutfilePath;
- }
-
- public void setOutfilePath(String outfilePath) {
- OutfilePath = outfilePath;
- }
-
- public List<String> getCommand() {
- return command;
- }
-
- public void setCommand(List<String> command) {
- this.command = command;
- }

加点东西。
ffmpeg转换成mp4文件以后,视频的元数据在末尾,jwplayer播放的时候需要全部缓冲结束才能开始播放,用户体验及其的不好~~ 更改后的代码先不贴上来了,就说下方法。
ffmpeg文件夹中,编译前的文件夹,tools下面有一个qt-faststart.c
执行下make qt-faststart 会生成一个qt-faststart 命令
然后代码中对文件 再执行一下 qt-faststart inputPath outPath 命令 就可以了
会生成一个新的文件,这个文件的元数据在开头,可以直接播放的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。