Android 开发一个耳返程序(录音,实时播放)

本文详细介绍了如何在Android上开发一个耳返程序,包括配置AndroidManifest.xml获取录音权限,使用AudioRecord和AudioTrack进行音频录制和播放,以及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 开发一个耳返程序

耳返程序是声音录入设备实时播放的一种程序,理论上实现方案是通过手机录音功能录制音频的同时播放音频,这样就可以简单达到耳返的目的。

分析完毕之后通过了解Android官方API和文档,决定采用AudioRecord/AudioTrack的方式实现简单的PCM编码录制和播放来实现耳返,接下来我们直接进入正题

程序编写

1. 配置 AndroidManifast.xml

录音需要使用录音权限,将以下代码写入AndroidManifast.xml文件中

    <uses-permission android:name="android.permission.RECORD_AUDIO" />

效果如下
配置权限

2.编写耳返管理器

这里我们创建一个类IEMSManager.kt,用来处理音频录制和播放

object IEMSManager {
    //录音来源使用通话语音,这样可以防止啸叫的同时拥有系统降噪
    private const val AUDIO_SOURCE = MediaRecorder.AudioSource.VOICE_COMMUNICATION
    // 采样频率:44100Hz是唯一目前所有Android设备都保证支持的采样频率
    private const val SAMPLE_RATE = 44100
    // 音频通道使用双声道输入
    private const val CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO
    // 音频通道使用双声道输出
    private const val CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO
    // PCM 16bits每个样本,所有设备保证支持
    private const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT

    // 录音时音频数据写入的buffer的大小
    private var recordBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_IN, AUDIO_FORMAT)
    // 播放时音频数据读取的buffer的大小
    private val trackBufferSize =
        AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL_OUT, AUDIO_FORMAT);

    //构建描述音频属性的对象
    private val attributes by lazy {
        AudioAttributes.Builder()
            //设置音频流的用途属性
            .setUsage(AudioAttributes.USAGE_ASSISTANT)
            //设置音频内容属性
            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
            .build()
    }

    //构建描述音频格式的对象
    private val format = AudioFormat.Builder()
        //设置采样频率
        .setSampleRate(SAMPLE_RATE)
        //设置音频格式的编码方式
        .setEncoding(AUDIO_FORMAT)
        //设置通道掩码
        .setChannelMask(CHANNEL_OUT)
        .build()

    //控制耳返的状态
    private var isRunning = false
    //音频录制器,可以录制音频裸数据PCM
    private var audioRecorder: AudioRecord? = null
    //音频播放器,支持PCM裸数据渲染
    private var audioTrack: AudioTrack? = null

    @RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
    fun start() {
        if (isRunning) return
        isRunning = true
        //初始化音频录制器
        audioRecorder = AudioRecord(
            AUDIO_SOURCE,
            SAMPLE_RATE,
            CHANNEL_IN,
            AUDIO_FORMAT,
            recordBufferSize
        )
        //初始化音频播放器
        audioTrack = AudioTrack(
            attributes,
            format,
            trackBufferSize,
            AudioTrack.MODE_STREAM,
            AudioManager.AUDIO_SESSION_ID_GENERATE
        )
        //开启线程
        thread {
            //创建字节数组存储PCM的二进制数据
            val data = ByteArray(recordBufferSize)
            //开始录制
            audioRecorder?.startRecording()
            //开始播放
            audioTrack?.play()
            while (isRunning) {
                //录音数据是根据录制缓冲区大小试试读取的
                val byteSize = audioRecorder?.read(data, 0, recordBufferSize) ?: 0
                //检查到录制数据正常
                if (byteSize >= AudioRecord.SUCCESS) {
                    //AudioTrack实时渲染刚刚录制的部分
                    audioTrack?.write(data, 0, byteSize)
                }
            }
            //释放资源
            audioRecorder?.stop()
            audioRecorder?.release()
            audioTrack?.stop()
            audioTrack?.release()
            audioRecorder = null
            audioTrack = null
        }
    }

    fun stop() {
        isRunning = false
    }
}

3. 录音权限申请

在使用耳返功能前,需要检查权限,并且授予RECORD_AUDIO权限,否则会闪退

            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.RECORD_AUDIO
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 0x1)
                return@setOnClickListener
            }

4. 使用

代码已经编写完成,只需要调用IEMSManager.kt使用即可听到自己发出的声音

IEMSManager.start()
IEMSManager.stop()

注意

因为使用通话的双通道麦克风实现了降噪,所以使用时可能声音较小,如果没有声音,请将声音调到最大,然后凑近麦克风吼两句"感谢博主,我会一键三连的"

最后我还有一句话要说

怕相思,已相思,轮到相思没处辞,眉间露一丝

明·俞彦《长相思·折花枝》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值