当前位置: 首页 > news >正文

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

本文目录 点击直达

  • Android 开发一个耳返程序
    • 程序编写
      • 1. 配置 `AndroidManifast.xml`
      • 2.编写耳返管理器
      • 3. 录音权限申请
      • 4. 使用
      • 注意
  • 最后我还有一句话要说
      • 怕相思,已相思,轮到相思没处辞,眉间露一丝

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//音频录制器,可以录制音频裸数据PCMprivate var audioRecorder: AudioRecord? = null//音频播放器,支持PCM裸数据渲染private var audioTrack: AudioTrack? = null@RequiresPermission(android.Manifest.permission.RECORD_AUDIO)fun start() {if (isRunning) returnisRunning = 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 = nullaudioTrack = 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()

注意

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

最后我还有一句话要说

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

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

相关文章:

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

本文目录 点击直达 Android 开发一个耳返程序程序编写1. 配置 AndroidManifast.xml2.编写耳返管理器3. 录音权限申请4. 使用注意 最后我还有一句话要说怕相思&#xff0c;已相思&#xff0c;轮到相思没处辞&#xff0c;眉间露一丝 Android 开发一个耳返程序 耳返程序是声音录入…...

提高办公效率:Excel在文秘与行政办公中的应用技巧

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在当今信息化时代&#xff0c;Excel作为一款常…...

Object.groupBy分组方法

在某些浏览器的某些版本中&#xff0c;此方法被实现为 Array.prototype.group() 方法。由于 web 兼容性问题&#xff0c;它现在以静态方法实现。 函数功能 提供的回调函数返回的字符串值对给定可迭代对象中的元素进行分组。返回的对象具有每个组的单独属性&#xff0c;其中包…...

从初步的需求收集到详细的规划和评估

综合需求分析建议 明确与细化用户故事 确保每个用户故事清晰、具体,包含角色、目标和成功标准。对用户故事进行优先级排序,以指导开发过程中的功能实现顺序。用户参与和原型制作 创建用户旅程图,以理解用户在使用产品或服务时的整体流程与体验。制作原型或草图,展示用户界面…...

石灰窑工艺流程以及富氧低氧燃烧技术

石灰窑的核心环节是煅烧过程&#xff0c;这是将石灰石转变为生石灰的关键步骤。煅烧反应是碳酸钙&#xff08;CaCO₃&#xff09;分解为氧化钙&#xff08;CaO&#xff09;和二氧化碳&#xff08;CO₂&#xff09;的过程。这一反应需要高温条件&#xff0c;通常在800摄氏度以上…...

LeetCode 2960.统计已测试设备

给你一个长度为 n 、下标从 0 开始的整数数组 batteryPercentages &#xff0c;表示 n 个设备的电池百分比。 你的任务是按照顺序测试每个设备 i&#xff0c;执行以下测试操作&#xff1a; 如果 batteryPercentages[i] 大于 0&#xff1a; 增加 已测试设备的计数。 将下标在 …...

vue中component is和keepAlive组合使用

component is用与动态渲染组件 组件基础 | Vue.js <template><div style"padding: 30px"><button click"change(1)">组件1</button><button click"change(2)">组件2</button><button click"chang…...

使用 Koltin 集合时容易产生的 bug 注意事项

来看下面代码&#xff1a; class ChatManager {private val messages mutableListOf<Message>()/*** 当收到消息时回调*/fun onMessageReceived(message: Message) {messages.add(message)}/*** 当删除消息时回调*/fun onMessageDeleted(message: Message) {messages.r…...

CKA认证,开启您的云原生之旅!

在当今数字化时代&#xff0c;云计算已经成为企业和个人发展的关键技术。而获得CKA&#xff08;Certified Kubernetes Administrator&#xff09;认证&#xff0c;将是您在云原生领域迈出的重要一步。 CKA认证是由Kubernetes官方推出的权威认证&#xff0c;它旨在验证您在Kuber…...

基于springboot+vue的抗疫物资管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…...

nebula容器方式安装:docker 安装nebula到windows

感谢阅读 基础环境安装安装docker下载nebula 安装数据库命令行安装查询network nebula-docker-compose_nebula-net并初始化查询安装初始使用root&#xff08;God用户类似LINUX的root&#xff09; 关闭服务 安装UI 基础环境安装 安装docker 点我下载docker 下载nebula 数据…...

干洗行业上门预约解决方案,干洗店洗鞋店小程序开发;

互联网干洗店洗鞋店小程序,企业干洗方案,干洗行业小程序,上门取衣小程序,预约干洗小程序,校园干洗店小程序,工厂干洗店小程序,干洗店小程序开发&#xff1b; 一、干洗店洗鞋店小程序核心功能介绍: 1.(支持上门取送、送货到店、寄存网点、智能衣柜四种下单方式) 用户下单-上门取…...

【Spring Boot 3】【JPA】@ManyToOne 实现一对多单向关联

【Spring Boot 3】【JPA】@ManyToOne 实现一对多单向关联 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学…...

Mathematica学习笔记收纳

笔记 可以关注官方公众号 帮助文件 https://reference.wolfram.com/language/index.html.zh 南京大学的介绍 https://oi.nju.edu.cn/Mathematica/listm.htm...

java反射高级用列(脱敏+aop)

ClassUtils 、FieldUtils、MethodUtils、ReflectionUtils高级 List<String> list = new ArrayList<>(); Class<?> userClass = ClassUtils.getUserClass(list.getClass()); System.out.println(Collection.class.isAssignableFrom(userClass)); Class<?…...

C++函数对象包装器function类详解

函数对象包装器是对函数的封装&#xff0c;为函数对象提供一个容器&#xff0c;一个封装。C中现有的可调用实体的一种类型安全的包装&#xff08;相对来说&#xff0c;函数指针的调用不是类型安全的&#xff09;&#xff0c;换句话说&#xff0c;函数对象包装器就是函数的容器。…...

SpringMVC 学习(八)之文件上传与下载

目录 1 文件上传 2 文件下载 1 文件上传 SpringMVC 对文件的上传做了很好的封装&#xff0c;提供了两种解析器。 CommonsMultipartResolver&#xff1a;兼容性较好&#xff0c;可以兼容 Servlet3.0 之前的版本&#xff0c;但是它依赖了 commons-fileupload …...

《低功耗方法学》翻译——附录A:睡眠晶体管设计

附录A&#xff1a;睡眠晶体管设计 休眠晶体管是PMOS或NMOS高VT晶体管&#xff0c;用于在待机模式下关闭设计部件的电源。PMOS休眠晶体管用于切换VDD电源&#xff0c;因此被称为“header开关”。NMOS休眠晶体管控制VSS电源&#xff0c;因此被称为“footer开关”。在90 nm及以下…...

How to implement multiple file uploads based on Swagger 3.x in Spring boot 3.x

How to implement multiple file uploads based on Swagger 3.x in Spring boot 3.x Projectpom.xmlOpenAPIConfigFileUploadControllerapplication.yaml Project pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://…...

spring boot 集成科大讯飞星火认知大模型

首先到官网https://console.xfyun.cn/services/aidoc申请key 一、安装依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...