從測試到開發掌握 ffmpeg安裝 以及amr 轉換MP3 並且播放

1:原理 調用ffmpeg 執行轉換

即:先把amr 下載到服務器 調用 ffmpeg -i    轉換生成MP3 文件 通過二進制流的形式 
ajax點擊播放異步轉換並且生成流通過audio的src屬性在web端播放,同時刪除後臺的amr和mp3文件,此功能是在後臺cms 中實現,也可以獨立部署轉換。

注意:在本地開發時 不管是linux 系列 還是windows系列 一定要安裝ffmpeg 工具 即通過控制檯可以轉換成功。

直接貼代碼:

    public class AmrToMp3 {
              public static void main(String[] args){
                 AmrToMp3.convertToMp3(args[0], args[1]);
              }
              public static boolean convertToMp3(String amrFile, String mp3File)  {
                 Process process = null;
                 try{
                    File mp3 = new File(mp3File);
                    if(mp3.exists()){
                       mp3.delete();
                    }
                    process =Runtime.getRuntime().exec("ffmpeg -i " + amrFile + " " + mp3File);
                    process.waitFor();
                 }catch (Exception ex){
                 }finally {
                    process.destroy();
                 }
                 return false;
              }
            }
/**
    * amr 文件轉換MP3
    *
    * @param url
    * @param req
    * @return
    */
    public static String amrSwitchToMp3(String url, HttpServletRequest req) {
       try {
           OSSObject oos = UploadImageUtils.getFile(url); //阿里存儲 具體根據自己的需要
           if (oos == null) {
               return null;
           }
           InputStream fis = oos.getObjectContent();
           String filePath = "/";
           String filen = url.substring(url.lastIndexOf("/") + 1, url.length());
           filen = filen.replaceAll(".amr", "");
           String realPathDir = req.getSession().getServletContext()
                   .getRealPath(filePath);
           File saveFile = new File(realPathDir);
           if (!saveFile.exists())
               saveFile.mkdirs();
           /** 獲取文件的後綴* */
           String suffixAmr = ".amr";
           String suffixMp3 = ".mp3";
           String srcNameEnd = filen + suffixAmr;// 構建文件名稱
           String targetNameEnd = filen + suffixMp3;// 構建文件名稱
           /** 拼成完整的文件保存路徑加文件* */
           String srcName = realPathDir + srcNameEnd;
           String targetName = realPathDir + targetNameEnd;
           try {
               getFileFromInputStream(fis, srcName);
               boolean result = AmrToMp3.convertToMp3(srcName, targetName);
               File source = new File(srcName);
               if (source != null && source.exists()) source.delete();
               if (result) {
                   return targetName;
               }

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

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

/**
 * amr 文件轉換MP3
 *
 * @param target
 * @param req
 * @param resp
 * @return
 */
public static boolean getMp3Resp(String target, HttpServletRequest req, HttpServletResponse resp) {
    try {
        File targetFile = new File(target);
        InputStream f = new BufferedInputStream(new FileInputStream(targetFile));
        byte[] buffer = new byte[f.available()];
        f.read(buffer);
        f.close();
        resp.addHeader("Content-Disposition", "attachment;filename="+target+".mp3");
        resp.addHeader("Content-Length", "" + targetFile.length());
        OutputStream ous = new BufferedOutputStream(resp.getOutputStream());
        resp.setContentType("application/octet-stream");
        ous.write(buffer);
        ous.flush();
        ous.close();
        if (targetFile != null && targetFile.exists()) targetFile.delete();
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

/**
 * 從流中寫出文件
 *
 * @param inStream
 * @param imageFileStr
 * @throws Exception
 */
public static void getFileFromInputStream(InputStream inStream, String imageFileStr) throws Exception {
    //new一個文件對象用來保存圖片,默認保存當前工程根目錄
    File imageFile = new File(imageFileStr);
    //創建輸出流
    FileOutputStream out = new FileOutputStream(imageFile);
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    //創建一個Buffer字符串
    byte[] buffer = new byte[1024];
    //每次讀取的字符串長度,如果爲-1,代表全部讀取完畢
    int len = 0;
    //使用一個輸入流從buffer裏把數據讀取出來
    while ((len = inStream.read(buffer)) != -1) {
        //用輸出流往buffer裏寫入數據,中間參數代表從哪個位置開始讀,len代表讀取的長度
        out.write(buffer, 0, len);
    }
    //關閉輸入流
    inStream.close();
    //關閉輸出流
    out.close();

}
控制層的調用:

/**
    * 轉換語音
    */
   @RequestMapping("/amrToMp3")
   public
   @ResponseBody
   Object amrToMp3(@RequestParam(value = "url", required = false) String url,
                   HttpServletRequest req, HttpServletResponse resp) {
       MsgBean msg = new MsgBean();
       if (StringUtils.isBlank(url)) {
           msg.setFailure(1, "視頻播放地址不存在!");
           return msg.returnMsg();
       }
       if (!url.contains("amr")) {
           msg.setFailure(1, "視頻文件有問題,無法播放!");
           return msg.returnMsg();
       }
       String result = FileUtils.amrSwitchToMp3(url, req);
       if (result != null && !"".equals(result)) {
           msg.put("url", result);
       } else {
           msg.setFailure(1, "視頻文件地址出錯,無法播放!");
           return msg.returnMsg();
       }
       return msg.returnMsg();
   }

/**
 * 播放語音
 */
@RequestMapping("/playMp3")
public
@ResponseBody
Object playMp3(@RequestParam(value = "url", required = false) String url,
               HttpServletRequest req, HttpServletResponse resp) {
    if (StringUtils.isBlank(url)) {
        return null;
    }
    return FileUtils.getMp3Resp(url, req, resp);
}

前端js

function  amrToMp3(id,url,btn){
    var path = "${BasePath}/chatReport/amrToMp3?url=" + url;
    $.ajax({
        type: "POST",
        url: path,
        datatype: "json",
        success: function (data) {
            if (data.errno == 1) {
                alert(data.errdesc);
            } else {
                play(id,data.url,btn);
            }
        },
        error: function () {
            alert("操作出錯,請聯繫管理員!");
        }
    });
}
    function  play(id,url,btn){
        var audio = document.getElementById('audio_'+id);
        if(btn.innerHTML=="播放"){
            audio.src="${BasePath}/chatReport/playMp3?url=" + url;
        }
        playOrPaused(audio,btn);
        var is_playFinish=  setInterval(function(){
            if(audio.ended){
             //   btn.innerHTML=="暫停"
            }
                //callback(audio,btn);
                window.clearInterval(is_playFinish);
        },1);
    }
    function  callback(audio,btn){
        // audio.play();
        playOrPaused(audio,btn);
    }
    function playOrPaused(id,obj){
        if(id.paused){
            id.play();
            obj.name="";
           // obj.innerHTML='暫停';
            return;
        }
        id.pause();
        obj.innerHTML='播放';
    }
HTML代碼:
<audio controls="controls" autoplay="autoplay"  id="audio_${obj.id }"  src=""   >
    您的瀏覽器不支持 audio 標籤
</audio>
<button    class="btn btn-danger btn-small"  name= "b1"  onclick="amrToMp3(${obj.id },'${obj.content.url}',this )">播放</button>

2: 線上安裝ffmpeg工具 centos redhat

(一)安裝編譯環境
#yum install -y automake autoconf libtool gcc gcc-c++
(二)安裝所需程序庫的RPM包到 centos(因爲centos自帶的庫中沒有ffmpeg包,這裏相當於是擴展)
#rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

如果這一步失敗可以將地址“http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm ”下載到電腦,然後直接運行下面的也可以
#rpm -Uhv rpmforge-release-0.3.6-1.el5.rf.i386.rpm
共享一個RPM包下載鏈接
(三)安裝 Install ffmpeg 等模塊
yum -y install ffmpeg ffmpeg-devel
方法二、此方法有時不太好用
1.安裝前準備
vi /etc/yum.repos.d/ffmpeg.repo
[dag]
name=Dag RPM Repository for Red Hat Enterprise Linux
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=0
enabled=1
2.安裝ffmpeg
yum -y install ffmpeg ffmpeg-devel

注意:網上好多安裝 諸如此類 參考即可 要求安裝最新版本各個交叉編譯比較繁瑣 其實低版本即可

—————————————-華麗的分割線—————————————–

   FFmpeg在Linux下的安裝
        在Redhat 9.0成功安裝了ffmpeg,現記錄如下。
        1、下載ffmpeg。
        http://download.chinaunix.net/download.php?id=5532&ResourceID=2990
        我是在這個網址上下載ffmpeg-0.4.9-p20051120.tar.bz2,看網上有人用的是svn下載,但是我的機子中沒有svn客戶端,然後就在網上搜索,下載了這個版本。如果利用svn可以下載ffmpeg最新的版本。
        svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
        2、解壓
        tar xvfj ffmpeg-0.4.9-p20051120.tar.bz2
        得到解壓後的目錄是ffmpeg-0.4.9-p20051120,名字太長,利用mv命令改爲ffmpeg
        mv ffmpeg-0.4.9-p20051120.tar.bz2 ffmpeg
        3、配置
        ./configure --enable-shared --prefix=/usr/local/ffmpeg
        其中:--enable-shared 是允許其編譯產生動態庫,在以後的編程中要用到這個幾個動態庫。--prefix設置的安裝目錄。
        4、編譯並安裝
        make
        make install
        5、安裝之後在/usr/local/ffmpeg會看到有三個目錄
        lib  動態鏈接庫位置
        include 編程要用到頭文件
        bin 執行文件所在的目錄
        6、爲了以後方便編程,我們把lib中的三個鏈接庫libavcodec.so libavformat.so libavutil.so複製到/usr/lib下。把include目錄下的ffmpeg目錄複製到/usr/include下。
        執行bin目錄下的ffplay,可以去播放音頻或者視頻文件。例如播放1.mp3
        ./ffplay 1.mp3
        另外,bin目錄下還有兩個文件:ffmpeg和ffserver
        ffmpeg是一個很好的視頻和音頻的格式轉化工具。網上有很多它的說明文檔。
        如果不想生成ffserver,只要在./configure的時候加--disable-ffserver即可。
        7、編程
        如果寫了一個test.c文件,要包含ffmpeg的頭文件,可以這樣寫:
        #include <ffmpeg/avcodec.h>
        編譯:gcc -o test test.c -lavformat -lavcodec -lavtuil (前提是有第6步的操作)
        如果沒有第6部的操作,則編譯的時候如下:
        gcc -o test test.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib  -lavformat
        -lavcodec -lavtuil
        說明:-I是指明需要的頭文件所在的文件,-L是指明動態庫所在的目錄,後面三個是指明需要的動態庫。
        編譯成功之後,執行的時候還是需要動態庫的支持,還是要把那三個動態庫文件複製到/usr/lib或者/lib中,不然執行的時候會說找不到動態庫鏈接。還有一個方法可以解決這個問題,就是把/usr/local/ffmpeg/lib這個目錄加入到/etc/ld.so.config中,然後執行ldconfig,或者重啓電腦,這樣執行的時候系統就可以從/usr/local/ffmpeg/lib這個目錄下去找這三個動態庫文件了。

        以上的方式是採用動態庫編譯ffmpeg的,如果在configure的時候不加上--enable-shared的,則採用靜態鏈接的方式,不會生成那三個動態庫。同時生成的ffplay、ffmpeg的執行文件也比較的大,因爲他們不需要動態庫的支持,就可以執行。但是不利於再次開發,所以我採用動態鏈接的方式。configure中還有很多的選項,可以通過./configure --help查看,也可以直接查看configure文件。這在配置的時候很重要。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章