使用 AudioRecord 采集音频PCM并保存到文件:
api - AndioRecord :
AndioRecord类的主要功能是让各种JAVA应用能够管理音频资源,以便它们通过此类能够录制声音相关的硬件所收集的声音。此功能的实现就是通过”pulling”(读取)AudioRecord对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过后面三个类方法中的一个去及时地获取AudioRecord对象的录音数据. AudioRecord类提供的三个获取声音数据的方法分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int). 无论选择使用那一个方法都必须事先设定方便用户的声音数据的存储格式。  开始录音的时候,AudioRecord需要初始化一个相关联的声音buffer, 这个buffer主要是用来保存新的声音数据。这个buffer的大小,我们可以在对象构造期间去指定。它表明一个AudioRecord对象还没有被读取(同步)声音数据前能录多长的音(即一次可以录制的声音容量)。声音数据从音频硬件中被读出,数据大小不超过整个录音数据的大小(可以分多次读出),即每次读取初始化buffer容量的数据。

AudioRecord 实现录音,并生成wav:

创建一个AudioRecord对象

private AudioRecord audioRecord = null;  // 声明 AudioRecord 对象
private int recordBufSize = 0; // 声明recoordBufffer的大小字段

获取buffer的大小并创建AudioRecord:

public void createAudioRecord() {recordBufSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, EncodingBitRate);  //audioRecord能接受的最小的buffer大小audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, EncodingBitRate, recordBufSize);
}

初始化一个buffer

byte data[] = new byte[recordBufSize];

开始录音

audioRecord.startRecording();
isRecording = true;

创建一个数据流,一边从AudioRecord中读取声音数据到初始化的buffer,一边将buffer中数据导入数据流。

