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

NO IMAGE

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檔案。這在配置的時候很重要。