您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關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; /** * AudioRecord 寫入緩沖區大小 */ protected int m_in_buf_size; /** * 錄制音頻對象 */ private AudioRecord m_in_rec; /** * 錄入的字節數組 */ private byte[] m_in_bytes; /** * 存放錄入字節數組的大小 */ private LinkedList<byte[]> 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<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如何實現邊錄邊播功能”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。