近期需要做音轨合成这样一个功能,何为音轨合成,说白了就是N个音频文件合成一个,同时播放N个声音。然而网上各种找代码,并没有一个能用的,最后终于找到一个外国大神写的合音工具类,稍加修改便成了自己的东西,现在分享出来,方便大家使用。

模拟器没办法录音,所以这里先只提供一张效果图

我这里做的效果是点击开始录音开始录制声音,停止后将该录音文件存储在sd卡,并在中间的ListViw显示名字,点击item选中多条后,即可开始合音

先来说一下步骤,

1.录音并将录音文件存储在sd卡下

2.解码

3.合音

从大的方向来讲,要实现这里的效果只需以上三步

我这里使用的MediaRecorder录音,首先,点击按钮后开始录音:

MediaRecorder mRecorder = new MediaRecorder();
mRecorder.reset();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置声音来源
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 设置所录制的音视频文件的格式
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 设置所录制的声音的编码格式
mRecorder.setAudioEncodingBitRate(96000);// 比特率
mRecorder.setAudioChannels(2);// 通道
mRecorder.setAudioSamplingRate(44100);// 采样率
mRecorder.setOutputFile(recordFile.getAbsolutePath() + "/record"+ count + ".mp4");// 设置录制的音频文件的保存位置
try {mRecorder.prepare();
} catch (IOException e) {e.printStackTrace();
}
mRecorder.start();

这里需要注意的是:

1.要合音的文件格式必须相同,比如必须都是MP4或都是MP3,否则合出来的音会像卡带了一样

2.采样率、通道、精度必须相同,有一个参数不同都会影响到合出来的效果

3.做的时候还遇到一个问题,设置采样率、通道、比特率的代码必须放在setOutputFormat后面,如果放在setOutputFormat前面,合出来的音也是有问题的。至于这个为什么, 我暂时也没有找到答案,当时因为这个问题困扰了很久,无意间放到setOutputFormat后面才意外成功

录音结束后,将文件名字添加到List中,来充当ListView的数据

mRecorder.stop();
mRecorder = null;
RecordBean bean = new RecordBean();
bean.setId(count);
bean.setName(count + ".mp4");
bean.setState(0);
bean.setPath(recordFile.getAbsolutePath() + "/record" + count + ".mp4");
list.add(bean);
adapter.setList(list);

接下来,就是选择录音的文件并进行解码,将解码后的文件存在sd卡,合音时,将解码后的文件进行合音。

解码:

