在Android中处理音频方面的知识一直是一块很重要的知识,正好最近公司做一个关于打卡的内容,所以正好总结一下相应的知识,其实这块的知识挺杂挺乱的,所以这个不打算一次讲解完,分开给大家讲解,如果有什么不对的,希望大家一起讨论下!怎么突然感觉自己正经起来挺可笑的呢?哈哈!!!

先唠叨一下关于平时开发时候的一个细节,我也是最近才觉得这个东西比较有用的!什么呢?大家平时接到任务的时候怎么着手开发的呢?说简单点,当你开始敲代码的时候是怎么开始的!最近我看见我同事有一个很好的习惯,他每次开始敲代码的时候,先拿张纸写下来,然后简单分析一下,其实我平时也这样。但是重点不在这里,每次我分析完了就直接写代码了?然后又什么BUG改什么BUG。他不是,他写每一个页面都先搭一个架子,把具体的每一块代码都分工明确,其实就是把方法都抽解出来,他还和我说,这样做的好处是如果你某一块代码不会写的话,找别人写就OK了,不会对自己的内容产生影响!其实我感觉这种做法是很好的,所以和大家分享一下!!!如果你有什么更好的方案,不妨分享一下!!!

关于音频的内容包括一下的知识点:

处理方式 文件方式 字节流方式
录制音频 MediaRecorder AudioRecord
播放音频 MediaPlayer AudioTrack

因为这里面每个内容都涉及到很多内容,所以这里准备一块一块去讲!感觉这样总结的话,还能讲的更加透彻一点

本文知识点


  • MediaRecorder录制音频

1. MediaRecorder录制音频

MediaRecorder录制音频是不保证线程安全的。其次,MediaRecorder采集音频是以文件的形式保存的,所以你可以不用去考虑相应的字节写入问题,这点比较简单。其他的知识我会在后面使用到的时候进行讲解!

1.1 MediaRecoeder录制音频注意的一些问题

当我们录制音频的时候要考虑以下几个问题?

  • 录制音频的时候在那个线程执行?如果不是在主线程执行的话,怎么保证状态的及时更新?
  • MediaRecorder录制开始时有哪些设置?
  • 出现的异常怎么解决?
  • 录制音频的时候用户按下HOME键怎么处理?
  • 用户退出页面需要哪些操作?
  • 录制音频文件的名称需要注意什么?

以上这些问题都是我们需要考虑的!其实简单的实现录音的话相对简单一些,但是如果所有的问题都加到一块的话,就比较复杂了!!!我们还是一点一点开始说吧

1.2 开始录制音频的准备

为了能给大家讲解明白!所以我觉得我还是由必要唠叨几句,强烈建议大家把架子先搭建好!养成了这样的习惯可以让你在一个月甚至更长的时间回头看代码的时候,最起码不会说!这他妈是谁写的代码?然后默默的看了署名居然是自己的!!!我现在在单位些代码,基本上都在最上面把里面要实现的内容大体写写,然后注释写的稍微多点,最起码在你以后离开公司的时候别人不会说你!!!相信我,有的时候公司之前写的代码,真的是看不懂!!!

权限千万别忘了

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
复制代码

首先先现象录制音频我们都需要什么?权限不能少吧!6.0权限的适配不能少吧?首先状态你不能少吧,反正很多东西要考虑!先说一下我的处理思路吧!我创建了一个线程去处理相应的音频录制,我通过一个按钮,在按下的时候开始录制音频,松开的时候停止录制音频,成功的话就保存相应的音频,如果时间小于3秒的话,就放弃保存文件(其实这里是删除了相应的文件,因为录制之前已经把文件路径传进去了,你录制多久都会有相应文件)!对了这里还有一个问题需要注意,就是录制文件的名称问题?我们项目在以前保存录制文件的名称是带有"-"的,像这样"2018-09-23-15:23:23"这种形式的,在大多数手机上是没有问题的,但是在OPPO手机上怎么也播放不出来,后来才知道有"-"就不行,后来干脆就直接用时间戳了,怎么也不会重复的!说了这么多,估计你也烦了,好吧!我先把基础的架子贴出来!!!

