Android录音AudioRecordMediaRecorder.docx
- 文档编号:17954370
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:32
- 大小:24.12KB
Android录音AudioRecordMediaRecorder.docx
《Android录音AudioRecordMediaRecorder.docx》由会员分享,可在线阅读,更多相关《Android录音AudioRecordMediaRecorder.docx(32页珍藏版)》请在冰点文库上搜索。
Android录音AudioRecordMediaRecorder
【Android】【录音】Android录音--AudioRecord、MediaRecorder
Android提供了两个API用于实现录音功能:
android.media.AudioRecord、android.media.MediaRecorder。
网上有很多谈论这两个类的资料。
现在大致总结下:
1、AudioRecord
主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫、语音)
优点:
语音的实时处理,可以用代码实现各种音频的封装
缺点:
输出是PCM语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩
示例:
使用AudioRecord类录音,并实现WAV格式封装。
录音20s,输出的音频文件大概为3.5M左右(已写测试代码)
2、MediaRecorder
已经集成了录音、编码、压缩等,支持少量的录音音频格式,大概有.aac(API=16).amr.3gp
优点:
大部分以及集成,直接调用相关接口即可,代码量小
缺点:
无法实时处理音频;输出的音频格式不是很多,例如没有输出mp3格式文件
示例:
使用MediaRecorder类录音,输出amr格式文件。
录音20s,输出的音频文件大概为33K(已写测试代码)
3、音频格式比较
WAV格式:
录音质量高,但是压缩率小,文件大
AAC格式:
相对于mp3,AAC格式的音质更佳,文件更小;有损压缩;一般苹果或者AndroidSDK4.1.2(API16)及以上版本支持播放
AMR格式:
压缩比比较大,但相对其他的压缩格式质量比较差,多用于人声,通话录音
至于常用的mp3格式,使用MediaRecorder没有该视频格式输出。
一些人的做法是使用AudioRecord录音,然后编码成wav格式,再转换成mp3格式
再贴上一些测试工程。
功能描述:
1、点击“录音WAV文件”,开始录音。
录音完成后,生成文件/sdcard/FinalAudio.wav
2、点击“录音AMR文件”,开始录音。
录音完成后,生成文件/sdcard/FinalAudio.amr
3、点击“停止录音”,停止录音,并显示录音输出文件以及该文件大小。
大致代码如下:
1、AudioRecord录音,封装成WAV格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
package com.example.audiorecordtest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.media.AudioFormat;
import android.media.AudioRecord;
public class AudioRecordFunc{
//缓冲区字节大小
private int bufferSizeInBytes=0;
//AudioName裸音频数据文件,麦克风
private StringAudioName="";
//NewAudioName可播放的音频文件
private StringNewAudioName="";
private AudioRecordaudioRecord;
private boolean isRecord=false;//设置正在录制的状态
private static AudioRecordFuncmInstance;
private AudioRecordFunc(){
}
public synchronized static AudioRecordFuncgetInstance()
{
if(mInstance==null)
mInstance=new AudioRecordFunc();
return mInstance;
}
public int startRecordAndFile(){
//判断是否有外部存储设备sdcard
if(AudioFileFunc.isSdcardExit())
{
if(isRecord)
{
return ErrorCode.E_STATE_RECODING;
}
else
{
if(audioRecord==null)
creatAudioRecord();
audioRecord.startRecording();
//让录制状态为true
isRecord=true;
//开启音频文件写入线程
new Thread(new AudioRecordThread()).start();
return ErrorCode.SUCCESS;
}
}
else
{
return ErrorCode.E_NOSDCARD;
}
}
public void stopRecordAndFile(){
close();
}
public long getRecordFileSize(){
return AudioFileFunc.getFileSize(NewAudioName);
}
private void close(){
if (audioRecord!
=null){
System.out.println("stopRecord");
isRecord=false;//停止文件写入
audioRecord.stop();
audioRecord.release();//释放资源
audioRecord=null;
}
}
private void creatAudioRecord(){
//获取音频文件路径
AudioName=AudioFileFunc.getRawFilePath();
NewAudioName=AudioFileFunc.getWavFilePath();
//获得缓冲区字节大小
bufferSizeInBytes=AudioRecord.getMinBufferSize(AudioFileFunc.AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT);
//创建AudioRecord对象
audioRecord=new AudioRecord(AudioFileFunc.AUDIO_INPUT,AudioFileFunc.AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT,bufferSizeInBytes);
}
class AudioRecordThreadimplements Runnable{
@Override
public void run(){
writeDateTOFile();//往文件中写入裸数据
copyWaveFile(AudioName,NewAudioName);//给裸数据加上头文件
}
}
/**
*这里将数据写入文件,但是并不能播放,因为AudioRecord获得的音频是原始的裸音频,
*如果需要播放就必须加入一些格式或者编码的头信息。
但是这样的好处就是你可以对音频的裸数据进行处理,比如你要做一个爱说话的TOM
*猫在这里就进行音频的处理,然后重新封装所以说这样得到的音频比较容易做一些音频的处理。
*/
private void writeDateTOFile(){
//new一个byte数组用来存一些字节数据,大小为缓冲区大小
byte[]audiodata=new byte[bufferSizeInBytes];
FileOutputStreamfos=null;
int readsize=0;
try {
Filefile=new File(AudioName);
if (file.exists()){
file.delete();
}
fos=new FileOutputStream(file);//建立一个可存取字节的文件
}catch (Exceptione){
e.printStackTrace();
}
while (isRecord==true){
readsize=audioRecord.read(audiodata,0,bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION!
=readsize&&fos!
=null){
try {
fos.write(audiodata);
}catch (IOExceptione){
e.printStackTrace();
}
}
}
try {
if(fos!
=null)
fos.close();//关闭写入流
}catch (IOExceptione){
e.printStackTrace();
}
}
//这里得到可播放的音频文件
private void copyWaveFile(StringinFilename,StringoutFilename){
FileInputStreamin=null;
FileOutputStreamout=null;
long totalAudioLen=0;
long totalDataLen=totalAudioLen+36;
long longSampleRate=AudioFileFunc.AUDIO_SAMPLE_RATE;
int channels=2;
long byteRate=16 *AudioFileFunc.AUDIO_SAMPLE_RATE*channels/8;
byte[]data=new byte[bufferSizeInBytes];
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 (FileNotFoundExceptione){
e.printStackTrace();
}catch (IOExceptione){
e.printStackTrace();
}
}
/**
*这里提供一个头信息。
插入这些信息就可以得到可以播放的文件。
*为我为啥插入这44个字节,这个还真没深入研究,不过你随便打开一个wav
*音频的文件,可以发现前面的头文件可以说基本一样哦。
每种格式的文件都有
*自己特有的头文件。
*/
private void WriteWaveFileHeader(FileOutputStreamout,long totalAudioLen,
long totalDataLen,long longSampleRate,int channels,long byteRate)
throws IOException{
byte[]header=new byte[44];
header[0]='R';//RIFF/WAVEheader
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);
header[8]='W';
header[9]='A';
header[10]='V';
header[11]='E';
header[12]='f';//'fmt'chunk
header[13]='m';
header[14]='t';
header[15]='';
header[16]=16;//4bytes:
sizeof'fmt'chunk
header[17]=0;
header[18]=0;
header[19]=0;
header[20]=1;//format=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);
header[32]=(byte)(2 *16 /8);//blockalign
header[33]=0;
header[34]=16;//bitspersample
header[35]=0;
header[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]=(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 录音 AudioRecordMediaRecorder