Java环境:
注意:以下转码兼容所有Android,iOS.网络上找的关于ffmpeg转mp4,只能兼容部分Android,iOS根本播放不了。
我这里有三个ffmpeg.exe文件版本。网络找下下载对应版本,根据ffmpeg大小不同具有不同的功能。
第1个: ffmpeg.exe 有7.57M大小,在32位系统转mp4标准输出  代码如下(代码为一段一段的转,转完后,再去转其它的):不能合成amr的音视频。需要将amr转为mp3,再合成。
合成前先将amr 转mp3
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:/ffmpeg/input/20160316133058.amr");
commend.add("c:\\ffmpeg\\output\\Auuuu.mp3");

将wmv转成mp4

List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
commend.add("c:/ffmpeg/input/A.wmv");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
//commend.add("aac");
commend.add("libfaac");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("c:\\ffmpeg\\output\\ACK.mp4");

将音频和视频合成mp4

List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:/ffmpeg/input/courseC.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/output/Auuuu.mp3");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
//commend.add("aac"); 在32位系统下不能使用aac.在64位系统下才能使用aac
commend.add("libfaac"); //32位系统下使用,64位不能用。
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("c:\\ffmpeg\\output\\ACKKPPPP.mp4");

第2个: ffmpeg.exe 有33.1M大小,在32位系统转mp4标准输出  代码同上:

List<String> commend = new ArrayList<String>();
//使用
commend.add("c:\\ffmpeg\\ffmpeg");
//commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
//commend.add("c:/ffmpeg/output/Auuuu.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/input/courseC.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/input/20160316133058.amr");   //------如果想合成amr和mp4,需要把以下红色注释掉。否则只能将amr先转mp3,再来合成。(不需要注释下面红色部分。),
commend.add("-ab");
commend.add("192");
//commend.add("-acodec");
//commend.add("aac");
//commend.add("libfaac");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("-vcodec");
commend.add("libx264");
commend.add("c:\\ffmpeg\\output\\ACKKPPPP.mp4");

List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
commend.add("c:/ffmpeg/input/C.wmv");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
commend.add("aac");  //--------wmv转mp4这里,必须使用这个。
//commend.add("libfaac");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("c:\\ffmpeg\\output\\courseC.mp4");

第3个:ffmpeg.exe 有37.3大小,是64位的,只能在64位系统上面运行。代码如下:

List<String> commend = new ArrayList<String>();
//commend.add("c:\\ffmpeg\\ffmpeg");
/*commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
commend.add("c:/ffmpeg/output/Auuuu.mp4");*/
/* 目前项目中采用的一种方法  */
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:/ffmpeg/input/courseC.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/input/20160316133058.amr");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
commend.add("aac"); //--------64位ffmpeg时 请用这个格式转。
//commend.add("libfaac"); --------32位ffmpeg时,请用这个格式转。
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("-vcodec");
commend.add("libx264");
commend.add("c:\\ffmpeg\\output\\ACKKLMOPLLL.mp4");

