Android项目中媒体是很多人头疼的一个问题,不仅仅因为处理起来很麻烦,而且不同的手机差别很大(和硬件,系统都有关系),今天就总结一下Android中的录音和播放,可保存成mp3或amr格式。

小米1s,三星,酷派8721移动版 测试通过

1、首先说一下amr格式和mp3格式的区别

----------------------------------------------------------------------------------------------

amr由欧洲通信标准化委员会提出,是在移动通信系统中使用最广泛的语音标准。它是被各大手机厂商认可的一种保存手机录音的格式。由于amr文件容量很小,因此即便是长达一分钟的音频文件,也能符合中国移动现行的彩信不超过50KB容量的技术规范,所以amr也是实现在彩信中加载人声的唯一格式。但是受体积所限,amr在音质方面不太乐观。

mp3是一个实用的有损音频压缩编码,以此获得较高的压缩和较小的体积。

所以录音优先选择amr格式,微信生成的语音文件就是amr格式的。

2、录音播放的步骤

---------------------------------------------------------------------------------------

Android api中可以录音并播放的类主要有2个,一个是AudioRecord,另一个是MediaRecorder,这篇文章我们用AudioRecord,至于他们的区别,在什么情况下用那个,大家可以自行百度。

1)实例化一个AudioRecord

2)设置录音频率,录制通道,编码格式等参数

3)设置录制缓存区大小

4)创建一个文件,用于保存录制的内容

5)打开一个流,指向创建的文件

6)开始录制

先定义一些音频录制的参数

private boolean isRecording = true, isPlaying = false; // 标记
private int frequence = 16000;// 8000;
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

在录制之前,先要判断一个sd卡是否存在:

if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))// 手机有SD卡的情况{// 在这里我们创建一个文件,用于保存录制内容fpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test_record/");fpath.mkdirs();// 创建文件夹} else// 手机无SD卡的情况{//返回在文件系统上应用程序特定的缓存目录的绝对路径fpath = this.getCacheDir();}try {// 创建临时文件,注意这里的格式为.pcm  .amr  .mp3audioFile = File.createTempFile("recording", ".amr", fpath);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}

这儿我们将事先定义好的参数作为AudioRecord的构造方法的参数传递进去,你也可以先new一个AudioRecord对象,然后设置它的录制参数。

class RecordTask extends AsyncTask<Void, Integer, Void> {@Overrideprotected Void doInBackground(Void... arg0) {isRecording = true;try {// 开通输出流到指定的文件DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile)));// 根据定义好的几个配置,来获取合适的缓冲大小int bufferSize = AudioRecord.getMinBufferSize(frequence,channelConfig, audioEncoding);// 实例化AudioRecordAudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, frequence,channelConfig, audioEncoding, bufferSize);// 定义缓冲short[] buffer = new short[bufferSize];// 开始录制record.startRecording();int r = 0; // 存储录制进度// 定义循环,根据isRecording的值来判断是否继续录制while (isRecording) {// 从bufferSize中读取字节,返回读取的short个数// 这里老是出现buffer overflow,不知道是什么原因,试了好几个值,都没用,TODO:待解决int bufferReadResult = record.read(buffer, 0, buffer.length);// 循环将buffer中的音频数据写入到OutputStream中for (int i = 0; i < bufferReadResult; i++) {dos.writeShort(buffer[i]);}publishProgress(new Integer(r)); // 向UI线程报告当前进度r++; // 自增进度值}// 录制结束record.stop();Log.v("The DOS available:", "::" + audioFile.length());dos.close();} catch (Exception e) {// TODO: handle exception}return null;}// 当在上面方法中调用publishProgress时,该方法触发,该方法在I线程中被执行protected void onProgressUpdate(Integer... progress) {stateView.setText(progress[0].toString());}protected void onPostExecute(Void result) {btnStop.setEnabled(false);btnStart.setEnabled(true);btnPlay.setEnabled(true);btnFinish.setEnabled(false);}protected void onPreExecute() {// stateView.setText("正在录制");btnStart.setEnabled(false);btnPlay.setEnabled(false);btnFinish.setEnabled(false);btnStop.setEnabled(true);}}

将音频录制的过程放到线程中取执行,然后更新ui给用户。接下来就是播放了,仍然在线程中播放

class PlayTask extends AsyncTask<Void, Integer, Void> {@Overrideprotected Void doInBackground(Void... arg0) {isPlaying = true;int bufferSize = AudioTrack.getMinBufferSize(frequence,channelConfig, audioEncoding);short[] buffer = new short[bufferSize / 4];try {// 定义输入流,将音频写入到AudioTrack类中,实现播放DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(audioFile)));// 实例AudioTrackAudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,frequence, channelConfig, audioEncoding, bufferSize,AudioTrack.MODE_STREAM);// 开始播放track.play();// 由于AudioTrack播放的是流,所以,我们需要一边播放一边读取while (isPlaying && dis.available() > 0) {int i = 0;while (dis.available() > 0 && i < buffer.length) {buffer[i] = dis.readShort();i++;}// 然后将数据写入到AudioTrack中track.write(buffer, 0, buffer.length);}// 播放结束track.stop();dis.close();} catch (Exception e) {// TODO: handle exception}return null;}protected void onPostExecute(Void result) {btnPlay.setEnabled(true);btnFinish.setEnabled(false);btnStart.setEnabled(true);btnStop.setEnabled(false);}protected void onPreExecute() {btnStart.setEnabled(false);btnStop.setEnabled(false);btnPlay.setEnabled(false);btnFinish.setEnabled(true);}}

到此一个音频录制,播放的demo就完成了,在对amr和mp3的格式进行比较时,分别录制了2段10分钟的视频,但是发现他们的大小是一样的?这就和我们上面说的矛盾了?其实不是,检查整个过程发现,生成音频文件的代码都是一样的,只是最终保存的格式不一样,它的大小肯定是一样的了,至于amr的文件的生成规则,没有做进一步的研究,但是肯定的是用它独特的方法生成的音频文件肯定要小,不然微信的录音也不会用amr的格式了。如果有人知道的话可以贴出来给大家分享。

Android录音并播放(mp3或amr格式)相关推荐

