java 用ffmpeg和mencoder进行视频转码

1.准备阶段:首先需要ffmpeg.exe和mencoder.exe,java需要调用这两个文件来进行转码。

drv43260.dll,pncrt.dll,pthreadGC2.dll  为动态链接库   必须有 ,否则 rm格式 文件利用mencoder转换avi时会报如下错误

Opening video decoder: [realvid] RealVideo decoder
Error loading dll
ERROR: Could not open required DirectShow codec drvc.so.
Read the RealVideo section of the DOCS!
VDecoder init failed :(
Opening video decoder: [realvid] RealVideo decoder
Error loading dll
ERROR: Could not open required DirectShow codec drv4.so.6.0.
Read the RealVideo section of the DOCS!
VDecoder init failed :(
Opening video decoder: [realvid] RealVideo decoder
Error loading dll
ERROR: Could not open required DirectShow codec drv43260.dll.
Read the RealVideo section of the DOCS!
VDecoder init failed :(
Opening video decoder: [realvid] RealVideo decoder
Error loading dll
ERROR: Could not open required DirectShow codec drvc.bundle/Contents/MacOS/drvc.

Read the RealVideo section of the DOCS!
VDecoder init failed :(
Cannot find codec matching selected -vo and video format 0x30345652.
Read DOCS/HTML/en/codecs.html!

--------------------------------------------------------------------------------------------------------------------

2.编码阶段:

转码类------FileUploadTools

package com.test.util;

import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.InputFormatException;
import it.sauronsoftware.jave.MultimediaInfo;
import it.sauronsoftware.jave.VideoAttributes;
import it.sauronsoftware.jave.VideoSize;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.http.HttpRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

public class FileUploadTool {
TransfMediaTools transfMediaTools=new TransfMediaTools();
//文件最大200M
private static long upload_maxsize=200*1024*1024;
// 文件允许格式
private static String[] allowFiles = { ".rar", ".doc", ".docx", ".zip",
".pdf", ".txt", ".swf", ".xlsx", ".gif", ".png", ".jpg", ".jpeg",
".bmp", ".xls", ".mp4", ".flv", ".ppt", ".avi", ".mpg", ".wmv",
".3gp", ".mov", ".asf", ".asx", ".vob", ".wmv9", ".rm", ".rmvb" };
//视频格式
private static String[] videoFiles={".swf",".mp4", ".flv",".avi", ".mpg", ".wmv",".3gp", ".mov", ".asf", ".asx", ".vob", ".wmv9", ".rm", ".rmvb"};
//图片格式
private static String[] photoFiles={".gif", ".png", ".jpg", ".jpeg",".bmp"};
// 允许转码的视频格式(ffmpeg)
private static String[] allowFLV = { ".avi", ".mpg", ".wmv", ".3gp",".mov", ".asf", ".asx", ".vob" ,".mp4"};
// 允许的视频转码格式(mencoder)
private static String[] allowAVI = { ".wmv9", ".rm", ".rmvb" };
//视频时长 秒
private static int max_time=180;

public Object createFile(MultipartFile multipartFile,HttpServletRequest request,HttpSession session){
Map<String, Object> map=new HashMap<String, Object>();

FileEntity entity=new FileEntity();
boolean bflag=false;

int minute=0;
int seconde=0;
int time=0;

String fileName=multipartFile.getOriginalFilename().toString();
//判断文件不能为空
if(multipartFile.getSize()!=0 && !multipartFile.isEmpty()){
bflag=true;
//判断文件大小
if(multipartFile.getSize()<=upload_maxsize){
bflag=true;
//文件类型判断
if(this.checkFileType(fileName)){
bflag=true;

try {
//获取文件时长
CommonsMultipartFile cf=(CommonsMultipartFile) multipartFile;
DiskFileItem fi=(DiskFileItem) cf.getFileItem();
File source=fi.getStoreLocation();
Encoder encoder=new Encoder();

MultimediaInfo m=encoder.getInfo(source);
System.out.println("-------"+m.getDuration());
long ls=m.getDuration()/1000;
minute=(int) ((ls%3600)/60);
seconde=(int)(ls-minute*60);
time=(int) ls;
System.out.println("此视频时长:"+minute+"分"+seconde+"秒, 总时长"+ls+"秒");
System.out.println("此视频格式:"+m.getFormat());
} catch (InputFormatException e1) {
e1.printStackTrace();
} catch (EncoderException e1) {
e1.printStackTrace();
}

if(time<=max_time){
bflag=true;
}else{
bflag=false;
System.out.println("视频时间过长");
map.put("code", 0);
map.put("msg", "视频时间过长");
}
}else{
bflag=false;
System.out.println("文件类型不允许");
map.put("code", 0);
map.put("msg", "文件类型不允许");
}
}else{
bflag=false;
System.out.println("文件大小超范围");
map.put("code", 0);
map.put("msg", "文件大小超范围");
}

}else{
bflag=false;
System.out.println("文件为空");
map.put("code", 0);
map.put("msg", "文件为空");
}

if(bflag){
String path = "F://video/";

// 新的文件名
String newFileName = this.getName(fileName);
//文件扩展名
String fileEnd=this.getFileExt(fileName);

//上传文件夹
File targetFile = new File(path,newFileName+fileEnd);
//1.采用transferTo方法 上传文件
//2.采用流方法上传文件 防止 文件过大 网络连接断开上传失败
if (!targetFile.exists()) {
targetFile.mkdirs();
}
try {
multipartFile.transferTo(targetFile);

// BufferedOutputStream stream = new BufferedOutputStream(
// new FileOutputStream(targetFile));
// int length=0;
// byte[] buffer = new byte[1024];
// InputStream inputStream = multipartFile.getInputStream();
// while ((length = inputStream.read(buffer)) != -1) {
// stream.write(buffer, 0, length);
// }
//
// stream.flush();
// stream.close();

} catch (Exception e) {
e.printStackTrace();
}

// 1.边上传 边压缩
// File yasFile=new File(path+"123.mp4");

// try {
// // 音频编码设置
// AudioAttributes audio = new AudioAttributes();
// audio.setCodec("libmp3lame");
// audio.setBitRate(new Integer(64000));
// audio.setChannels(new Integer(1));
// audio.setSamplingRate(new Integer(22050));

// // 视频编码设置
// VideoAttributes video = new VideoAttributes();
// video.setCodec("flv");
// video.setBitRate(new Integer(160000));
// video.setFrameRate(new Integer(15));
// video.setSize(new VideoSize(400, 300));

// // 视频转码编码设置
// EncodingAttributes attrs = new EncodingAttributes();
// attrs.setFormat("flv");
// attrs.setAudioAttributes(audio);
// attrs.setVideoAttributes(video);

// // 编码器
// Encoder encoder = new Encoder();
// encoder.encode(targetFile, yasFile, attrs);
//
// System.out.println("压缩完成...");
// } catch (EncoderException e) {
// e.printStackTrace();
//
// }

//2. 先上传 后压缩 采用工具压缩
String name = fileName.substring(0, fileName.lastIndexOf("."));
//压缩文件夹
File yasuoFile=new File(path+"yasuo/");
if(!yasuoFile.exists()){
yasuoFile.mkdirs();
}

// 相对路径
entity.setType(fileEnd);
String finalFileDir= "/filedizhi/video/yasuo/"+newFileName+fileEnd;
String size=this.getSize(targetFile);
String aviPath=targetFile.getAbsolutePath();
System.out.println("aviPath:"+aviPath);

//转码avi
if(this.checkAVIType(fileEnd)){
// 设置转换为AVI格式后文件的保存路径
String codcAviPath = path +"yasuo/"+ File.separator + newFileName + ".avi";
System.out.println("codcAviPath:"+codcAviPath);
// 获取配置的转换工具(mencoder.exe)的存放路径  tools文件夹存放在WebContent下
String mencoderPath = request.getSession().getServletContext().getRealPath("tools/mencoder.exe");
aviPath = transfMediaTools.processAVI(mencoderPath, targetFile.getAbsolutePath(), codcAviPath);
fileEnd = this.getFileExt(codcAviPath);
}

if(aviPath!=null){
//转码Flv
if (this.checkMediaType(fileEnd)) {
try {
// 设置转换为flv格式后文件的保存路径
String codcFilePath = path +"yasuo/"+ File.separator + newFileName + ".flv";
System.out.println("codcFilePath:"+codcFilePath);
// 获取配置的转换工具(ffmpeg.exe)的存放路径

String ffmpegPath =request.getSession().getServletContext().getRealPath("tools/ffmpeg.exe");
transfMediaTools.processFLV(ffmpegPath, aviPath, codcFilePath);
finalFileDir = "/filedizhi/video/yasuo/" + newFileName + ".flv";

} catch (Exception e) {
e.printStackTrace();
}
}
entity.setSize(size);
entity.setPath(finalFileDir);
entity.setTitleOrig(name);
entity.setTitleAlter(newFileName);
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
entity.setUploadTime(timestamp);

map.put("code", 1);
map.put("msg", "上传成功");
map.put("data", entity);

return map;

}else{
return null;
}
}else{
return map;
}
}

/**
* 视频文件类型判断
*
* @param fileName
* @return
*/
private boolean checkFileType(String fileName) {
Iterator<String> type = Arrays.asList(videoFiles).iterator();
while (type.hasNext()) {
String ext = type.next();
if (fileName.toLowerCase().endsWith(ext)) {
return true;
}
}
return false;
}
/**
* 图片文件类型判断
*
* @param fileName
* @return
*/
public boolean checkPhotoFileType(String fileName) {
Iterator<String> type = Arrays.asList(photoFiles).iterator();
while (type.hasNext()) {
String ext = type.next();
if (fileName.toLowerCase().endsWith(ext)) {
return true;
}
}
return false;
}

/**
* 视频类型判断(flv)
*
* @param fileName
* @return
*/
private boolean checkMediaType(String fileEnd) {
Iterator<String> type = Arrays.asList(allowFLV).iterator();
while (type.hasNext()) {
String ext = type.next();
if (fileEnd.equals(ext)) {
return true;
}
}
return false;
}

/**
* 视频类型判断(AVI)
*
* @param fileName
* @return
*/
private boolean checkAVIType(String fileEnd) {
Iterator<String> type = Arrays.asList(allowAVI).iterator();
while (type.hasNext()) {
String ext = type.next();
if (fileEnd.equals(ext)) {
return true;
}
}
return false;
}

/**
* 获取文件扩展名
*
* @return string
*/
private String getFileExt(String fileName) {
return fileName.substring(fileName.lastIndexOf("."));
}

/**
* 依据原始文件名生成新文件名
* @return
*/
private String getName(String fileName) {
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH~mm~ss");
Iterator<String> type = Arrays.asList(allowFiles).iterator();
while (type.hasNext()) {
String ext = type.next();
if (fileName.contains(ext)) {
String newFileName = formatter.format(date) + "_" + stringfilString(fileName.substring(0, fileName.lastIndexOf(ext)));
return newFileName;
}
}
return "";
}

public static String stringfilString(String str){
// 只允许字母和数字 // String regEx = "[^a-zA-Z0-9]";
// 清除掉所有特殊字符
String regEx = "[`[email protected]#$%^&*()+=|{}‘:;‘,\\[\\]<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return filterChinese(m.replaceAll("").trim());
}
public static String filterChinese(String chin){
return chin.replaceAll("[\\u4e00-\\u9fa5]", "");
}

/**
* 文件大小,返回kb.mb
*
* @return
*/
private String getSize(File file) {
String size = "";
long fileLength = file.length();
DecimalFormat df = new DecimalFormat("#.00");
if (fileLength < 1024) {
size = df.format((double) fileLength) + "BT";
} else if (fileLength < 1048576) {
size = df.format((double) fileLength / 1024) + "KB";
} else if (fileLength < 1073741824) {
size = df.format((double) fileLength / 1048576) + "MB";
} else {
size = df.format((double) fileLength / 1073741824) + "GB";
}
return size;
}

}

3.实体类

public class FileEntity {
private String type;
private String size;
private String path;
private String titleOrig;
private String titleAlter;
private Timestamp uploadTime;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getTitleOrig() {
return titleOrig;
}
public void setTitleOrig(String titleOrig) {
this.titleOrig = titleOrig;
}
public String getTitleAlter() {
return titleAlter;
}
public void setTitleAlter(String titleAlter) {
this.titleAlter = titleAlter;
}
public Timestamp getUploadTime() {
return uploadTime;
}
public void setUploadTime(Timestamp uploadTime) {
this.uploadTime = uploadTime;
}

}

4.设置编码格式

package com.test.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class TransfMediaTools {

/**
* 视频转码flv
*
* @param ffmpegPath
* 转码工具的存放路径
* @param upFilePath
* 用于指定要转换格式的文件,要截图的视频源文件
* @param codcFilePath
* 格式转换后的的文件保存路径
* @return
* @throws Exception
*/
public void processFLV(String ffmpegPath, String upFilePath, String codcFilePath) {
// 创建一个List集合来保存转换视频文件为flv格式的命令
List<String> convert = new ArrayList<String>();
convert.add(ffmpegPath); // 添加转换工具路径
convert.add("-i"); // 添加参数"-i",该参数指定要转换的文件
convert.add(upFilePath); // 添加要转换格式的视频文件的路径
convert.add("-ab");
convert.add("56");
convert.add("-ar");
convert.add("22050");
convert.add("-q:a");
convert.add("8");
convert.add("-r");
convert.add("15");
convert.add("-s");
convert.add("600*500");

/*
* convert.add("-qscale"); // 指定转换的质量 convert.add("6");
* convert.add("-ab"); // 设置音频码率 convert.add("64"); convert.add("-ac");
* // 设置声道数 convert.add("2"); convert.add("-ar"); // 设置声音的采样频率
* convert.add("22050"); convert.add("-r"); // 设置帧频 convert.add("24");
* convert.add("-y"); // 添加参数"-y",该参数指定将覆盖已存在的文件
*/
convert.add(codcFilePath);
try {
Process videoProcess = new ProcessBuilder(convert).redirectErrorStream(true).start();
new PrintStream(videoProcess.getInputStream()).start();
videoProcess.waitFor();
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

/**
* 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 先用mencoder转换为avi(ffmpeg能解析的)格式
*
* @param mencoderPath
* 转码工具的存放路径
* @param upFilePath
* 用于指定要转换格式的文件,要截图的视频源文件
* @param codcFilePath
* 格式转换后的的文件保存路径
* @return
* @throws Exception
*/
public String processAVI(String mencoderPath, String upFilePath, String codcAviPath) {
// boolean flag = false;
List<String> commend = new ArrayList<String>();
commend.add(mencoderPath);
commend.add(upFilePath);
commend.add("-oac");
commend.add("mp3lame");
// commend.add("lavc");
commend.add("-lameopts");
commend.add("preset=64");
commend.add("-lavcopts");
commend.add("acodec=mp3:abitrate=64");
commend.add("-ovc");
commend.add("xvid");
commend.add("-xvidencopts");
commend.add("bitrate=600");
commend.add("-of");
commend.add("avi");
commend.add("-o");
commend.add(codcAviPath);
try {
// 预处理进程
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);

// 进程信息输出到控制台
Process p = builder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
p.waitFor();// 直到上面的命令执行完,才向下执行
return codcAviPath;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

}

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();
}
}

}

5.调用接口上传

/**
* 上传视频
* @param file
* @param request
* @param model
* @param session
* @param response
* @return
*/
@RequestMapping("/uploadflv")
@ResponseBody
public Object uploadflv(@RequestParam("file") MultipartFile file, HttpServletRequest request, Model model, HttpSession session, HttpServletResponse response){
FileUploadTool fileUploadTool=new FileUploadTool();
Object map=fileUploadTool.createFile(file, request, session);

return map;

}

原文地址:https://www.cnblogs.com/Forever-wind/p/11730874.html

时间: 2024-11-13 23:05:42

java 用ffmpeg和mencoder进行视频转码的相关文章

java使用ffmpeg和mencoder做视频格式转换

首发:个人博客,持续更新和纠错 主要使用技术:1)FFmpeg,用于主流格式之间的转换,例如AVI,MP4,FLV等.2)MEncoder,用于奇葩格式转主流格式,例如RMVB转AVI.这样我们可以把奇葩格式先转AVI,再由FFmpeg把AVI转成想要的格式.3)java的执行命令行操作的技术,这样安装在服务器上的↑这两个转换器就可以被java调用了.包括ProcessBuilder和Runtime这两种调法.可以参考这篇. FFmpeg的官网在这里,其文档在这里.MEncoder的官网在这里,

ASP.NET下调用ffmpeg与mencoder实现视频转换截屏

最近要做一个视频播放的系统,用到了ffmpeg和mencoder两个工具,查了一些资料,发现这方面的资料还挺多的,但是就是乱了一点,我自己从头整理了一下,和大家分享一下: 1.ffmpeg实现视频(avi,wmv等格式)转换为flv格式: /// <summary> /// 转换视频为flv /// </summary> /// <param name="fileName">上传视频文件的路径(原文件)</param> /// <p

Java+Windows+ffmpeg实现视频转换

最近由于项目需要,研究了一下如何用Java实现视频转换,“着实”废了点心思,整理整理,写出给自己备忘下. 思路 由于之前没有没法过相关功能的经验,一开始来真不知道从哪里入手.当然,这个解决,google一下立马就发现了ffmpeg,网上讲解用Java+ffmpeg来进行视频转换的文章也不在少数,我主要参考的这篇文章. 上文提到的这篇文章,基本已经把开发流程什么的讲的很清楚了,这里总结下: 1)核心是利用ffmpeg进行视频转换,我们自己并不写转换视频的代码,只是调用ffmpeg,它会帮我们完成视