public class FileActivity extends AppCompatActivity {@BindView(R.id.tv_show)TextView mTvShow;@BindView(R.id.btn_start)TextView mBtnStart;@BindView(R.id.btn_play)TextView mBtnPlay;private ExecutorService mExecutorService;private Handler mMainHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_file);ButterKnife.bind(this);mMainHandler = new Handler(Looper.getMainLooper());mExecutorService = Executors.newSingleThreadExecutor();//对按钮进行监听mBtnStart.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://开始录音startRecord();break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL://停止录音stopRecord();break;}return true;}});}/*** 开始录音*/private void startRecord() {//更改UI的状态mBtnStart.setText("松手就可以停止录音");//开始录音mExecutorService.submit(new Runnable() {@Overridepublic void run() {//释放之前存在的资源,因为这里是按下的时候就开始录音,所以按下的时候一定要先释放相应的资源releaseResources();if (!doStart()) {//不成功弹Toast提示用户ToastFail();//提示用户}}});}/*** 提示用户失败信息*/private void ToastFail() {}/*** 开始录音是否成功,* 所以所有的逻辑就直接在这里去写了*/private boolean doStart() {return true;}/*** 停止录音*/private void stopRecord() {mBtnStart.setText("按下开始录音");mExecutorService.submit(new Runnable() {@Overridepublic void run() {if(!doStop()){ToastFail();}//这里停止后应该,释放相应的资源releaseResources();}});}/*** 停止录音*/private boolean doStop() {//这里说处理停止播放的逻辑return false;}/*** 释放资源*/private void releaseResources() {}@Overrideprotected void onDestroy() {super.onDestroy();//在主线程关闭的时候一定要停止线程,避免内存泄露mExecutorService.shutdownNow();}
}
复制代码

注释还是比较全的,相信大家一看就能看懂,看不懂的可以骚扰我!!!

1.3 MediaRecorder录制音频的设置

这里主要是设置MediaRecorder的一些配置,主要包括一下几个内容。

  • 创建MediaRecorder对象
  • 创建录音文件保存的位置
  • 配置MediaRecorder
  • 开始录音
  • 保存开始时间,因为这里要做时间判断,所以要记录开始时间

