Android 音频简介
常见的音频编解码的类型:AAC OPUS MP3 AMR Ogg PCM
AAC: 高级音频编码 对应 .m4a(audio/m4a)或者.3pg(audio/3gpp)文件 HEAAC:高级AAC,使用的比较多。
OPUS:有损声音编码的格式,由互联网工程任务组(IETF)进来开发,适用于网络上的实时声音传输,如:语音通话
MP3: 使用的最广泛的音频编解码器 对应 .mp3(audio/mp3) 各种音乐网站一般用这种。
AMR:自适应多速率音频编解码器,一般用于语音呼叫程序。
Ogg:开发的无专利的音频编解码器,其质量可与商业的和手专利保护的MP3以及AAC编解码相媲美。
PCM :原始音频,在android平台上由audio record直接录用下来的,未经过编码的。
视频直播,语音通话中一般使用AAC或者OPUS ,如果对声音要进行处理就需要使用PCM原始音频加工处理,然后再进行编码.
Android音频采集(捕获)
android平台上的音频采集一般就三种:1.利用android内置的应用程序 2.使用MediaRecorder进行音频捕获 3.使用AudioRecord进行音频捕获。此3种方式的灵活性逐渐增大,相应的所需要做的工作也逐渐增多。
一、Android 内置的应用程序。
1. Intent intent=new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
2. startActivityForResult(intent,0); //通过startActivityForResult获取音频录制的结果的路径
这种方式灵活度最差,一般就是做着演示下,开发中基本不用这种方案。
二、使用MediaRecorder进行音频的捕获。 这个是 录影视频和音频分别编码后保存成一个文件,单独音频也可以,不过是编码后的数据
这种方案相较于调用系统内置的用用程序,灵活度要高很多,便于开发者在UI界面上布局,而且系统封装的很好,便于使用,唯一的缺点是使用它录下来的音频是经过编码的,没有办法的得到原始的音频。同时MediaRecorder即可用于音频的捕获也可以用于视频的捕获相当的强大。实际开发中没有特殊需求的话,用的是比较多的!
使用步骤:
创建MediaRecorder对象,调用如下方法(Ps:调用顺序顺序对结果的影响是非常的大。)
MediaRecorder recorder=new MediaRecorder();//创建MediaRecoder对象
1.recorder.setAudioSource(MediaRecorder.AudioSource.MIC); //调用setAudioSource方法 (调用的第一个方法)
MediaRecorder.AudioSource.CAMCORDER和MediaRecorder.AudioSource.VOICE_RECOGNITION当设备具有。>=2个麦克风的时候就可以使用它们。
MediaRecorder.AudioSource.VOICE_CALL从电话中录音
2.recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//setOutputFormat方法(调用的第二个方法)
MediaRecorder.OutputFormat.THREE_GPP 输出文件将是一个扩展名为(.3gp)的文件。它可能包含音频和视频。
MediaRecorder.OutputFormat.MPEG_4 输出一个MPEG_4文件,它可能包含音频和视频。
3.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //setAudioEncoder方法 (这是调用的第三个方法)
4.recorder.setOutputFile(url); //setOutputFile方法 url是目标文件路径(这是调用的第四个方法)
以上四个方法一次调用完成之后,就可以像MediaPlayer一样控制录制和暂停录制了。
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:orientation="vertical"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent"
6. android:background="#fff"
7. android:gravity="center">
8.
9. <Button
10. android:text="开始录音"
11. android:id="@+id/StartRecording"
12. android:layout_width="wrap_content"
13. android:layout_height="wrap_content"/>
14.
15. <Button
16. android:text="停止录音"
17. android:id="@+id/StopRecording"
18. android:layout_width="wrap_content"
19. android:layout_height="wrap_content"/>
20.
21. </LinearLayout>
1. public class MainActivity extends Activity implements OnClickListener{
2.
3. //开始录音、停止录音、释放资源
4. MediaRecorder recorder;
5. //录音保存的文件
6. boolean isRecoding=false;// true 表示正在录音
7.
8. @Override
9. public void onCreate(Bundle savedInstanceState) {
10. super.onCreate(savedInstanceState);
11. requestWindowFeature(Window.FEATURE_NO_TITLE);
12. setContentView(R.layout.main);
13. init();
14. initListener();
15. }
16.
17. //初始化
18. public void init(){
19. this.findViewById(R.id.StopRecording);
20. this.findViewById(R.id.StartRecording);
21.
22. new MediaRecorder();
23. //设置播放源 麦克风
24. //设置输入格式 3gp
25. //设置编码 AMR
26. }
27.
28. //设置监听器
29. public void initListener(){
30. this);
31. this);
32. }
33.
34. //录音
35. public void recod(){
36.
37. //此处还应该对手机进行下判断,判断下手机里面有没有内存卡
38. //保存在SD卡下MediaRecorderTest文件夹中
39. new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/MediaRecorderTest");
40. if(!path.exists())
41. {
42. path.mkdirs();
43. }
44.
45. try {
46. new File(path,"test.3gp");
47. if(audioFile.exists())
48. {
49. audioFile.delete();
50. }
51. //创建文件
52.
53. catch (Exception e) {
54. throw new RuntimeException("Couldn't create recording audio file", e);
55. }
56.
57. //设置输出文件
58.
59. try {
60. recorder.prepare();
61. catch (IllegalStateException e) {
62. throw new RuntimeException("IllegalStateException on MediaRecorder.prepare", e);
63. catch (IOException e) {
64. throw new RuntimeException("IOException on MediaRecorder.prepare", e);
65. }
66. true;
67. recorder.start();
68. }
69.
70.
71. public void onClick(View v) {
72.
73. switch (v.getId())
74. {
75. //开始录音
76. case R.id.StartRecording:
77. {
78. this,"开始录音",Toast.LENGTH_SHORT).show();
79. recod();
80. break;
81. }
82.
83. //停止录音
84. case R.id.StopRecording:
85. {
86. if(isRecoding)
87. {
88. this,"停止录音",Toast.LENGTH_SHORT).show();
89. recorder.stop();
90. recorder.release();
91. }
92. break;
93. }
94.
95. default:
96. break;
97. }
98. }
99.
100. }
1. MediaRecoder的其他API方法:
2. //设置录制允许的最大时长 单位是毫秒。必须在setOutFormat方法之后,prepare方法之前使用。
3. setMaxDuration(int);
4. //设置文件录制的存放文件的最大值,单位是字节 。必须在setOutFormat方法之后,prepare方法之前使用。
5. setMaxFileSize(long)
6. //允许录制的音频通道数,通常是一个通道(单声道,2个通道双声道,立体声)。必须在调用prepare方法之前调用。
7. setAudioChannels(int)
8. //允许制定捕获和编码音频的采样率。硬件和使用的编码器将会决定合适的采样率。必须在调用prepare方法之前调用。
9. setAudioSamplingRate(int)
10. //允许指定当压缩音频时编码器所使用的每秒位数(位/秒)。必须在调用prepare方法之前调用。
11. setAudioEncodingBitRate在(int)
三、使用AudioRecord 进行音频捕获。——从某个输入,直接捕获音频数据:PCM格式
这种方法是3种之中最为灵活的,能让开发者最大限度的处理采集的音频,同时它捕获到的音频是原始音频PCM格式的!像做变声处理的需要就必须要用它收集音频。在实际开发中,它也是最常用来采集音频的手段。也是本文介绍的重点。
1. //指定音频源 这个和MediaRecorder是相同的
2. int audioSource=MediaRecorder.AudioSource.MIC;
3. //指定采样率 (MediaRecoder 的采样率通常是8000Hz CD的通常是44100Hz 不同的Android手机硬件将能够以不同的采样率进行采样。其中11025是一个常见的采样率)
4. int sampleRateInHz=11025 ;
5. //指定捕获音频的通道数目。在AudioFormat类中指定用于此的常量
6. int channelConfig=AudioFormat.CHANNEL_CONFIGURATION_MONO;
7. //指定音频量化位数 ,在AudioFormaat类中指定了以下各种可能的常量。通常我们选择ENCODING_PCM_16BIT和ENCODING_PCM_8BIT PCM代表的是脉冲编码调制,它实际上是原始音频样本。
8. //因此可以设置每个样本的分辨率为16位或者8位,16位将占用更多的空间和处理能力,表示的音频也更加接近真实。
9. int audioFormat=AudioFormat.ENCODING_PCM_16BIT;
10. 指定缓冲区大小。调用AudioRecord类的getMinBufferSize方法可以获得。
11. //创建AudioRecord。AudioRecord类实际上不会保存捕获的音频,因此需要手动创建文件并保存下载。
12. AudioRecord record=new AudioRecord(audioSource,sampleRateInHz,channelConfig,audioFormat,bufferSizeInBytes);
布局xml文件和MediaRecorder Demo中一样,2个按钮而已!就不贴了,下面贴出AudioRecord的Demo的源代码.
1. public class MainActivity extends Activity implements OnClickListener {
2. //开始录音、停止录音
3. //储存AudioRecord录下来的文件
4. boolean isRecording = false; //true表示正在录音
5. null;
6. null;//文件目录
7. int bufferSize=0;//最小缓冲区大小
8. int sampleRateInHz = 11025;//采样率
9. int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; //单声道
10. int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //量化位数
11. "AudioRecord";
12.
13. @Override
14. public void onCreate(Bundle savedInstanceState) {
15. super.onCreate(savedInstanceState);
16. requestWindowFeature(Window.FEATURE_NO_TITLE);
17. setContentView(R.layout.main);
18. init();
19. initListener();
20. }
21.
22. //初始化
23. public void init(){
24. startRecordingButton = (Button)findViewById(R.id.StartRecordingButton);
25. stopRecordingButton = (Button)findViewById(R.id.StopRecordingButton);
26.
27. //计算最小缓冲区
28. new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz,channelConfig, audioFormat, bufferSize);//创建AudioRecorder对象
29.
30. new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/AudiioRecordTest");
31. if(!parent.exists())
32. //创建文件夹
33. }
34.
35. //初始化监听器
36. public void initListener(){
37. this);
38. this);
39. }
40.
41. public void onClick(View v) {
42. switch (v.getId()) {
43. //开始录音
44. case R.id.StartRecordingButton:
45. {
46. record();
47. break;
48. }
49.
50. //停止录音
51. case R.id.StopRecordingButton:
52. {
53. stopRecording();
54. break;
55. }
56. }
57.
58. }
59.
60. //开始录音
61. public void record() {
62. true;
63. new Thread(new Runnable() {
64. @Override
65. public void run() {
66. true;
67.
68. new File(parent,"audiotest.pcm");
69. if(recordingFile.exists()){
70. recordingFile.delete();
71. }
72.
73. try {
74. recordingFile.createNewFile();
75. }
76. catch (IOException e) {
77. e.printStackTrace();
78. "创建储存音频文件出错");
79. }
80.
81.
82. try {
83. new DataOutputStream(new BufferedOutputStream(new FileOutputStream(recordingFile)));
84. byte[] buffer = new byte[bufferSize];
85. //开始录音
86. int r = 0;
87. while (isRecording) {
88. int bufferReadResult = audioRecord.read(buffer,0,bufferSize);
89. for (int i = 0; i < bufferReadResult; i++)
90. {
91. dos.write(buffer[i]);
92. }
93. r++;
94. }
95. //停止录音
96. dos.close();
97. catch (Throwable t) {
98. "Recording Failed");
99. }
100.
101. }
102. }).start();
103.
104. }
105.
106. //停止录音
107. public void stopRecording()
108. {
109. false;
110. }
111.
112.
113. }
注意这几个Demo都要添加以下权限:
1. <uses-permission android:name="android.permission.RECORD_AUDIO"/>
2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
四、备注:
MediaRecorder采集音频的Demo源码
AudioRecord采集音频的Demo源码
原始音频PCM播放器 使用方法 : 文件->导入->裸数据 然后根据你录音时的配置填写相应参数 就可以播放了!