FileOutputStream os = null;try {os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {e.printStackTrace();
}
if (null != os) {while (isRecording) {read = audioRecord.read(data, 0, recordBufSize);// 如果读取音频数据没有出现错误,就将数据写入到文件if (AudioRecord.ERROR_INVALID_OPERATION != read) {try {os.write(data);} catch (IOException e) {e.printStackTrace();}}}try {os.close();} catch (IOException e) {e.printStackTrace();}
}

关闭数据流:isRecording = false;

释放资源:

if ( audioRecord !=null ) {audioRecord.stop();audioRecord.release();audioRecord = null;recordingThread = null;
}

到这一步我们已经把数据写入本地了,但是你会发现并播不了,我们需要对原数据进行处理才能让播放器识别。

数据开头加入WAVE HEAD 即头文件:

public class PcmToWavHelper {/*** 缓存的音频大小*/private int mBufferSize;/*** 采样率*/private int mSampleRate;/*** 声道数*/private int mChannel;/*** @param sampleRate sample rate、采样率* @param channel channel、声道* @param encoding Audio data format、音频格式*/PcmToWavHelper(int sampleRate, int channel, int encoding) {this.mSampleRate = sampleRate;this.mChannel = channel;this.mBufferSize = AudioRecord.getMinBufferSize(mSampleRate, mChannel, encoding);}/*** pcm文件转wav文件** @param inFilename 源文件路径* @param outFilename 目标文件路径*/public void pcmToWav(String inFilename, String outFilename) {FileInputStream in;FileOutputStream out;long totalAudioLen;long totalDataLen;long longSampleRate = mSampleRate;int channels = mChannel == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;long byteRate = 16 * mSampleRate * channels / 8;byte[] data = new byte[mBufferSize];try {in = new FileInputStream(inFilename);out = new FileOutputStream(outFilename);totalAudioLen = in.getChannel().size();totalDataLen = totalAudioLen + 36;writeWaveFileHeader(out, totalAudioLen, totalDataLen,longSampleRate, channels, byteRate);while (in.read(data) != -1) {out.write(data);}in.close();out.close();} catch (IOException e) {e.printStackTrace();}}/*** 加入wav文件头*/private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,long totalDataLen, long longSampleRate, int channels, long byteRate)throws IOException {byte[] header = new byte[44];// RIFF/WAVE headerheader[0] = 'R';header[1] = 'I';header[2] = 'F';header[3] = 'F';header[4] = (byte) (totalDataLen & 0xff);header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);//WAVEheader[8] = 'W';header[9] = 'A';header[10] = 'V';header[11] = 'E';// 'fmt ' chunkheader[12] = 'f';header[13] = 'm';header[14] = 't';header[15] = ' ';// 4 bytes: size of 'fmt ' chunkheader[16] = 16;header[17] = 0;header[18] = 0;header[19] = 0;// format = 1header[20] = 1;header[21] = 0;header[22] = (byte) channels;header[23] = 0;header[24] = (byte) (longSampleRate & 0xff);header[25] = (byte) ((longSampleRate >> 8) & 0xff);header[26] = (byte) ((longSampleRate >> 16) & 0xff);header[27] = (byte) ((longSampleRate >> 24) & 0xff);header[28] = (byte) (byteRate & 0xff);header[29] = (byte) ((byteRate >> 8) & 0xff);header[30] = (byte) ((byteRate >> 16) & 0xff);header[31] = (byte) ((byteRate >> 24) & 0xff);// block alignheader[32] = (byte) (2 * 16 / 8);header[33] = 0;// bits per sampleheader[34] = 16;header[35] = 0;//dataheader[36] = 'd';header[37] = 'a';header[38] = 't';header[39] = 'a';header[40] = (byte) (totalAudioLen & 0xff);header[41] = (byte) ((totalAudioLen >> 8) & 0xff);header[42] = (byte) ((totalAudioLen >> 16) & 0xff);header[43] = (byte) ((totalAudioLen >> 24) & 0xff);out.write(header, 0, 44);}
}

音视频开发 ● android录音到播放的整个过程相关推荐

  1. iOS 音视频开发:Audio Unit播放FFmpeg解码的音频

    本文档描述了iOS播放经FFmpeg解码的音频数据的编程步骤,具体基于Audio Toolbox框架的Audio Session和Audio Unit框架提供的接口实现.在iOS 7及以上平台Audi ...

  2. N32905音视频学习笔记-录音和播放

    陈生 微信:chenzhe_yj 提供开源硬件产品.嵌入式软硬件开发.技术咨询 淘宝店:https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-1 ...

  3. 音视频开发 ● Android 音视频开发总结

    关于视频中的黑屏.花屏.绿屏问题 我们在做音视频开发的时候难免会遇到一些很棘手的问题,但是我们只要找准问题出现的阶段,定位问题的根源就会轻松很多. 前几天我看了一篇总结这些问题的文章,写的很好,根据自 ...

  4. 音视频开发系列(28)AudioTrack播放PCM音频

    目录 AudioTrack和MediaPlayer AudioTrack的API介绍(构造.操作.状态机) 具体实现(Static和Stream两种模式) 遇到的问题 收获 一.MediaPlayer ...

  5. Android 音视频开发(一) -- 使用AudioRecord 录制PCM(录音);AudioTrack播放音频

    前言,音视频这块,确实比较难入门,本着学习的态度,我这边也跟着 Android 音视频开发入门指南 打怪升级,留下个脚印,大家共勉. 音视频 系列文章 Android 音视频开发(一) – 使用Aud ...

  6. Android音视频开发之音频录制和播放

    Android音视频开发之音频录制和播放 1.封装音频录制工具类: public class RecorderAudioManagerUtils {private static volatile Re ...

  7. 音视频开发刚入门该如何实现一个录音/播放器

    如果你从未接触过音视频开发,但有实现一个录音器.播放器的需求或想法,本文会是一个比较好的入门内容. 本博客是从基础内容到具体的实践,再展现一个简易的整体框架,内容主要有: 1.音频基础知识,可以了解音 ...

  8. Android 音视频开发(一):PCM 格式音频的播放与采集

    什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...

  9. Android音视频开发(2)常用的系统播放器MediaPlayer

    1.状态图及生命周期 MediaPlayer是一个多媒体播放类,通过它控制音视频流或本地音视频资源的播放过程. 它分为很多状态,如下图所示: 图中的单箭头弧代表同步函数调用,双箭头弧代表异步函数调用. ...

最新文章

  1. 【NYOJ-35】表达式求值——简单栈练习
  2. rabbitmq-路由模式-routingkey
  3. 解决开发问题的思路与心态
  4. 利用Windows 2003系统中实现两个网段的路由
  5. 测试一下各浏览器对CSS3的支持
  6. 语义分割数据集——VOC2012
  7. 【大数据语言】怎样利用Python爬虫,高效获取大规模数据
  8. 箱线图2种画法-直接给出各个四分位值或者数据集
  9. 退休当月要干到月底吗_退休时间是从到达年龄的当月算起还是次月算起
  10. Unity笔记-29-ARPG游戏项目-06-弓箭
  11. Win11玩红警2突然就卡住不动?
  12. python怎么把ppt转成html,如何使用python把ppt转换成pdf
  13. Android service后台执行定时任务
  14. WebService的简单案例记录(Java)
  15. barcode--php生成条形码
  16. 【今晚7点】:如何借助Google Cloud在海外部署音视频业务?
  17. SpringMVC REST ful API
  18. 【NIPS 2018】完整论文下载链接
  19. html圆角边框背景颜色,CSS之圆角边框渐变的实现
  20. 360网页html,360综艺频道-更新更全更受欢迎的影视网站-在线观看

热门文章

  1. ADI Blackfin DSP处理器-BF533的开发详解49:图像处理专题-Bright (图像亮暗处理)(含源码)
  2. CS品牌SD NAND在车联网行业中的应用案例
  3. 【微信小程序】知识付费小程序梦想贩卖机v2-1.0.88-带4插件
  4. 路由器虚拟服务器的设置
  5. 求1+2+3+···
  6. (一)2005年我的第一次软件行业创业,烧掉30万、2年时间打水漂的惨痛教训
  7. “汽车人”眼中的网络安全---关于AUTOSAR E2E及测试开发实践
  8. python数组赋值失败
  9. Java Springboot 微信第三方支付 证书认证绑定 Docker导入CER证书
  10. 我找到了 4 个 Midjourney 的免费替代品,停止为 Midjourney 付费,有免费的 AI 替代品