Java Web 中使用ffmpeg实现视频转码、视频截图

转载自:[http://www.cnblogs.com/dennisit/archive/2013/02/16/2913287.html] 视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器. 多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能.视频格式转换.视频抓图.给视频加水印等. ffmpeg视频采集功能非常强大,不仅可以采集视频采集卡或USB摄像头的图像,还可

Java使用FFmpeg处理视频文件指南

Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频的文章,大多都讲的比较简单,楼主在实操过程中踩了很多坑也填了很多坑,希望这份详细的踩坑&填坑指南能帮助到大家: 1. 什么是FFmpeg 点我了解 2. 开发前准备 在使用Java调用FFmpeg处理音视频之前,需要先安装FFmpeg,安装方法分为两种: 引入封装了FFmpeg的开源框架 在系统中手

Java实现视频网站的视频上传、视频转码、视频关键帧抽图, 及视频播放功能

视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器. 多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能.视频格式转换.视频抓图.给视频加水印等. ffmpeg视频采集功能非常强大,不仅可以采集视频采集卡或USB摄像头的图像,还可以进行屏幕录制,同时还支持以RTP方式将视频流传送给支持RTSP的流媒体服务器,支持直播应用. 1.能支持的格式 ffmpeg能解析的格式:

使用java执行ffmpeg命令进行推流操作

视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器. 多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能.视频格式转换.视频抓图.给视频加水印等. ffmpeg视频采集功能非常强大,不仅可以采集视频采集卡或USB摄像头的图像,还可以进行屏幕录制,同时还支持以RTP方式将视频流传送给支持RTSP的流媒体服务器,支持直播应用. 1.能支持的格式 ffmpeg能解析的格式:

利用FFmpeg玩转Android视频录制与压缩(二)&lt;转&gt;

转载出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女票已经分了又合,合了又分,本屌依旧骄傲单身.上一次啊我们大致说了一些简单的FFmpeg命令以及Java层简单的调用方式,然后有很多朋友在github或者csdn上给我留言,很多时候我都选择避而不答,原因是本库以前用的so包是不开源的,我根本改不了里面东西.但是这一次啊我们玩点大的,我重新编译了FFm

Install FFmpeg, Mplayer, Mencoder, MP4Box, Flvtool2

You can use the following tutorial to install ffmpeg and other video modules in your centos server.FFmpegis an audio/video conversion tool. It includes libavcodec, the leading open source codec library. An experimental streaming server for live broad