默認
發表評論 10
想開發IM:買成品怕坑?租第3方怕貴?找開源自已擼?盡量別走彎路了... 找站長給點建議
分享java AMR音頻文件合并源碼,全網最全
閱讀(15649) | 評論(10 收藏6 淘帖 2
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

public class AudioUtils {
        public static void uniteAMRFile(String[] partsPaths, String unitedFilePath) {
                try {
                        File unitedFile = new File(unitedFilePath);
                        FileOutputStream fos = new FileOutputStream(unitedFile);
                        RandomAccessFile ra = null;
                        for (int i = 0; i < partsPaths.length; i++) {
                                ra = new RandomAccessFile(partsPaths[i], "r");
                                if (i != 0) {
                                        ra.seek(6);
                                }
                                byte[] buffer = new byte[1024 * 8];
                                int len = 0;
                                while ((len = ra.read(buffer)) != -1) {
                                        fos.write(buffer, 0, len);
                                }
                        }
                        ra.close();
                        fos.close();
                } catch (Exception e) {
                }
        }

        public static boolean merge(String[] files, String outPath) {

                // Merge files
                try {
                        FileOutputStream fos = new FileOutputStream(outPath);
                        for (int i = 0, len = files.length; i < len; i++) {
                                File file = new File(files[i]);
                                FileInputStream fis = new FileInputStream(file);
                                // Skip file header bytes,
                                // amr file header's length is 6 bytes
                                if (i > 0) {
                                        for (int j = 0; j < 6; j++) {
                                                fis.read();
                                        }
                                }
                                byte[] buffer = new byte[512];
                                int count = 0;
                                while ((count = fis.read(buffer)) != -1) {
                                        fos.write(buffer, 0, count);
                                }

                                fis.close();
                                fos.flush();
                                file.delete();
                        }

                        fos.flush();
                        fos.close();

                        return true;
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }

                return false;
        }

        /**
         * 合并AMR文件 ,
         * 
         * @param files
         *            需要合成的兩個文件
         * @param outPath
         *            輸出路徑
         * @param ifDeleteOld
         *            是否刪除合成之前的文件,
         */
        public static void amrCatch(String[] files, String outPath, boolean ifDeleteOld) {
                File outPutFile = new File(outPath);

                if (!outPutFile.exists()) {
                        try {
                                outPutFile.createNewFile();
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                }
                FileOutputStream fileOutPutStream = null;
                try {
                        fileOutPutStream = new FileOutputStream(outPutFile);
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                for (int i = 0; i < files.length; i++) {
                        File file = new File(files[i]);
                        try {
                                FileInputStream fileInputStream = new FileInputStream(file);
                                byte[] fileByte = new byte[fileInputStream.available()];
                                int fileLength = fileByte.length;
                                if (i == 0) {
                                        while (fileInputStream.read(fileByte) != -1) {
                                                fileOutPutStream.write(fileByte, 0, fileLength);

                                        }
                                } else {
                                        while (fileInputStream.read(fileByte) != -1) {
                                                fileOutPutStream.write(fileByte, 6, fileLength - 6);

                                        }
                                }
                                fileOutPutStream.flush();
                                fileInputStream.close();
                        } catch (FileNotFoundException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }

                }
                try {
                        fileOutPutStream.close();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                if (ifDeleteOld) {
                        for (int i = 0; i < files.length; i++) {
                                File file = new File(files[i]);
                                if (file.exists()) {
                                        file.delete();
                                }
                        }
                }

        }

        /**
         * 通過FileChannel方式
         */
        public static void mergeFiles2(String[] tempFiles, String realFile) {
                FileChannel mFileChannel;
                try {
                        FileOutputStream fos = new FileOutputStream(realFile);
                        mFileChannel = fos.getChannel();
                        FileChannel inFileChannel;
                        for (String file : tempFiles) {
                                inFileChannel = new FileInputStream(file).getChannel();
                                // 下面應該根據不同文件減去相應的文件頭(這里沒有剪去文件頭,實際應用中應當減去)
                                inFileChannel.transferTo(0, inFileChannel.size(), mFileChannel);
                                inFileChannel.close();
                        }
                        fos.close();
                        mFileChannel.close();
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }

        public static void mergeFiles3(String[] tempFiles, String realFile) {
                try {
                        FileOutputStream fos = new FileOutputStream(realFile);
                        RandomAccessFile ra = null;
                        for (int i = 0; i < tempFiles.length; i++) {
                                ra = new RandomAccessFile(tempFiles[i], "r");
                                if (i != 0) {
                                        ra.seek(6);// 跳過amr文件的文件頭
                                }
                                byte[] buffer = new byte[1024 * 8];
                                int len = 0;
                                while ((len = ra.read(buffer)) != -1) {
                                        fos.write(buffer, 0, len);
                                }
                        }
                        ra.close();
                        fos.close();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
        @SuppressWarnings("unused")
        public static void mergeFiles4(String[] tempFiles) {
                try {
                        String originalVoiceMessageRecording = tempFiles[0];
                        String newVoiceMessageRecording = tempFiles[1];
                        File outputFile = new File(originalVoiceMessageRecording);
                        FileOutputStream fos = new FileOutputStream(outputFile, true);
                        File inputFile = new File(newVoiceMessageRecording);
                        FileInputStream fis = new FileInputStream(inputFile);

                        byte fileContent[] = new byte[(int) inputFile.length()];
                        fis.read(fileContent);
                        byte[] headerlessFileContent = new byte[fileContent.length - 6];
                        for (int j = 6; j < fileContent.length; j++) {
                                headerlessFileContent[j - 6] = fileContent[j];
                        }
                        fileContent = headerlessFileContent;

                        /* Write the byte into the combine file. */
                        fos.write(fileContent);

                        File file = new File(newVoiceMessageRecording);
                
                        boolean deleted = file.delete();

                } catch (Exception ex) {
                        ex.fillInStackTrace();
                }
        }
}

附錄:全站精品資源下載


[1] 精品源碼下載:
輕量級即時通訊框架MobileIMSDK的iOS源碼(開源版)[附件下載]
開源IM工程“蘑菇街TeamTalk”2015年5月前未刪減版完整代碼 [附件下載]
微信本地數據庫破解版(含iOS、Android),僅供學習研究 [附件下載]
NIO框架入門(四):Android與MINA2、Netty4的跨平臺UDP雙向通信實戰 [附件下載]
NIO框架入門(三):iOS與MINA2、Netty4的跨平臺UDP雙向通信實戰 [附件下載]
NIO框架入門(二):服務端基于MINA2的UDP雙向通信Demo演示 [附件下載]
NIO框架入門(一):服務端基于Netty4的UDP雙向通信Demo演示 [附件下載]
用于IM中圖片壓縮的Android工具類源碼,效果可媲美微信 [附件下載]
高仿Android版手機QQ可拖拽未讀數小氣泡源碼 [附件下載]
一個WebSocket實時聊天室Demo:基于node.js+socket.io [附件下載]
Android聊天界面源碼:實現了聊天氣泡、表情圖標(可翻頁) [附件下載]
高仿Android版手機QQ首頁側滑菜單源碼 [附件下載]
開源libco庫:單機千萬連接、支撐微信8億用戶的后臺框架基石 [源碼下載]
分享java AMR音頻文件合并源碼,全網最全
微信團隊原創Android資源混淆工具:AndResGuard [有源碼]
一個基于MQTT通信協議的完整Android推送Demo [附件下載]
Android版高仿微信聊天界面源碼 [附件下載]
仿微信的IM聊天時間顯示格式(含iOS/Android/Web實現)[圖文+源碼]

[2] 精品文檔和工具下載:
計算機網絡通訊協議關系圖(中文珍藏版)[附件下載]
史上最全即時通訊軟件簡史(精編大圖版)[附件下載]
基于RTMP協議的流媒體技術的原理與應用(技術論文)[附件下載]
獨家發布《TCP/IP詳解 卷1:協議》CHM版 [附件下載]
良心分享:WebRTC 零基礎開發者教程(中文)[附件下載]
MQTT協議手冊(中文翻譯版)[附件下載]
經典書籍《UNIX網絡編程》最全下載(卷1+卷2、中文版+英文版)[附件下載]
音視頻開發理論入門書籍之《視頻技術手冊(第5版)》[附件下載]
國際電聯H.264視頻編碼標準官方技術手冊(中文版)[附件下載]
Apache MINA2.0 開發指南(中文版)[附件下載]
網絡通訊數據抓包和分析工具 Wireshark 使用教程(中文) [附件下載]
最新收集NAT穿越(p2p打洞)免費STUN服務器列表 [附件下載]
高性能網絡編程經典:《The C10K problem(英文)》[附件下載]
即時通訊系統的原理、技術和應用(技術論文)[附件下載]
技術論文:微信對網絡影響的技術試驗及分析[附件下載]
華為內部3G網絡資料: WCDMA系統原理培訓手冊[附件下載]
網絡測試:Android版多路ping命令工具EnterprisePing[附件下載]
Android反編譯利器APKDB:沒有美工的日子里繼續堅強的擼
一款用于P2P開發的NAT類型檢測工具 [附件下載]
兩款增強型Ping工具:持續統計、圖形化展式網絡狀況 [附件下載]

[3] 精選視頻、演講PPT下載:
QQ空間移動端10億級視頻播放技術優化揭秘(視頻+PPT)[附件下載]
RTC實時互聯網2017年度大會精選演講PPT [附件下載]
微信分享開源IM網絡層組件庫Mars的技術實現(視頻+PPT)[附件下載]
微服務理念在微信海量用戶后臺架構中的實踐(視頻+PPT)[附件下載]
移動端IM開發和構建中的技術難點實踐分享(視頻+PPT)[附件下載]
網易云信的高品質即時通訊技術實踐之路(視頻+PPT)[附件下載]
騰訊音視頻實驗室:直面音視頻質量評估之痛(視頻+PPT)[附件下載]
騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT[附件下載]
微信朋友圈海量技術之道PPT[附件下載]
手機淘寶消息推送系統的架構與實踐(音頻+PPT)[附件下載]
如何進行實時音視頻的質量評估與監控(視頻+PPT)[附件下載]
Go語言構建高并發消息推送系統實踐PPT(來自360公司)[附件下載]
網易IM云千萬級并發消息處理能力的架構設計與實踐PPT [附件下載]
手機QQ的海量用戶移動化實踐分享(視頻+PPT)[附件下載]
釘釘——基于IM技術的新一代企業OA平臺的技術挑戰(視頻+PPT)[附件下載]
微信技術總監談架構:微信之道——大道至簡(PPT講稿)[附件下載]
Netty的架構剖析及應用案例介紹(視頻+PPT)[附件下載]
聲網架構師談實時音視頻云的實現難點(視頻采訪)
滴滴打車架構演變及應用實踐(PPT講稿)[附件下載]
微信海量用戶背后的后臺系統存儲架構(視頻+PPT)[附件下載]
在線音視頻直播室服務端架構最佳實踐(視頻+PPT)[附件下載]
從0到1:萬人在線的實時音視頻直播技術實踐分享(視頻+PPT)[附件下載]
微信移動端應對弱網絡情況的探索和實踐PPT[附件下載]
Android版微信從300KB到30MB的技術演進(PPT講稿)[附件下載]

即時通訊網 - 即時通訊開發者社區! 來源: - 即時通訊開發者社區!

評分

2

查看評分

上一篇:NIO框架入門(四):Android與MINA2、Netty4的跨平臺UDP雙向通信實戰 [附件下載]下一篇:聲網架構師談實時音視頻云的實現難點(視頻采訪)
推薦方案
評論 10
感謝樓主分享。

能否把這篇內容增加以下內容,這樣就讓你分享的東西讓更多人理解,也就更有價值了:
1)為何要進行java AMR文件合并,用在什么樣的場景下?
2)以上代碼可以用在什么平臺?標準java平臺還是Android平臺?
3)java AMR文件合并的技術原理是什么?你是如何辦到的?
4)java AMR文件合并遇到過什么樣的難題嗎?你是如何解決的?
5)如何調用你的代碼?能否給個簡單的示例?

以上是我的建議,再次感謝分享!
簽名: 《主流移動端賬號登錄方式的原理及設計思路》http://www.uktmgv.tw/thread-2863-1-1.html
引用:JackJiang 發表于 2016-07-01 12:02
感謝樓主分享。

能否把這篇內容增加以下內容,這樣就讓你分享的東西讓更多人理解,也就更有價值了:

是的,如果樓主能描述的更詳細一點就更好了,我也想知道amr合并是基于什么需求考慮,頂原創。
簽名: 星期六,那又怎樣,還是得上班
雖然現在用不上,但這樣的代碼很難找,先收了,感謝!
引用:只是路過 發表于 2016-07-01 12:04
是的,如果樓主能描述的更詳細一點就更好了,我也想知道amr合并是基于什么需求考慮,頂原創。

我們我們平時做這個錄音的時候,有的時候需要斷點錄音,就是加入暫停恢復,或者業務數據一會兒停一下,一會兒停一下,這時候用這個可以減少上傳資源的大小,
簽名: 17 小時前 (Lv9)以壇為家II
引用:瘋華整貓 發表于 2016-07-01 12:47
我們我們平時做這個錄音的時候,有的時候需要斷點錄音,就是加入暫停恢復,或者業務數據一會兒停一下,一 ...

建議逐條回復我的問題然后補到你的帖子里哦
簽名: 《主流移動端賬號登錄方式的原理及設計思路》http://www.uktmgv.tw/thread-2863-1-1.html
引用:JackJiang 發表于 2016-07-01 12:02
感謝樓主分享。

能否把這篇內容增加以下內容,這樣就讓你分享的東西讓更多人理解,也就更有價值了:

感謝站長,其實我這個還真沒想到,其實這只是一個工具類,所以我也沒想怎么搞,就分享了,這個也是我從國內的論壇和國外的論壇,開源項目里面挖的,真沒想那么多,如果涉及到一些有趣的事情,有些深度的還好,但是這種應該不是很有必要了吧,都是直接使用的
簽名: 17 小時前 (Lv9)以壇為家II
感謝樓主分享
我做個類似需求,就是長按發送語音消息時手指移出button范圍后錄音暫停,重新回到button里后繼續錄音,其實很簡單,暫停后重新錄音時往之前的臨時錄音文件繼續添加amr數據就行。見代碼188行:https://coding.net/u/coding/p/Co ... rAudioRecorder.java
好文章 學習了
感謝樓主分享
簽名: 很好非常的很好
打賞樓主 ×
使用微信打賞! 使用支付寶打賞!

返回頂部
曾氏料二肖中特