默认
发表评论 10
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
分享java AMR音频文件合并源码,全网最全
阅读(78006) | 评论(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)如何调用你的代码?能否给个简单的示例?

以上是我的建议,再次感谢分享!
引用:JackJiang 发表于 2016-07-01 12:02
感谢楼主分享。

能否把这篇内容增加以下内容,这样就让你分享的东西让更多人理解,也就更有价值了:

是的,如果楼主能描述的更详细一点就更好了,我也想知道amr合并是基于什么需求考虑,顶原创。
签名: 星期六,那又怎样,还是得上班
虽然现在用不上,但这样的代码很难找,先收了,感谢!
引用:只是路过 发表于 2016-07-01 12:04
是的,如果楼主能描述的更详细一点就更好了,我也想知道amr合并是基于什么需求考虑,顶原创。

我们我们平时做这个录音的时候,有的时候需要断点录音,就是加入暂停恢复,或者业务数据一会儿停一下,一会儿停一下,这时候用这个可以减少上传资源的大小,
签名: 17 小时前 (Lv9)以坛为家II
引用:疯华整猫 发表于 2016-07-01 12:47
我们我们平时做这个录音的时候,有的时候需要断点录音,就是加入暂停恢复,或者业务数据一会儿停一下,一 ...

建议逐条回复我的问题然后补到你的帖子里哦
引用:JackJiang 发表于 2016-07-01 12:02
感谢楼主分享。

能否把这篇内容增加以下内容,这样就让你分享的东西让更多人理解,也就更有价值了:

感谢站长,其实我这个还真没想到,其实这只是一个工具类,所以我也没想怎么搞,就分享了,这个也是我从国内的论坛和国外的论坛,开源项目里面挖的,真没想那么多,如果涉及到一些有趣的事情,有些深度的还好,但是这种应该不是很有必要了吧,都是直接使用的
签名: 17 小时前 (Lv9)以坛为家II
感谢楼主分享
我做个类似需求,就是长按发送语音消息时手指移出button范围后录音暂停,重新回到button里后继续录音,其实很简单,暂停后重新录音时往之前的临时录音文件继续添加amr数据就行。见代码188行:https://coding.net/u/coding/p/Co ... rAudioRecorder.java
好文章 学习了
感谢楼主分享
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部