/*** 解码* */class DecodeTask extends AsyncTask<Void, Double, Boolean> {private String fileUrl;private int position;DecodeTask(String url, int p) {fileUrl = url;position = p;}@Overrideprotected Boolean doInBackground(Void... params) {try {// 解码后的路径String decodeFilePath = decodeFile.getAbsolutePath()+ "/decode" + MD5Util.getMD5Str(fileUrl);// 将解码后的路径保存在list中,方便后面取值list.get(position).setDecodePath(decodeFilePath);// 解码AudioDecoder audioDec = AudioDecoder.createDefualtDecoder(fileUrl);fileUrl = decodeFilePath;audioDec.decodeToFile(decodeFilePath);return true;} catch (IOException e) {e.printStackTrace();return false;}}@Overrideprotected void onPostExecute(Boolean result) {super.onPostExecute(result);dialog.cancel();}}

合音:

/*** 合音* */class MixTask extends AsyncTask<Void, Double, Boolean> {private int size;MixTask(int num) {size = num;}@Overrideprotected Boolean doInBackground(Void... params) {String rawAudioFile = null;// 将需要合音的音频解码后的文件放到数组里File[] rawAudioFiles = new File[size];StringBuilder sbMix = new StringBuilder();int index = 0;for (int i = 0; i < list.size(); i++) {if (1 == list.get(i).getState()) {rawAudioFiles[index++] = new File(list.get(i).getDecodePath());sbMix.append(i + "");}}// 最终合音的路径final String mixFilePath = mixFile.getAbsolutePath() + "/mix"+ MD5Util.getMD5Str(sbMix.toString());// 下面的都是合音的代码try {MultiAudioMixer audioMixer = MultiAudioMixer.createAudioMixer();audioMixer.setOnAudioMixListener(new OnAudioMixListener() {FileOutputStream fosRawMixAudio = new FileOutputStream(mixFilePath);@Overridepublic void onMixing(byte[] mixBytes) throws IOException {fosRawMixAudio.write(mixBytes);}@Overridepublic void onMixError(int errorCode) {try {if (fosRawMixAudio != null)fosRawMixAudio.close();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void onMixComplete() {try {if (fosRawMixAudio != null)fosRawMixAudio.close();} catch (IOException e) {e.printStackTrace();}}});audioMixer.mixAudios(rawAudioFiles);rawAudioFile = mixFilePath;} catch (FileNotFoundException e) {e.printStackTrace();}AudioEncoder accEncoder = AudioEncoder.createAccEncoder(rawAudioFile);String finalMixPath = mixFile.getAbsolutePath() + "/finalMix.aac";accEncoder.encodeToFile(finalMixPath);return true;}@Overrideprotected void onPostExecute(Boolean result) {super.onPostExecute(result);Toast.makeText(getApplicationContext(), "合音成功", Toast.LENGTH_SHORT).show();dialog.cancel();}}

最后合成的声音,可以在sdcard/merge/mix/中找到,叫finalMix.aac,可以点击播放试一下

Demo中只是实现该操作,有些东西没有加,如判断sd卡、判断权限是否关闭等,这些实际操作中切勿忘记自行加上

由于所需要的类还是比较多的,这里不能贴上全部代码,有需要的可自行下载Demo:http://download.csdn.net/detail/qq_18612815/9529622

Demo中重要的地方我都加了注释,基本都能看得懂

本篇讲的是音轨合成,接下来的几篇会增加音轨拼接、音轨与视频合成,有需要的加个关注,方便get

刚刚发现了一个bug,Demo中  RecordWithRecordActivity  199行应改为 new MixTask(num).execute();,之前写demo时候测试把num写成2固定死了,所以如果选择超过2个文件就会崩...

转载请注明来自http://blog.csdn.net/qq_18612815



Android多媒体(一) 音轨合成 我用双手成就你的梦想相关推荐

  1. 英雄联盟:英雄台词翻译(我用双手成就你的梦想。)

    英雄联盟:英雄台词翻译(我用双手成就你的梦想.) 一.总结 一句话总结:李青:Your will,my hands. Your will my hands 1.一点寒芒先到,然后枪出如龙!? 德邦: ...

  2. 【PS功能学习】01:我用双手实现你的梦想

    第1节:我用双手成就你的梦想(前言) 课程简介: 本节学习目标: 1.软件介绍: (1)PS的应用: 广告设计: 摄影后期: 电商网页: UI界面设计: (2)AI的应用: (3)ID的应用: 2.新 ...

  3. android开发高级开发,Android多媒体开发高级编程 (Shawn Van Every) pdf扫描版

    <android多媒体开发高级编程--为智能手机和平板电脑开发图形.音乐.视频和富媒体应用>使用清晰.直观的示例介绍了android sdk中丰富的多媒体功能,有助于您开发能够创建.播放和 ...

  4. android编程高级教程 pdf,Android多媒体开发高级编程

    在多媒体功能方面,今天的手机同时是照相机.相册.摄像机.电影播放器.音乐播放器.听写机,且可能具备更多功能. 特别是,Android在SDK中具有非常丰富的功能,本书将试图通过讨论和实例对该SDK进行 ...

  5. Android 多媒体之音频----(日积月累)

    在开发上,习惯的将音频.视频功能的使用称之为多媒体,实际上如果讲的宽泛一些的话,相机的使用,比如拍照,录制视频等,也可以划分到多媒体的范畴里面. 从本节课开始,我们就来看看Android中多媒体的AP ...

  6. Android多媒体开发介绍

    Android多媒体开发介绍 一.       多媒体架构 基于第三方PacketVideo公司的OpenCORE来实现,支持所有通用的音频/视频/静态图像格式,包括:MPEG4.H.264.MP3. ...

  7. Android 多媒体之音频

    在开发上,习惯的将音频.视频功能的使用称之为多媒体,实际上如果讲的宽泛一些的话,相机的使用,比如拍照,录制视频等,也可以划分到多媒体的范畴里面. 从本节课开始,我们就来看看Android中多媒体的AP ...

  8. Android 多媒体综述

    Android 多媒体综述 多媒体系统是Android中最为庞大的系统,涉及了硬件抽象层.编解码.OpenCore多媒体框架.Android多媒体框架.Java层接口多方面的内容. 一.引言 本系列内 ...

  9. Android多媒体之GLES2战记第四集--移形换影

    视野限制了人对这个宇宙的认知,但没有视野,人将会一无所知 上集说到勇者坠入黑暗之渊,凭借对世界的认知构建出了世界系 到此为止,OpenGL的世界观已经映入脑海,新手十二副本已经通过 接下来等待他们的将 ...

最新文章

  1. JQuery中each()的使用方法说明
  2. 强弩之末,势不能穿鲁缟
  3. html div转换图片
  4. 2014_anshan_onsite
  5. Cocos Studio 2.3.2不再支持直接导入PSD文件
  6. 雅思作文模板.html,雅思小作文常用模板万能句大全
  7. Ajax Control Toolkit--Slider:有朝一日倒过来
  8. css中em单位和rem单位
  9. java jxl 复制单元格_如何用JAVA(如poi、jxl等)读取excel文件中的下拉框单元格的值。...
  10. Alex Chen:3月21日阿里云北京峰会演讲大神
  11. 安全教育平台账号后四位_安全教育平台登录账号是什么?
  12. mybatis执行sql脚本
  13. 【硬刚Hive】MYSQL/HIVESQL笔试题(七):HIVESQL(七)
  14. 红外接收电路自己制作,我用过的
  15. linux加密狗复制克隆教程,圣天狗SentinelDog
  16. OpenKG开源系列 | 轻量级知识图谱抽取开源工具OpenUE
  17. 简单是王道《九、讲故事》
  18. U8 8.9 数据库置疑恢复方法
  19. 项目实战:如何构建知识图谱
  20. PointNet++理解(PointNet++实现第2步)

热门文章

  1. java excel打印_技巧(excel,excel使用java打印输出)
  2. 面向对象系统分析与设计,让你真正了解什么是面向对象(傻瓜式讲解)
  3. MATLAB 数学应用 微分方程 边界值问题 使用延拓求解BVP问题
  4. iwara_php,iwara里版mmd怎么下载_iwara里版mmd资源下载方法_软件侠下载站
  5. 力扣一日一练(5)——最长公共前缀
  6. 下载docker-compose太慢解决方式
  7. IBM故障灯报警指示
  8. Complete Internet Repair修复选项
  9. 两台路由器LAN-WAN级联,两台路由器下面的电脑能否互访
  10. linux 之nginx