Android提供了两个类用于实现录音功能:MediaRecorder、AudioRecord。
1.MediaRecorder
MediaRecorder封装度高,调用简单方便,直接输出文件。
下面是我封装的一个工具类:
class MediaRecorderUtil private constructor() {
private var mr: MediaRecorder? = null
/**
* 录音文件目录
*/
var dir = ""
/**
* 录音文件名(需要加后缀)
*/
var filename = ""
/**
* 音频输入源
*/
var source = MediaRecorder.AudioSource.MIC
/**
* 输出文件格式
*/
var outputFormat = MediaRecorder.OutputFormat.DEFAULT
/**
* 音频编码器
*/
var encoder = MediaRecorder.AudioEncoder.AAC
/**
* 采样率
*/
var samplingRate = 44100
/**
* 音频通道数
*/
var channels = AudioFormat.CHANNEL_IN_DEFAULT
/**
* 音频编码比特率
*/
var encodingBitRate = AudioFormat.ENCODING_PCM_16BIT
companion object {
fun create(block: MediaRecorderUtil.() -> Unit): MediaRecorderUtil {
return MediaRecorderUtil().apply { block() }
}
}
/**
* 开始录音
*/
fun startRecord() {
val parent = File(dir)
if (!parent.exists()) {
parent.mkdirs()
}
val soundFile = File(dir, filename)
if (!soundFile.exists()) {
soundFile.createNewFile()
}
mr = MediaRecorder().apply {
setAudioSource(source)
setOutputFormat(outputFormat)
setOutputFile(soundFile.absolutePath)
setAudioEncoder(encoder)
setAudioSamplingRate(samplingRate)
setAudioChannels(channels)
setAudioEncodingBitRate(encodingBitRate)
try {
prepare()
start()
} catch (e: IOException) {
HyLog.e("MediaRecorderUtil", e.message.toString())
}
}
}
/**
* 停止录音
*/
fun stopRecord() {
try {
mr?.stop()
} catch (e: IllegalStateException) {
HyLog.e("MediaRecorderUtil", e.message.toString())
}
mr?.release()
mr = null
}
}
调用示例:
val util = MediaRecorderUtil.create {
dir = filesDir.absolutePath
filename = "myAudio.aac"
}
util.startRecord()
停止录音:
util.stopRecord()
2.AudioRecord
AudioRecord可以对语音数据实时处理,比如边录边播。
我也封了一个工具类:
class AudioRecordUtil private constructor() {
private var ar: AudioRecord? = null
private val defaultBufferSize = 2048
/**
* 是否正在录音
*/
private var isRecording = false
/**
* 音频输入源
*/
var audioSource = MediaRecorder.AudioSource.MIC
/**
* 采样率
*/
var sampleRate = 44100
/**
* 音频通道数
*/
var channel = AudioFormat.CHANNEL_IN_DEFAULT
/**
* 音频编码比特率
*/
var audioFormat = AudioFormat.ENCODING_PCM_16BIT
/**
* 缓存区大小
*/
var bufferSizeInBytes = AudioFormat.ENCODING_PCM_16BIT
companion object {
fun create(block: AudioRecordUtil.() -> Unit): AudioRecordUtil {
return AudioRecordUtil().apply { block() }
}
}
/**
* 开始录音
* @param block 处理数据流的方法
*/
fun startRecord(block: (ByteArray, Int) -> Unit) {
try {
//计算AudioRecord内部buffer最小值
val minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channel, audioFormat)
//取defaultBufferSize和minBufferSize中的大值
val size = defaultBufferSize.coerceAtLeast(minBufferSize)
val mBuffer = ByteArray(size)
ar = AudioRecord(audioSource, sampleRate, channel, audioFormat, size).apply {
isRecording = true
startRecording() ////开始录音
while (isRecording) {
val read = read(mBuffer, 0, size)
if (read <= 0) {
isRecording = false
} else {
//处理数据流
block(mBuffer, read)
}
}
}
stopRecord()
} catch (e: Exception) {
HyLog.e("AudioRecordUtil", e.message.toString())
} finally {
ar?.release()
}
}
/**
* 停止录音
*/
fun stopRecord() {
isRecording = false
ar?.let {
it.stop()
it.release()
}
ar = null
}
}
调用示例:
val util =AudioRecordUtil.create {
//可以对音频格式等进行设置
}
util.startRecord { bytes, i ->
//处理数据流
}
停止录音:
util.stopRecord()