Android录音的两种方式

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()

Comment

您的电子邮箱地址不会被公开。 必填项已用 * 标注