  1. Android 录音和播放

    原文地址:Android 录音和播放 今天主要讲解一下使用MediaRecorder 实现录音,主要是参照Android官网介绍来说明. 今天讲的并不能实现一边录音一边播放,下一篇文章我再说如何解决这 ...

  2. Android实现mp3分析,Android编程实现播放MP3功能示例

    本文实例讲述了Android编程实现播放MP3功能.分享给大家供大家参考,具体如下: 在android中播放mp3非常简单,也是项目中经常使用的,比如说要做项目的背景音乐,应用中某些功能的提示音等的. ...

  3. java 视频边下边播,android 边下边播放mp3完美实现(有缓冲和播放进度效果)

    [实例简介] android 边下边播放mp3完美实现,有缓冲和播放进度效果. [实例截图] [核心代码] MusicPlayer ├── __MACOSX │   └── MusicPlayer │ ...

  4. android播放mp3功能,Android编程实现播放MP3功能示例

    本文实例讲述了android编程实现播放mp3功能.分享给大家供大家参考,具体如下: 在android中播放mp3非常简单,也是项目中经常使用的,比如说要做项目的背景音乐,应用中某些功能的提示音等的. ...

  5. 录音文件上传且amr格式转mp3格式

    1.录音文件 前台测试代码: <form id="upload" enctype="multipart/form-data" method="p ...

  6. 【Java】java转换可播放的QQ/微信高质量语音格式,mp3/wav转silk格式(高质量音频),mp3转换amr格式(低质量音频),mp3/wav转pcm(非语音格式)

    1.简要 参考各个博主,发现java里mp3转silk的案例真的少,几乎没有,有的都是基于 linux系统的,所以自己研究了下就有了以下代码 tips:mp3转换silk格式,需要先转换成pcm再转换 ...

  7. android 录音与播放录音 带根据音频大小动态效果

    先看看效果图:         首先是布局文件: <?xml version="1.0" encoding="utf-8"?> <Linear ...

  8. Android录音与播放

    Android多媒体框架包含获取和编码多种音频格式的支持,所以你可以轻松地把音频合并到你的应用中.如果设备支持,你可以使用MediaRecorder APIs 进行录音. 本章向你展示如何写一个应用从 ...

  9. 音视频开发 ● android录音到播放的整个过程

    使用 AudioRecord 采集音频PCM并保存到文件: api - AndioRecord : AndioRecord类的主要功能是让各种JAVA应用能够管理音频资源,以便它们通过此类能够录制声音 ...

最新文章

  1. Python之装饰器
  2. SpringBoot+Vue整合WebSocket实现前后端消息推送
  3. Java小青蛙跳台街,青蛙跳台阶问题:Java版,递归算法和循环
  4. mysql用 fifo 记录日志_MySQL一丢丢知识点的了解
  5. 【Java】蒙提霍尔问题的概率原理及随机化模拟
  6. python如何操作excel 基础代码
  7. Hibernate---简介
  8. .NET 4 实践 - 使用dynamic 和MEF实现轻量级的 AOP 组件 (1)
  9. 脏写 脏读 不可重复读 幻读 读偏差 写偏差 丢失更新 示例
  10. About Paraview
  11. 《计算机场地安全要求》最新版,计算机场地安全要求gb936200x.doc
  12. 什么是Windows安全模式?Windows安全模式详解
  13. HTML5实现音频和视频嵌入,如何利用HTML5实现音频和视频嵌入的方法
  14. ASII码:小写字符比大写字符大32
  15. 广东深圳计算机学校排名2015,2015年广东深圳重点小学排名
  16. Deadline = Diedline?拖延症幻想美好
  17. 学计算机女生考研什么专业好就业,适合女生考研易就业的十大专业有哪些
  18. 2012 5.4青年节--上海出差
  19. loopback地址是什么?怎么配置
  20. 分享B2C来客推线上商城网站SEO优化方案

热门文章

  1. 迅软手动解密文件夹,有几个文件解密报错解决方法
  2. 利用PT模拟器设计的小型企业局域网实验
  3. 冬季进补,根据体质吃药膳
  4. Java代码输出心形图案
  5. IDEA引入jar包详细
  6. day13—栈和队列完结
  7. 图像处理(7) : 边缘检测
  8. 记录存储用户视频播放历史记录选型
  9. python语言的编程模式是什么意思_编程语言Python,可以用来干什么
  10. Adobe Premiere基础(视频的最后一步字幕添加)(六)