Android如何实现边录边播功能
发表于:2025-11-06 作者:千家信息网编辑
千家信息网最后更新 2025年11月06日,这篇文章给大家分享的是有关Android如何实现边录边播功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Android可以通过MediaRecorder和AudioRec
千家信息网最后更新 2025年11月06日Android如何实现边录边播功能
这篇文章给大家分享的是有关Android如何实现边录边播功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
Android可以通过MediaRecorder和AudioRecord这两个工具来实现录音,MediaRecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如AMR,MP3等),而AudioRecord则是读取麦克风的音频流。本文使用AudioRecord读取音频流,使用AudioTrack播放音频流,通过"边读边播放"以及增大音量的方式来实现一个简单的助听器程序。
PS:由于目前的Android模拟器还不支持AudioRecord,因此本程序需要编译之后放到真机运行。
Activity_layout:
MainActivity:
import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat; import android.Manifest;import android.content.pm.PackageManager;import android.media.AudioFormat;import android.media.AudioManager;import android.media.AudioRecord;import android.media.AudioTrack;import android.media.MediaRecorder;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast; import java.util.LinkedList; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "ktv"; /** * 按钮 */ private Button bt_exit; /** * AudioRecord 写入缓冲区大小 */ protected int m_in_buf_size; /** * 录制音频对象 */ private AudioRecord m_in_rec; /** * 录入的字节数组 */ private byte[] m_in_bytes; /** * 存放录入字节数组的大小 */ private LinkedList m_in_q; /** * AudioTrack 播放缓冲大小 */ private int m_out_buf_size; /** * 播放音频对象 */ private AudioTrack m_out_trk; /** * 播放的字节数组 */ private byte[] m_out_bytes; /** * 录制音频线程 */ private Thread record; /** * 播放音频线程 */ private Thread play; /** * 让线程停止的标志 */ private boolean flag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.setTitle("音频回路"); requestAllPower(); Log.d("dfdfd", "333333333333"); init(); record = new Thread(new recordSound()); play = new Thread(new playRecord()); // 启动录制线程 record.start(); // 启动播放线程 play.start(); } private void init() { bt_exit = findViewById(R.id.bt_yinpinhuilu_testing_exit); Log.i(TAG, "bt_exit====" + bt_exit); bt_exit.setOnClickListener(this); // AudioRecord 得到录制最小缓冲区的大小 m_in_buf_size = AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); // 实例化播放音频对象 m_in_rec = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, m_in_buf_size); // 实例化一个字节数组,长度为最小缓冲区的长度 m_in_bytes = new byte[m_in_buf_size]; // 实例化一个链表,用来存放字节组数 m_in_q = new LinkedList(); // AudioTrack 得到播放最小缓冲区的大小 m_out_buf_size = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); // 实例化播放音频对象 m_out_trk = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, m_out_buf_size, AudioTrack.MODE_STREAM); // 实例化一个长度为播放最小缓冲大小的字节数组 m_out_bytes = new byte[m_out_buf_size]; } public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.bt_yinpinhuilu_testing_exit: flag = false; m_in_rec.stop(); m_in_rec = null; m_out_trk.stop(); m_out_trk = null; this.finish(); } } /** * 录音线程 */ class recordSound implements Runnable { @Override public void run() { Log.i(TAG, "........recordSound run()......"); byte[] bytes_pkg; // 开始录音 m_in_rec.startRecording(); while (flag) { m_in_rec.read(m_in_bytes, 0, m_in_buf_size); bytes_pkg = m_in_bytes.clone(); Log.i(TAG, "........recordSound bytes_pkg==" + bytes_pkg.length); if (m_in_q.size() >= 2) { m_in_q.removeFirst(); } m_in_q.add(bytes_pkg); } } } /** * 播放线程 */ class playRecord implements Runnable { @Override public void run() { // TODO Auto-generated method stub Log.i(TAG, "........playRecord run()......"); byte[] bytes_pkg = null; // 开始播放 m_out_trk.play(); while (flag) { try { m_out_bytes = m_in_q.getFirst(); bytes_pkg = m_out_bytes.clone(); m_out_trk.write(bytes_pkg, 0, bytes_pkg.length); } catch (Exception e) { e.printStackTrace(); } } } } /** * 录音哦动态权限 */ public void requestAllPower() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) { } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE}, 1); } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { for (int i = 0; i < permissions.length; i++) { Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show(); } } }} AndroidManifest.xml
感谢各位的阅读!关于"Android如何实现边录边播功能"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
音频
线程
大小
字节
缓冲
实例
数组
最小
对象
缓冲区
长度
功能
内容
更多
权限
程序
篇文章
麦克风
麦克
不错
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库技术第九单元思考题
现在较为流行的软件开发模型
原神切换服务器2.5版本
数据库中的研究文献以什么为主
无线网络技术填空
打开sql数据库图片
网络安全留言有哪些
济南中中网络技术有限公司介绍
网固打印服务器
妈妈好网络技术有限公司怎么样
2021官方服务器人口普查
手机软件开发嵌入式
未来教育网络技术上级题库
平谷区一站式网络技术信息推荐
数据库held
网络技术改变社会
fastapi 用什么数据库
云南数据库通用多路锁控板装备
好的软件开发诚信为本
前端平台软件开发
软件开发程序员程序员
根据照片捏脸数据库
北邮网络安全期末试题
数据库服务未启动什么原因
山东服务器回收推荐云主机
软件开发说明书 毕设
inux服务器开源
数据库发生冲突自动保存文件
云联客户端服务器地址端口填什么
科技发展互联网发展