上篇文章我们介绍了音频输出(音乐播放),本文将介绍音频的录音即输入,文章中代码坏境Android 4.4
音频输入类:
MediaRecorder
AudioRecord
首先录制音频需要在 AndroidManifest.xml 中加入权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
1、MediaRecorder
MediaRecorder是Android 提供媒体文件录制的类,可以录制视频和音频,我们这主要的是录制音频,下面先看一段录音的代码:
package com.example.framework;
import java.io.File;
import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.AudioEncoder;
import android.media.MediaRecorder.AudioSource;
import android.media.MediaRecorder.OutputFormat;
import android.os.Bundle;
public class MediaRecorderActivity extends Activity {
private MediaRecorder mRediaRecorder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
String path = new File(getCacheDir(), "audio.mp4").getAbsolutePath();
mRediaRecorder = new MediaRecorder();
mRediaRecorder.setAudioChannels(2);
mRediaRecorder.setAudioSource(AudioSource.MIC);
mRediaRecorder.setAudioSamplingRate(44100);
mRediaRecorder.setOutputFormat(OutputFormat.MPEG_4);
mRediaRecorder.setOutputFile(path);
mRediaRecorder.setAudioEncoder(AudioEncoder.DEFAULT);
mRediaRecorder.prepare();
mRediaRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mRediaRecorder != null) {
mRediaRecorder.stop();
mRediaRecorder.release();
}
}
}
参数说明:
AudioChannels
声道,Android中取值范围:1或者2,1代表单声道,2代表双声道(立体声)
AudioSource
音频源,Android中已经定义好常量,android.media.MediaRecorder.AudioSource 类
public final class AudioSource {
private AudioSource() {}
/** Default audio source **/
public static final int DEFAULT = 0;
/** Microphone audio source */
public static final int MIC = 1;
/** Voice call uplink (Tx) audio source */
public static final int VOICE_UPLINK = 2;
/** Voice call downlink (Rx) audio source */
public static final int VOICE_DOWNLINK = 3;
/** Voice call uplink + downlink audio source */
public static final int VOICE_CALL = 4;
/** Microphone audio source with same orientation as camera if available, the main
* device microphone otherwise */
public static final int CAMCORDER = 5;
public static final int VOICE_RECOGNITION = 6;
public static final int VOICE_COMMUNICATION = 7;
public static final int REMOTE_SUBMIX = 8;
}
AudioSource.DEFAULT 默认
AudioSource.MIC 麦克风
AudioSource.VOICE_UPLINK 电话上行
AudioSource.VOICE_DOWNLINK 电话下行
AudioSource.VOICE_CALL 电话 上行+下行
AudioSource.CAMCORDER 摄像机
AudioSource.VOICE_RECOGNITION 语音识别
AudioSource.VOICE_COMMUNICATION 语音通信,例如VoIP
AudioSource.REMOTE_SUBMIX 远程声音,例如wifi display
电话录音:AudioSource.VOICE_UPLINK,AudioSource.VOICE_DOWNLINK,AudioSource.VOICE_CALL 需要系统权限
AudioSource.REMOTE_SUBMIX 需要在AndroidManifest中加入
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
SamplingRate
采样率,一般取值范围在8000-48000,取值越大声音越好,采样率高文件也会更大
OutputFormat
输出格式,Android中已经定义好常量,android.media.MediaRecorder.OutputFormat 类
public final class OutputFormat {
private OutputFormat() {}
public static final int DEFAULT = 0;
/** 3GPP media file format*/
public static final int THREE_GPP = 1;
/** MPEG4 media file format*/
public static final int MPEG_4 = 2;
/** The following formats are audio only .aac or .amr formats */
/**
* AMR NB file format
* @deprecated Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB
*/
public static final int RAW_AMR = 3;
/** AMR NB file format */
public static final int AMR_NB = 3;
/** AMR WB file format */
public static final int AMR_WB = 4;
/** @hide AAC ADIF file format */
public static final int AAC_ADIF = 5;
/** AAC ADTS file format */
public static final int AAC_ADTS = 6;
/** @hide Stream over a socket, limited to a single stream */
public static final int OUTPUT_FORMAT_RTP_AVP = 7;
/** @hide H.264/AAC data encapsulated in MPEG2/TS */
public static final int OUTPUT_FORMAT_MPEG2TS = 8;
}
介绍几种常用的格式, @hide 隐藏的,开发中避免使用,新的版本中就可能去掉该格式的支持。
OutputFormat.THREE_GPP
3gp格式
OutputFormat.MPEG_4
mp4格式
OutputFormat.AMR_NB
OutputFormat.AMR_WB
AMR_NB和AMR_WB的算法不一样.
OutputFormat.AAC_ADTS
ADTS 全称是(Audio Data Transport Stream) 主要用于音频流传输.
文件格式中并没有看到MP3,Android暂时不支持MP3格式,可以自己录制PCM数据编码成MP3 ,后面我们会介绍PCM数据的录制
OutputFile
录音的文件保存路径
AudioEncoder
音频编码,编码定义常量类,android.media.MediaRecorder.AudioEncoder
public final class AudioEncoder {
/* Do not change these values without updating their counterparts
* in include/media/mediarecorder.h!
*/
private AudioEncoder() {}
public static final int DEFAULT = 0;
/** AMR (Narrowband) audio codec */
public static final int AMR_NB = 1;
/** AMR (Wideband) audio codec */
public static final int AMR_WB = 2;
/** AAC Low Complexity (AAC-LC) audio codec */
public static final int AAC = 3;
/** High Efficiency AAC (HE-AAC) audio codec */
public static final int HE_AAC = 4;
/** Enhanced Low Delay AAC (AAC-ELD) audio codec */
public static final int AAC_ELD = 5;
}
对于不同的文件格式选择不同的编码
录制MP4或者AAC_ADTS格式时选用编码 AudioEncoder.AAC,AudioEncoder.HE_AAC,AudioEncoder.AAC_ELD
录制3gp或者amr格式时选用编码 AudioEncoder.AMR_NB,AudioEncoder.AMR_WB
MediaRecorder录音的主要步骤
1:设置参数
2:prepare 准备
3:start 开始录音
4:stop 停止录音
5:release 释放资源
2、AudioRecord
AudioRecord 低级API,录制的是PCM数据,没有经过压缩,先看Demo
package com.example.framework;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import android.os.Bundle;
public class AudioRecordActivity extends Activity implements Runnable {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(this).start();
}
@Override
public void run() {
BufferedOutputStream bos = null;
AudioRecord audioRecord = null;
try {
int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat) * 2;
audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);
audioRecord.startRecording();
bos = new BufferedOutputStream(new FileOutputStream(new File(getCacheDir(), "audio.pcm")));
byte[] buffer = new byte[bufferSizeInBytes];
int len = 0;
while (!isFinishing()) {
len = audioRecord.read(buffer, 0, bufferSizeInBytes);
if (len <= 0) {
break;
}
bos.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {}
}
if (audioRecord != null) {
audioRecord.release();
}
}
}
}
上面的代码是录制麦克风的数据,将录制之后的数据写入"audio.pcm" 文件。
AudioRecord 主要参数说明
audioSource
和MediaRecorder的一样。
sampleRateInHz
和MediaRecorder的一样。
channelConfig
和MediaRecorder 不一样,AudioFormat.CHANNEL_OUT_STEREO或者AudioFormat.CHANNEL_OUT_STEREO
audioFormat
AudioFormat.ENCODING_PCM_8BIT 或者 AudioFormat.ENCODING_PCM_16BIT
bufferSizeInBytes
音频缓冲区大小,使用AudioRecord.getMinBufferSize 方法可以获取最小的缓冲区,上面的代码是获取最小的缓冲区乘以2
AudioRecord 的步骤:
1、设置参数
2、startRecording 开始录音
3、read 读取录制的数据
4、release 释放资源
当我们调用startRecording之后就可以调用read方法从系统中读取音频的PCM数据
read方法的返回值:返回的是读取的数据len,如果大于0读取数据成功,否则读取失败.
总结:MediaRecorder 功能比较强大,录制压缩格式,AudioRecord录制的是PCM数据,在实际开发中两个都有可能用到。