基本上就以上这些内容,这里要是展开讲太多,其实是我也不会!真的,没个流媒体工程师你能说你会?不可能的!

    /*** 开始录音是否成功,* 所以所有的逻辑就直接在这里去写了*/private boolean doStart() {/** 1.创建MediaRecorder对象* 2.创建相应的保存文件* 3.配置相应的MediaRecorder* 4.开始录音*/try {//创建mediaRecorder对象MediaRecorder recorder = new MediaRecorder();if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//创建保存的文件String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Video/" + System.currentTimeMillis() + ".m4a";mAudioFile = new File(path);mAudioFile.getParentFile().mkdirs();mAudioFile.createNewFile();/** 重点来了,配置MediaRecorder*///配置采集方式,这里用的是麦克风的采集方式recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//配置输出方式,这里用的是MP4,recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//配置采样频率,频率越高月接近原始声音,Android所有设备都支持的采样频率为44100recorder.setAudioSamplingRate(44100);//配置文件的编码格式,AAC是比较通用的编码格式recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//配置码率,这里一般通用的是96000recorder.setAudioEncodingBitRate(96000);//配置录音文件的位置recorder.setOutputFile(mAudioFile.getAbsolutePath());//开始录制音频recorder.prepare();//准备recorder.start();//开始录音/*因为这里要做相应的时间判断,所以要做时间的记录*/mStartRecordTime = System.currentTimeMillis();} else {//因为这里SD卡没有挂在,所以就直接返回false,如果你真的想在项目中使用的话,需要判断内存大小什么的,这里为了简便就没有写,//但是现在基本上都没事,因为手机内容都很大,但是如果做项目的话这些都要做的!return false;}} catch (IOException|RuntimeException e) {e.printStackTrace();return false;}return true;}
复制代码

我个人感觉已经写的很清楚了,你就这么整就一定能开始录制音频,别点赞。要脸!!!然后你在失败的ToastFail方法中随便提示点什么就可以了,但是有一点需要注意,你要注意,这个ToastFail方法是在线程中执行的,那么问题来了?怎么在主线程提示呢?眼尖的童鞋应该注意到我在最开始的时候定义了一个主线程的Handler,这个时候它就排上用场了!整体代码如下:

    /*** 提示用户失败信息*/private void ToastFail() {mAudioFile = null;mMainHandler.post(new Runnable() {@Overridepublic void run() {Toast.makeText(FileActivity.this, "录制音频失败", Toast.LENGTH_SHORT).show();}});}
复制代码

1.4 MediaRecorder停止录音的方法

其实这里的逻辑还是很简单的,基本上就是调用一个stop的方法,判断一下时间,和上面一样,需要注意线程的问题,做Android的应该都知道,在非UI线程里面修改UI会报异常的!!!代码就像这个样子!

    /*** 停止录音*/private boolean doStop() {try {//这里说处理停止播放的逻辑mMediaRecorder.stop();//因为这里要判断相应的时间,如果大于三秒就直接保存,否则删除文件mEndRecordTime = System.currentTimeMillis();final int time = (int) ((mEndRecordTime - mStartRecordTime) / 1000);if (time > 3) {mMainHandler.post(new Runnable() {@Overridepublic void run() {String des = "录音成功" + time + "秒";mTvShow.setText(des);}});} else {if (mAudioFile.exists()) {mAudioFile.delete();}mMainHandler.post(new Runnable() {@Overridepublic void run() {mTvShow.setText("录音小于3秒没有保存文件");}});}} catch (RuntimeException e) {e.printStackTrace();Log.e(TAG, "doStop: " + e);return false;}return true;}
复制代码

上面就是停止录音的方法了,基本的实现逻辑就是大于3秒钟保存文件,否则就删除文件,其实MediaRecorder保存文件,不管你录制多少秒都会保存的!所以为了节约空间,所以这里做了删除的操作!就是把之前录制的文件进行删除!

1.5 释放相应的资源

其实释放资源就比较简单了,直接释放了滞空就可以了

    /*** 释放资源*/private void releaseResources() {if (mMediaRecorder != null) {mMediaRecorder.release();mMediaRecorder = null;}}
复制代码

关于音频的录制就这么多的内容了,对了!提醒一下,测试的时候最好找个真机去测试,虚拟机会有各种各样的毛病!真心的,这一点千万要记得。我没有做权限的适配,因为不是重点!!!好了今天就到这里吧。詹姆斯输球了,很是不开心,激动的我一上午没怎么写代码,能赢的比赛就这么葬送了。。。可怜了詹姆斯啊!!!不说了,心塞。。。

忘了说了,代码地址

Android音频处理知识(一)MediaRecorder录制音频相关推荐

  1. Android音视频开发:MediaRecorder录制音频

    Android 多媒体框架针对音频录制提供了两种方法:MediaRecorder和AudioRecord. 区别 MediaRecorder:录制的音频文件是经过压缩后的,需要设置编码器,并且录制的音 ...

  2. Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.使用录音机录制音频 手机有自带的系统相机,也有自带的系统录音机,只要在调用startActivityForResult之前指定该动作,就会自动 ...

  3. Android音视频开发:MediaRecorder录制视频

    简介 安卓api提供了Camera类控制相机捕获图像,在api21以后,安卓也提供了Camera2,Camera变得过时了,但为了兼容性,这里还是使用Camera. 对于录制视频,可以使用MediaR ...

  4. 多媒体——音频——利用MediaRecorder录制音频

    布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:lay ...

  5. # 蓝牙音频相关知识

    蓝牙音频相关知识 文章目录 蓝牙音频相关知识 1 音频源 2 蓝牙音频编解码器 3 一些标准 4 蓝牙音频其他相关知识 4.1 蓝牙版本 4.2 ANC(主动降噪) 4.3 音响相关参数 4.4 音质 ...

  6. AudioUnit录制音频+耳返(四)

    前言 视频直播,K歌应用等等都会有音频录制的功能,音频录制时还可以带有耳返效果,那这些是如何实现的呢?如果仅仅是录制音频,那使用IOS的AudioQueue框架实现即可,但是在直播这些实时性要求比较高 ...

  7. Android录制音频方式AudioRecorder和MediaRecorder

    AudioRecorder和MediaRecorder AudioRecord和MediaRecorder两种都可以录制音频,MediaRecorder已实现大量的封装,操作起来更加简单,而Audio ...

  8. Android录制音频的三种方式

    对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...

  9. Android音视频学习系列(五) — 掌握音频基础知识并使用AudioTrack、OpenSL ES渲染PCM数据

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

最新文章

  1. c语言变量在头文件定义变量吗,在头文件C中声明变量
  2. CodeForces - 78E Evacuation(最大流)
  3. [转]html超链接打开的窗口大小
  4. python安装json模块_python 标准模块之json 模块
  5. JVM第一讲:为什么需要 JVM?它处在什么位置?
  6. SQLserver通过链接服务器连接oracle
  7. F10-MYSQL的yum源码
  8. 性能测试学习笔记-如何管理loadrunner的临时文件
  9. SpringBoot中前后端数据交互
  10. 交换机在局域网内的日常工作
  11. 商务与经济统计(13版,Python)笔记 01-02章
  12. java报表技术总结_15个Java的报表工具总结
  13. 自动注册11平台账号
  14. Vite-babysitter 像月嫂?保姆?照顾孩子一般为你讲解Vite源码。
  15. 2015届华为校园招聘机试题 C语言实现
  16. 权威典藏版:漫游费的前世今生(上)
  17. 软件解决机械键盘连击问题(或许是最佳实践); 软件解决鼠标连击问题
  18. 攻防演练-一次内网渗透
  19. 淘宝API接口,获得淘宝app商品详情原数据(Onebound数据)
  20. 水稻外源DNA导入机制 国稻种芯-章成君:基因融合又被证实

热门文章

  1. 获取洞口边界及在墙上开洞(Revit二次开发)
  2. linux nc命令 测试网络连通性
  3. 09 | I/O优化(上):开发工程师必备的I/O优化知识
  4. 人脸识别技术在智慧城城市建设中的深度应用
  5. tomcat 日志报错 java.lang.UnsupportedClassVersionError: com/wlt/controller/IndexController
  6. Html 实现角标效果
  7. 接下来的认证考试 阿里云云计算专业认证考试(ACP级)
  8. julius开源语音识别引擎
  9. R语言--模型的定阶、估计和显著性检验
  10. 二级菜单原生js实现