Android如何实现边录边播功能
发表于:2024-12-02 作者:千家信息网编辑
千家信息网最后更新 2024年12月02日,这篇文章给大家分享的是有关Android如何实现边录边播功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Android可以通过MediaRecorder和AudioRec
千家信息网最后更新 2024年12月02日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 LinkedListm_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安全错误
数据库的锁怎样保障安全
网络安全管控对策
docker聊天服务器
redmine数据库迁移
小学生网络安全小卫士手抄报
消防系统计算机网络安全
东台农商行 网络安全
数据库技术从何时开始发展
战地5怎样找服务器
儿童网络安全保护计划
工作一年自学软件开发
湘潭网络安全人才与创新基地
数据库a表怎么同步b表
柬埔寨服务器管理
数据库日志审计功能怎么打开
新主张网络技术有限公司
网络安全我践行手抄报
杭州互动多媒体软件开发
江北应用软件开发商
软件开发用电类别
青岛盈实互联网科技公司
网络安全培训费属于哪类税收
如何写网络安全演讲稿
数据库连接怎么配置文件
杭州乐客网络技术有限公司
内蒙古招生大数据库
数据库语法大全
小伙伴网络技术有限公司
互联网科技有限公司营业执照
统计数据库如何使用
信息系统和网络安全排查报告