以下为完整的代码:
流程是:Servlet接收上传的amr文件。并将ffmpeg路径和音频路径,视频路径转到这个类下面执行。
--------------Servlet ----------------
package com.victoria.controller;import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import net.sf.json.JSONArray;
import net.sf.json.JSONObject;import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;import com.victoria.dao.DaoFactory;
import com.victoria.dao.MediaDao;
import com.victoria.entity.Media;
import com.victoria.manager.MediaManager;
import com.victoria.utils.DateTimeUtil;/****  MediaService.java   **  @version : 1.1* *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>*   *  @since     : 1.0        创建时间:    2013-2-08        下午02:24:47*     *  TODO     :    class MediaService.java is used for ...**/
public class MediaServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {PrintWriter out = response.getWriter();MediaDao mediaDao = DaoFactory.getMediaDao();ServletContext sctx = this.getServletContext();//获得保存文件的路径String audiosPath = sctx.getRealPath("audios");String videosPath = sctx.getRealPath("videos");String dataPath = DateTimeUtil.getYMDFormat();String savePath = ""; //mp4保存路径String fileName = ""; //上传的文件名
audiosPath = audiosPath + File.separator + dataPath;Map<String, String> map = new HashMap<String, String>();//创建音频保存路径File audiosFile = new File(audiosPath);if (!audiosFile.exists()) {audiosFile.mkdir();}//创建视频保存路径videosPath = videosPath + File.separator + dataPath;File videosFile = new File(videosPath);if (!videosFile.exists()) {videosFile.mkdir();}String uri = request.getRequestURI();String path = uri.substring(uri.lastIndexOf("/"));if (uri.indexOf(".") != -1) {path = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));}//System.out.println("path: "+ System.getProperties().getProperty("os.name"));if("/uploadFile".equals(path)){//提供解析时的一些缺省配置
DiskFileItemFactory factory = new DiskFileItemFactory();//创建一个解析器,分析InputStream,该解析器会将分析的结果封装成一个FileItem对象的集合//一个FileItem对象对应一个表单域ServletFileUpload sfu = new ServletFileUpload(factory);try {Media media = new Media();List<FileItem> items = sfu.parseRequest(request);boolean flag = false;    //转码成功与否的标记for(int i=0; i<items.size(); i++){FileItem item = items.get(i);//要区分是上传文件还是普通的表单域if(!item.isFormField()){//isFormField()为true,表示这不是文件上传表单域//上传文件//获得文件名fileName = item.getName();System.out.println("---------------上传文件名:"+fileName+"-----------------");long size = item.getSize();if((fileName == null || "".equals(fileName)) && size == 0){continue;}fileName = URLDecoder.decode(fileName, "UTF-8"); //System.out.println("上传文件" + item.getName());//在某些操作系统上,item.getName()方法会返回文件的完整名称,即包括路径String mp3 = audiosPath + File.separator + DateTimeUtil.getYMDHMS();String fileType = "";if (fileName.indexOf(".")!=-1) {fileType = fileName.substring(fileName.lastIndexOf(".")); //截取文件格式mp3 += fileType;}//待转码的文件File uploadFile = new File(mp3);item.write(uploadFile);System.out.println("--------------mp3:"+mp3+"--------------");if(item.getSize()>500*1024*1024){map.put("state", "0");}//String mediaPicPath = basePath + "/images" +File.separator+ serialName + ".jpg";    //设置上传视频截图的保存路径// 获取配置的转换工具(ffmpeg.exe)的存放路径String ffmpegPath = getServletContext().getRealPath("/tools/ffmpeg.exe");System.out.println("--------------ffmpegPath:"+ffmpegPath+"--------------");String[] arr = null;if (fileName.indexOf(File.separator)!=-1) {//如果文件名带完整路径 包括 斜杠的。进行截取String wei = fileName.substring(fileName.lastIndexOf(File.separator)+1, fileName.lastIndexOf("."));arr = wei.split("-");media.setImei(wei.substring(0, wei.lastIndexOf("-")));media.setCid(arr[arr.length-1]);if ("course1".equals(arr[arr.length-1])){} else {}} else {//如果文件名是不带路径的String wei = fileName.substring(0, fileName.lastIndexOf("."));arr = wei.split("-");media.setImei(wei.substring(0, wei.lastIndexOf("-")));media.setCid(arr[arr.length-1]);System.out.println("imei:"+media.getImei()+"Cid:"+arr[arr.length-1]);if ("course1".equals(arr[1])){} else {}}String codcFilePath = videosPath +File.separator+ media.getCid() +"-" + DateTimeUtil.getYMDHMS() + ".mp4";//设置转换为flv格式后文件的保存路径//用于保存mp4最终路径savePath = "/videos/" + dataPath + "/" + media.getCid() +"-" +DateTimeUtil.getYMDHMS() + ".mp4";media.setSrc("/audios/" + dataPath + "/" + DateTimeUtil.getYMDHMS() + fileType);media.setDest(savePath);media.setUptime(DateTimeUtil.getYMDHMSFormat());//转码ffmpegPath = ffmpegPath.replaceAll("\\\\","/");codcFilePath = codcFilePath.replaceAll("\\\\","/");String uploadFilePath = uploadFile.getAbsolutePath().replaceAll("\\\\","/");flag = mediaDao.executeCodecs(ffmpegPath, uploadFilePath, codcFilePath, media.getCid());}}if(flag){//转码成功,向数据表中添加该视频信息//mediaDao.saveMedia(media);//MediaManager.getInstance().addMedia(media);map.put("state", "1");map.put(media.getCid(), savePath);} else {map.put("state", "0");}//request.setAttribute("message", message);//request.getRequestDispatcher("media_upload.jsp").forward(request,response);//response.sendRedirect(request.getContextPath()+ "/index.jsp?success=modify");
} catch (Exception e) {e.printStackTrace();map.put("state", "0");throw new ServletException(e);} finally {//response.getOutputStream().write();response.setCharacterEncoding("UTF-8");response.getWriter().print(JSONObject.fromObject(map));}}if("/queryAll".equals(path)){List<Media> mediaList;try {mediaList = mediaDao.queryALlMedia(0,5);request.setAttribute("mediaList", mediaList);request.getRequestDispatcher("media_list.jsp").forward(request, response);} catch (Exception e) {e.printStackTrace();}}if("/play".equals(path)){String idstr = request.getParameter("id");int mediaId = -1;Media media = null;if(null!=idstr){mediaId = Integer.parseInt(idstr);}try {media = mediaDao.queryMediaById(mediaId);} catch (Exception e) {e.printStackTrace();}request.setAttribute("media", media);request.getRequestDispatcher("media_player.jsp").forward(request, response);}}}

补充代码(在项目中因为语音识别apk不能和系统自带的录音调用接口同时使用,导致 我只能用语音识别apk去生成pcm格式文件):
因为pcm格式不能和视频直接合成,需要先转换为amr音频文件或wav文件后,才能和视频合成。代码如下:
//ffmpeg -f s16le -ar 8000 -ac 2 -i out.pcm -ar 44100 -ac 2 out.wav   ---- 可用
//ffmpeg -i file.wav -f s16le -acodec pcm_s16le file.pcm  ----- 没测
//ffmpeg -f s16le -ar 44.1k -ac 2 -i file.pcm file.wav   ----- 没测
// ffmpeg -y -ac 2 -ar 44100 -f s16le -i output.pcm -acodec libmp3lame -ab 128k a.mp3   ----- 不能用
List<String> commend = new ArrayList<String>();
/*commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-f");
commend.add("s16le");
commend.add("-ar");
commend.add("8000");
commend.add("-ac");
commend.add("2");
commend.add("-i");
commend.add("c:\\ffmpeg\\input\\863925029959719-courseA.pcm");
commend.add("-ar");
commend.add("44100");
commend.add("-ac");
commend.add("2");
commend.add("c:\\ffmpeg\\output\\vvvvvvvvv.wav");*///ffmpeg -i testwav.wav -ar 8000 -ab 12.2k audio.amr  -----不能用
//ffmpeg -i test.wav -acodec libamr_nb -ab 12.2k -ar 8000 -ac 1 wav2amr.amr  -----不能用
//ffmpeg.exe -i PA003.wav -ar 8000 -ab 12.2k -ac 1 target.amr  此方法验证通过
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:\\ffmpeg\\output\\vvvvvvvvv.wav");
//commend.add("-acodec");
//commend.add("libamr_nb");
commend.add("-ab");
commend.add("12.2k");
commend.add("-ar");
commend.add("8000");
commend.add("-ac");
commend.add("1");
commend.add("c:\\ffmpeg\\output\\audio.amr");

Java环境:
注意:以下转码兼容所有Android,iOS.网络上找的关于ffmpeg转mp4,只能兼容部分Android,iOS根本播放不了。
我这里有三个ffmpeg.exe文件。
第1个: ffmpeg.exe 有7.57M大小,在32位系统转mp4标准输出  代码如下(代码为一段一段的转,转完后,再去转其它的):不能合成amr的音视频。需要将amr转为mp3,再合成。
合成前先将amr 转mp3
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:/ffmpeg/input/20160316133058.amr");
commend.add("c:\\ffmpeg\\output\\Auuuu.mp3");
将wmv转成mp4
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
commend.add("c:/ffmpeg/input/A.wmv");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
//commend.add("aac");
commend.add("libfaac");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("c:\\ffmpeg\\output\\ACK.mp4");
将音频和视频合成mp4
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:/ffmpeg/input/courseC.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/output/Auuuu.mp3");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
//commend.add("aac"); 在32位系统下不能使用aac.在64位系统下才能使用aac
commend.add("libfaac"); //32位系统下使用,64位不能用。
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("c:\\ffmpeg\\output\\ACKKPPPP.mp4");
第2个: ffmpeg.exe 有33.1M大小,在32位系统转mp4标准输出  代码同上:
List<String> commend = new ArrayList<String>();
//使用
commend.add("c:\\ffmpeg\\ffmpeg");
//commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
//commend.add("c:/ffmpeg/output/Auuuu.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/input/courseC.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/input/20160316133058.amr");   //------如果想合成amr和mp4,需要把以下红色注释掉。否则只能将amr先转mp3,再来合成。(不需要注释下面红色部分。),
commend.add("-ab");
commend.add("192");
//commend.add("-acodec");  
//commend.add("aac");
//commend.add("libfaac");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("-vcodec");
commend.add("libx264");
commend.add("c:\\ffmpeg\\output\\ACKKPPPP.mp4");
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
commend.add("c:/ffmpeg/input/C.wmv");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
commend.add("aac");  //--------wmv转mp4这里,必须使用这个。
//commend.add("libfaac");
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("c:\\ffmpeg\\output\\courseC.mp4");
第3个:ffmpeg.exe 有37.3大小,是64位的,只能在64位系统上面运行。代码如下:
List<String> commend = new ArrayList<String>();
//commend.add("c:\\ffmpeg\\ffmpeg");
/*commend.add("-i");
//commend.add("c:/ffmpeg/input/courseA.mp4");
commend.add("c:/ffmpeg/output/Auuuu.mp4");*/
/* 目前项目中采用的一种方法  */
List<String> commend = new ArrayList<String>();
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:/ffmpeg/input/courseC.mp4");
commend.add("-i");
commend.add("c:/ffmpeg/input/20160316133058.amr");
commend.add("-ab");
commend.add("192");
commend.add("-acodec");
commend.add("aac"); //--------64位ffmpeg时 请用这个格式转。
//commend.add("libfaac"); --------32位ffmpeg时,请用这个格式转。
commend.add("-ac");
commend.add("2");
commend.add("-ar");
commend.add("44100");
commend.add("-qscale");
commend.add("4");
commend.add("-r");
commend.add("29.97");
commend.add("-s");
commend.add("800x480");
commend.add("-y");
commend.add("-vcodec");
commend.add("libx264");
commend.add("c:\\ffmpeg\\output\\ACKKLMOPLLL.mp4");
以下为完整的代码:
流程是:Servlet接收上传的amr文件。并将ffmpeg路径和音频路径,视频路径转到这个类下面执行。
--------------Servlet ----------------
package com.victoria.controller;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.victoria.dao.DaoFactory;
import com.victoria.dao.MediaDao;
import com.victoria.entity.Media;
import com.victoria.manager.MediaManager;
import com.victoria.utils.DateTimeUtil;
/**
*
*  MediaService.java   
*
*  @version : 1.1
*  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
*   
*  @since     : 1.0        创建时间:    2013-2-08        下午02:24:47
*     
*  TODO     :    class MediaService.java is used for ...
*
*/
public class MediaServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
MediaDao mediaDao = DaoFactory.getMediaDao();
ServletContext sctx = this.getServletContext();
//获得保存文件的路径
String audiosPath = sctx.getRealPath("audios");
String videosPath = sctx.getRealPath("videos");
String dataPath = DateTimeUtil.getYMDFormat();
String savePath = ""; //mp4保存路径
String fileName = ""; //上传的文件名
audiosPath = audiosPath + File.separator + dataPath;
Map<String, String> map = new HashMap<String, String>();
//创建音频保存路径
File audiosFile = new File(audiosPath);
if (!audiosFile.exists()) {
audiosFile.mkdir();
}
//创建视频保存路径
videosPath = videosPath + File.separator + dataPath;
File videosFile = new File(videosPath);
if (!videosFile.exists()) {
videosFile.mkdir();
}
String uri = request.getRequestURI();
String path = uri.substring(uri.lastIndexOf("/"));
if (uri.indexOf(".") != -1) {
path = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
}
//System.out.println("path: "+ System.getProperties().getProperty("os.name"));
if("/uploadFile".equals(path)){
//提供解析时的一些缺省配置
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建一个解析器,分析InputStream,该解析器会将分析的结果封装成一个FileItem对象的集合
//一个FileItem对象对应一个表单域
ServletFileUpload sfu = new ServletFileUpload(factory);
try {
Media media = new Media();
List<FileItem> items = sfu.parseRequest(request);
boolean flag = false;    //转码成功与否的标记
for(int i=0; i<items.size(); i++){
FileItem item = items.get(i);
//要区分是上传文件还是普通的表单域
if(!item.isFormField()){//isFormField()为true,表示这不是文件上传表单域
//上传文件
//获得文件名
fileName = item.getName();
System.out.println("---------------上传文件名:"+fileName+"-----------------");
long size = item.getSize();
if((fileName == null || "".equals(fileName)) && size == 0){
continue;
}
fileName = URLDecoder.decode(fileName, "UTF-8"); 
//System.out.println("上传文件" + item.getName());
//在某些操作系统上,item.getName()方法会返回文件的完整名称,即包括路径
String mp3 = audiosPath + File.separator + DateTimeUtil.getYMDHMS();
String fileType = "";
if (fileName.indexOf(".")!=-1) {
fileType = fileName.substring(fileName.lastIndexOf(".")); //截取文件格式
mp3 += fileType;
}
//待转码的文件
File uploadFile = new File(mp3);
item.write(uploadFile);
System.out.println("--------------mp3:"+mp3+"--------------");
if(item.getSize()>500*1024*1024){
map.put("state", "0");
}
//String mediaPicPath = basePath + "/images" +File.separator+ serialName + ".jpg";    //设置上传视频截图的保存路径
// 获取配置的转换工具(ffmpeg.exe)的存放路径
String ffmpegPath = getServletContext().getRealPath("/tools/ffmpeg.exe");
System.out.println("--------------ffmpegPath:"+ffmpegPath+"--------------");
String[] arr = null;
if (fileName.indexOf(File.separator)!=-1) {
//如果文件名带完整路径 包括 斜杠的。进行截取
String wei = fileName.substring(fileName.lastIndexOf(File.separator)+1, fileName.lastIndexOf("."));
arr = wei.split("-");
media.setImei(wei.substring(0, wei.lastIndexOf("-")));
media.setCid(arr[arr.length-1]);
if ("course1".equals(arr[arr.length-1])){
} else {
}
} else {
//如果文件名是不带路径的
String wei = fileName.substring(0, fileName.lastIndexOf("."));
arr = wei.split("-");
media.setImei(wei.substring(0, wei.lastIndexOf("-")));
media.setCid(arr[arr.length-1]);
System.out.println("imei:"+media.getImei()+"Cid:"+arr[arr.length-1]);
if ("course1".equals(arr[1])){
} else {
}
}
String codcFilePath = videosPath +File.separator+ media.getCid() +"-" + DateTimeUtil.getYMDHMS() + ".mp4";//设置转换为flv格式后文件的保存路径
//用于保存mp4最终路径
savePath = "/videos/" + dataPath + "/" + media.getCid() +"-" +DateTimeUtil.getYMDHMS() + ".mp4";
media.setSrc("/audios/" + dataPath + "/" + DateTimeUtil.getYMDHMS() + fileType);
media.setDest(savePath);
media.setUptime(DateTimeUtil.getYMDHMSFormat());
//转码
ffmpegPath = ffmpegPath.replaceAll("\\\\","/");
codcFilePath = codcFilePath.replaceAll("\\\\","/");
String uploadFilePath = uploadFile.getAbsolutePath().replaceAll("\\\\","/");
flag = mediaDao.executeCodecs(ffmpegPath, uploadFilePath, codcFilePath, media.getCid());
}
}
if(flag){
//转码成功,向数据表中添加该视频信息
//mediaDao.saveMedia(media);
//MediaManager.getInstance().addMedia(media);
map.put("state", "1");
map.put(media.getCid(), savePath);
} else {
map.put("state", "0");
}
//request.setAttribute("message", message);
//request.getRequestDispatcher("media_upload.jsp").forward(request,response);
//response.sendRedirect(request.getContextPath()+ "/index.jsp?success=modify");
} catch (Exception e) {
e.printStackTrace();
map.put("state", "0");
throw new ServletException(e);
} finally {
//response.getOutputStream().write();
response.setCharacterEncoding("UTF-8");
response.getWriter().print(JSONObject.fromObject(map));
}
}
if("/queryAll".equals(path)){
List<Media> mediaList;
try {
mediaList = mediaDao.queryALlMedia(0,5);
request.setAttribute("mediaList", mediaList);
request.getRequestDispatcher("media_list.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
if("/play".equals(path)){
String idstr = request.getParameter("id");
int mediaId = -1;
Media media = null;
if(null!=idstr){
mediaId = Integer.parseInt(idstr);
}
try {
media = mediaDao.queryMediaById(mediaId);
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("media", media);
request.getRequestDispatcher("media_player.jsp").forward(request, response);
}
}
}
package com.victoria.dao;
import java.util.List;
import com.victoria.entity.Media;/****  MediaDao.java    **  @version : 1.1*  *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>*    *  @since     : 1.0        创建时间:    2013-2-07        上午10:19:54*     *  TODO     :    interface MediaDao.java is used for ...**/
public interface MediaDao {/*** 视频转码* @param ffmpegPath    转码工具的存放路径* @param upFilePath    用于指定要转换格式的文件,要截图的视频源文件* @param codcFilePath    格式转换后的的文件保存路径* @param mediaPicPath    截图保存路径* @return* @throws Exception*/public boolean executeCodecs(String ffmpegPath,String upFilePath, String codcFilePath, String cid)throws Exception;/*** 保存文件* @param media* @return* @throws Exception*/public boolean saveMedia(Media media) throws Exception;/*** 查询本地库中所有记录的数目* @return* @throws Exception*/public int getAllMediaCount()throws Exception;/*** 带分页的查询* @param firstResult* @param maxResult* @return*/public List<Media> queryALlMedia(int firstResult, int maxResult)throws Exception;/*** 根据Id查询视频* @param id* @return* @throws Exception*/public Media queryMediaById(int id)throws Exception;
}

  

----------MediaDaoImpl 处理类---------------
package com.victoria.dao.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.victoria.dao.MediaDao;
import com.victoria.entity.Media;
import com.victoria.utils.CommandUtil;
public class MediaDaoImpl implements MediaDao{
/**
* 视频转码
* @param ffmpegPath    转码工具的存放路径
* @param upFilePath    用于指定要转换格式的文件,要截图的视频源文件
* @param codcFilePath    格式转换后的的文件保存路径
* @param mediaPicPath    截图保存路径
* @return
* @throws Exception
*/
public boolean executeCodecs(String ffmpegPath, String upFilePath, String codcFilePath, String cid) throws Exception {
// 创建一个List集合来保存转换视频文件为flv格式的命令
//获取无音视频路径
String noneSoundVideo = "";
String hasSoundVideo = "";
Process process = null;//------------------
ProcessBuilder builder = new ProcessBuilder();//------------------
InputStream isErr = null;//------------------
InputStream is = null;//------------------
OutputStream os = null;
ThreadUtil stdoutUtil = null;
ThreadUtil erroroutUtil = null;
boolean mark = true;
if (codcFilePath.indexOf("/") != -1) {
noneSoundVideo = codcFilePath.substring(0, codcFilePath.indexOf("videos")+6) + "/" + "nonesound"+"/" + cid + ".mp4";
hasSoundVideo =  codcFilePath.substring(0, codcFilePath.indexOf("videos")+6) + "/"+ "hassound"+"/" + cid + ".mp4";
}
System.out.println("--"+noneSoundVideo);
//判断无音视频是否存在,不存在则将有音视频转为无音视频。
try {
if (!"".equals(noneSoundVideo) && !"".equals(hasSoundVideo) && !fileExist(noneSoundVideo) && fileExist(hasSoundVideo)) {
List<String> commend = new ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(hasSoundVideo);
commend.add("-an");
commend.add("-sameq");
commend.add("-y");
commend.add(noneSoundVideo);
builder.command(commend);//------------------
builder.redirectErrorStream(true);//------------------
process = builder.start();//------------------
isErr = process.getErrorStream();
is = process.getInputStream();
stdoutUtil = new ThreadUtil(is);
erroroutUtil = new ThreadUtil(isErr);
//启动线程读取缓冲区数据
stdoutUtil.start();
erroroutUtil.start();
process.waitFor();//------------------
os = process.getOutputStream();
os.flush();
if (os!=null) {
os.close();
}
//cu.executeCommand(commend);
}
if (fileExist(ffmpegPath) && fileExist(upFilePath)) {
//如果不是mp3文件,将其转为mp3文件
/*boolean flag = false;
if (upFilePath.indexOf(".pcm") != -1) {
flag = true;
}
String mp3 = upFilePath.replace(".pcm", ".mp3");
if (flag) {
List<String> convert = new ArrayList<String>();
convert.add(ffmpegPath); // 添加转换工具路径
convert.add("-acodec");
convert.add("pcm_s16le");
convert.add("-ar");
convert.add("8000");
convert.add("-ac");
convert.add("2");
convert.add("-f");
convert.add("alaw");
convert.add("-i");// 添加参数"-i",该参数指定要转换的文件
convert.add(upFilePath);
convert.add("-acodec");
convert.add("libmp3lame");
convert.add("-ac");
convert.add("2");
convert.add("-ab");
convert.add("128k");
convert.add(mp3);
builder.command(convert);//------------------
builder.redirectErrorStream(true);//------------------
process = builder.start();//------------------
isErr = process.getErrorStream();
is = process.getInputStream();
stdoutUtil = new ThreadUtil(is);
erroroutUtil = new ThreadUtil(isErr);
//启动线程读取缓冲区数据
stdoutUtil.start();
erroroutUtil.start();
process.waitFor();//------------------
os = process.getOutputStream();
os.flush();
if (os!=null) {
os.close();
}
}
convert.add(mp3); // 添加要转换格式的视频文件的路径
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);
*/
// 创建一个List集合来保存从视频中截取图片的命令
List<String> cutpic = new ArrayList<String>();
cutpic.add(ffmpegPath);
cutpic.add("-i");
cutpic.add(noneSoundVideo);
cutpic.add("-i");
//cutpic.add(mp3);
cutpic.add(upFilePath);
cutpic.add("-ab");
cutpic.add("192");
cutpic.add("-acodec");
cutpic.add("aac");
cutpic.add("-ac");
cutpic.add("2");
cutpic.add("-ar");
cutpic.add("44100");
cutpic.add("-qscale");
cutpic.add("4");
cutpic.add("-r");
cutpic.add("29.97");
cutpic.add("-s");
cutpic.add("800x480");
cutpic.add("-y");
cutpic.add("-vcodec");
cutpic.add("libx264");
cutpic.add(codcFilePath);
builder.command(cutpic);//------------------
builder.redirectErrorStream(true);//------------------
process = builder.start();//------------------
isErr = process.getErrorStream();
is = process.getInputStream();
stdoutUtil = new ThreadUtil(is);
erroroutUtil = new ThreadUtil(isErr);
//启动线程读取缓冲区数据
stdoutUtil.start();
erroroutUtil.start();
process.waitFor();//------------------
//process.destroy();//------------------
os = process.getOutputStream();
os.flush();
// 如果此属性为 true,则任何由通过此对象的 start() 方法启动的后续子进程生成的错误输出都将与标准输出合并,
//因此两者均可使用 Process.getInputStream() 方法读取。这使得关联错误消息和相应的输出变得更容易
}
} catch (Exception e) {
mark = false;
System.out.println(e);
e.printStackTrace();
} finally {
try{
/*if (isErr != null) {------------------
isErr.close();------------------
}
if (is != null) {------------------
is.close();
}------------------*/
if (os != null) {//------------------
os.close();//------------------
}
} catch (Exception ee) {
mark = false;
//ee.printStackTrace();
}
}
return mark;
}
private boolean checkfile(String path) {
File file = new File(path);
if (!file.isFile()) {
return false;
}
return true;
}
private boolean fileExist(String path) {
File file = new File(path);
if (file.exists() && file.isFile()){
return true;
}
return false;
}
@Override
public boolean saveMedia(Media media) throws Exception {
// TODO Auto-generated method stub
return false;
}
@Override
public int getAllMediaCount() throws Exception {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<Media> queryALlMedia(int firstResult, int maxResult)
throws Exception {
// TODO Auto-generated method stub
return null;
}
@Override
public Media queryMediaById(int id) throws Exception {
// TODO Auto-generated method stub
return null;
}
}
class ThreadUtil implements Runnable {
// 设置读取的字符编码
private String character = "GB2312";
private InputStream inputStream;
public ThreadUtil(InputStream inputStream) {
this.inputStream = inputStream;
}
public void start() {
Thread thread = new Thread(this);
thread.setDaemon(true);//将其设置为守护线程
thread.start();
}
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(inputStream, character));
String line = null;
while ((line = br.readLine()) != null) {
if (line != null) {
//list.add(line);
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//释放资源
if (inputStream != null) {
inputStream.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
补充代码(在项目中因为语音识别apk不能和系统自带的录音调用接口同时使用,导致 我只能用语音识别apk去生成pcm格式文件):
因为pcm格式不能和视频直接合成,需要先转换为amr音频文件或wav文件后,才能和视频合成。代码如下:
//ffmpeg -f s16le -ar 8000 -ac 2 -i out.pcm -ar 44100 -ac 2 out.wav   ---- 可用
//ffmpeg -i file.wav -f s16le -acodec pcm_s16le file.pcm  ----- 没测
//ffmpeg -f s16le -ar 44.1k -ac 2 -i file.pcm file.wav   ----- 没测
// ffmpeg -y -ac 2 -ar 44100 -f s16le -i output.pcm -acodec libmp3lame -ab 128k a.mp3   ----- 不能用
List<String> commend = new ArrayList<String>();
/*commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-f");
commend.add("s16le");
commend.add("-ar");
commend.add("8000");
commend.add("-ac");
commend.add("2");
commend.add("-i");
commend.add("c:\\ffmpeg\\input\\863925029959719-courseA.pcm");
commend.add("-ar");
commend.add("44100");
commend.add("-ac");
commend.add("2");
commend.add("c:\\ffmpeg\\output\\vvvvvvvvv.wav");*/
//ffmpeg -i testwav.wav -ar 8000 -ab 12.2k audio.amr  -----不能用
//ffmpeg -i test.wav -acodec libamr_nb -ab 12.2k -ar 8000 -ac 1 wav2amr.amr  -----不能用
//ffmpeg.exe -i PA003.wav -ar 8000 -ab 12.2k -ac 1 target.amr  此方法验证通过
commend.add("c:\\ffmpeg\\ffmpeg");
commend.add("-i");
commend.add("c:\\ffmpeg\\output\\vvvvvvvvv.wav");
//commend.add("-acodec");
//commend.add("libamr_nb");
commend.add("-ab");
commend.add("12.2k");
commend.add("-ar");
commend.add("8000");
commend.add("-ac");
commend.add("1");
commend.add("c:\\ffmpeg\\output\\audio.amr");

转载于:https://www.cnblogs.com/wangfx/p/5649016.html

ffmpeg 在线音频上传合成mp4格式视频,可以在网络中直接播放。相关推荐

  1. 解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题

    解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题 问题描述 java程序,使用阿里云oss文件上传服务,在测试时偶然发现,我用苹果手机开启高清进行摄像,将原图通过qq传到电脑上,在电 ...

  2. FFMPEG采集摄像头图像SDL渲染+MP4格式视频编码

    FFMPEG采集摄像头图像SDL渲染+MP4格式视频编码 FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音 ...

  3. react-前端excel 文件/PDF文件 导入 --导出、照片上传、mp4格式视频下载

    需要了解,new FormData() --上传时,将内容转为文件流 FormData提供一种表示表单数据的键值对的构造方式,实现表单数据的序列化,从而减少表单元素的拼接,提高工作效率 new Fil ...

  4. kindeditor支持视频flv, mp4格式视频上传播放

    首先声明本人用的版本为4.1.12 1.mp4视频格式上传: 修改kindeditor-all.js  _mediaImg()方法 原代码 function _mediaImg(blankPath, ...

  5. 服务器在线看视频无法播放,上传到服务器的视频不能在线播放怎么办?

    原标题:上传到服务器的视频不能在线播放怎么办? 问题:我们在本地测试视频播放时,常常遇到这种情况,本地测试视频是可以正常播放的,但项目上传服务器后,视频就无法播放了,原因通常有以下几种,原因及解决方案 ...

  6. 服务器上批量将.mp4格式的视频转化成.m3u8的shell脚本

    在服务器上批量将.mp4格式的视频转化成.m3u8的shell脚本 前半部分介绍如何安装软件以及每步骤的功能,后半部分为命令集合 一.准备步骤: 服务器的某个文件夹下要存在.mp4文件,文件名为 xx ...

  7. 【Axure高保真原型】音频上传和播放

    今天和大家分享音频上传和播放的原型模板,可以真实选择本地文件,如果选择的是音频文件文件,就会在对应区域内显示音频播放器,我们可以控制播放器从而播放音频:如果选择的不是音频文件,就会弹出提示,提示用户上 ...

  8. 在线编辑器 上传控件

    为什么80%的码农都做不了架构师?>>>    在线编辑器 上传控件 http://kindeditor.net/demo.php 上传控件: 转载于:https://my.osch ...

  9. Android之PC浏览器上传表单格式大文件到手机客户端read函数阻塞问题

    1 .问题 PC浏览器上传表单格式大文件到手机服务器端,然后read文件真实数据时候出现阻塞. 比如 User-Agent: PostmanRuntime/7.26.1Accept: */*Cache ...

最新文章

  1. word2html文档,Word2HTML用户手册.doc
  2. 索引的使用—— 验证索引提升查询效率 || 避免索引失效 —— 全值匹配 /最左前缀法则/范围查询右边的列,不能使用索引/不要在索引列上进行运算操作/字符串不加单引号,造成索引失效
  3. Python Setuptools 升级(Upgrade)
  4. python1080p壁纸高清图片_Python爬取高清桌面壁纸(附源码),直接运行即可
  5. Spark _26_Spark On Hive的配置
  6. @ngrx/router-store 在 SAP 电商云 Spartacus UI 开发中的作用
  7. Effective_STL 学习笔记(二十七) 用 distance 和 advance 把 const_iterator 转化成 iterator...
  8. Anaconda中出现No module named cv2
  9. matlab 中 x 轴的各种设置
  10. android 仿旅游日历控件_仿携程日历控件
  11. QQ截图出现闪退,无法截图(亲测有效)
  12. 树莓派4B安装中文输入法(Googlepinyin)
  13. Easyrecovery激活码生成器分享
  14. 道里云公司网络虚拟化架构NVI技术开放源代码--序言
  15. 维修技术论坛万能预装系统 v5.0
  16. BurpSuite抓包出现建立安全连接失败(Software is Preventing Firefox From Safely Connecting to This Si)
  17. 软件工程——形式化方法概述
  18. 布局——线性布局、相对布局
  19. 黑马NLP实战 --- 新闻分类模型训练
  20. Sql 日期操作 获取年月日等

热门文章

  1. matlab中自相关函数
  2. MATLAB求矩阵的100次方,Matlab矩阵幂运算
  3. 寻找两个有序数组的中位数(虚拟数组图文详解)
  4. 错误: Unknown class XXX in Interface Builder file
  5. 架构设计:架构设计要平衡兼顾多方需求
  6. 山西民生养老认证显示服务器异常,民生山西养老认证
  7. ES6 JavaScript Promise的感性认知
  8. 浅析微信支付:支付结果通知
  9. Cuda: Handle Conflicting Installation Methods
  10. java国际象棋棋牌_用java画国际象棋棋盘