Android如何实现边录边播功能
短信预约 -IT技能 免费直播动态提醒
这篇文章给大家分享的是有关Android如何实现边录边播功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
Android可以通过MediaRecorder和AudioRecord这两个工具来实现录音,MediaRecorder直接把麦克风的数据存到文件,并且能够直接进行编码(如AMR,MP3等),而AudioRecord则是读取麦克风的音频流。本文使用AudioRecord读取音频流,使用AudioTrack播放音频流,通过“边读边播放”以及增大音量的方式来实现一个简单的助听器程序。
PS:由于目前的Android模拟器还不支持AudioRecord,因此本程序需要编译之后放到真机运行。
Activity_layout:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/bt_yinpinhuilu_testing_exit" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Close" /> </LinearLayout>
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; protected int m_in_buf_size; private AudioRecord m_in_rec; private byte[] m_in_bytes; private LinkedList<byte[]> m_in_q; 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<byte[]>(); // 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
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.speex"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
感谢各位的阅读!关于“Android如何实现边录边播功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341