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 .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@">发送邮件</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(""));
        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 .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@">发送邮件</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(""));      


               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@">发送邮件</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");