Android使用AudioRecord實(shí)現(xiàn)錄音功能
前言
Android使用AudioRecord實(shí)現(xiàn)錄音
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、AudioRecord使用
Android平臺可以使用AudioRecord和MediaRecorder來實(shí)現(xiàn)錄音,因?yàn)锳udioRecord更接近底層,并且錄制的數(shù)據(jù)為原始(pcm)數(shù)據(jù),pcm數(shù)據(jù)可以再進(jìn)行處理轉(zhuǎn)換,直播中使用的都是處理后的pcm數(shù)據(jù),所以在這里面學(xué)習(xí)下使用AudioRecord。
- 構(gòu)造AudioRecord
AudioRecord類的構(gòu)造方法中有5個(gè)參數(shù)
/** * audioSource 表示數(shù)據(jù)來源 一般為麥克風(fēng) MediaRecorder.AudioSource.MIC * sampleRateInHz 表示采樣率 一般設(shè)置為 44100 * channelConfig 表示聲道 一般設(shè)置為 AudioFormat.CHANNEL_IN_MONO * audioFormat 數(shù)據(jù)編碼方式 這里使用 AudioFormat.ENCODING_PCM_16BIT * bufferSizeInBytes 數(shù)據(jù)大小 這里使用AudioRecord.getMinBufferSize 獲取? */ AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, ? ? ? ? ? ? int bufferSizeInBytes)
- 創(chuàng)建AudioRecord對象
private AudioRecord audioRecord = null; private int recordBufsize = 0; ? ? private void createAudioRecord() { ? ? ? ? recordBufsize = AudioRecord ? ? ? ? ? ? ? ? .getMinBufferSize(44100, ? ? ? ? ? ? ? ? ? ? ? ? AudioFormat.CHANNEL_IN_MONO, ? ? ? ? ? ? ? ? ? ? ? ? AudioFormat.ENCODING_PCM_16BIT); ? ? ? ? audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, ? ? ? ? ? ? ? ? 44100, ? ? ? ? ? ? ? ? AudioFormat.CHANNEL_IN_MONO, ? ? ? ? ? ? ? ? AudioFormat.ENCODING_PCM_16BIT, ? ? ? ? ? ? ? ? recordBufsize); ? ? }
- 開始錄音
// 調(diào)用開始錄音 audioRecord.startRecording();
調(diào)用開始錄音后,需要從audioRecord中讀取錄音的數(shù)據(jù)
audioRecord.read(data, 0, recordBufsize);
- 結(jié)束錄音
audioRecord.stop();
- 釋放資源
audioRecord.release();
AudioRecord的關(guān)鍵方法已經(jīng)介紹了,下面貼上完整的代碼
二、使用步驟
清單文件聲明權(quán)限
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
關(guān)于Android 6.0動(dòng)態(tài)申請權(quán)限這里就不重復(fù)了,可自行百度
完整代碼
public class MainActivity extends AppCompatActivity { ? ? private static final String FILE_NAME = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + File.separator + "test.pcm"; ? ? private AudioRecord audioRecord = null; ? ? private int recordBufsize = 0; ? ? private boolean isRecording = false; ? ? private Button startRecordBtn; ? ? private Button stopRecordBtn; ? ? private Thread recordingThread; ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ? ? ? ? ? ? ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000); ? ? ? ? } ? ? ? ? if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ? ? ? ? ? ? ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 2000); ? ? ? ? } ? ? ? ? startRecordBtn = findViewById(R.id.start_record_btn); ? ? ? ? stopRecordBtn = findViewById(R.id.stop_record_btn); ? ? ? ? createAudioRecord(); ? ? ? ? startRecordBtn.setOnClickListener(v -> { ? ? ? ? ? ? startRecord(); ? ? ? ? }); ? ? ? ? stopRecordBtn.setOnClickListener(v -> { ? ? ? ? ? ? stopRecord(); ? ? ? ? }); ? ? } ? ? private void createAudioRecord() { ? ? ? ? recordBufsize = AudioRecord ? ? ? ? ? ? ? ? .getMinBufferSize(44100, ? ? ? ? ? ? ? ? ? ? ? ? AudioFormat.CHANNEL_IN_MONO, ? ? ? ? ? ? ? ? ? ? ? ? AudioFormat.ENCODING_PCM_16BIT); ? ? ? ? Log.i("audioRecordTest", "size->" + recordBufsize); ? ? ? ? audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, ? ? ? ? ? ? ? ? 44100, ? ? ? ? ? ? ? ? AudioFormat.CHANNEL_IN_MONO, ? ? ? ? ? ? ? ? AudioFormat.ENCODING_PCM_16BIT, ? ? ? ? ? ? ? ? recordBufsize); ? ? } ? ? private void startRecord() { ? ? ? ? if (isRecording) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? isRecording = true; ? ? ? ? audioRecord.startRecording(); ? ? ? ? Log.i("audioRecordTest", "開始錄音"); ? ? ? ? recordingThread = new Thread(() -> { ? ? ? ? ? ? byte data[] = new byte[recordBufsize]; ? ? ? ? ? ? File file = new File(FILE_NAME); ? ? ? ? ? ? FileOutputStream os = null; ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? if (!file.exists()) { ? ? ? ? ? ? ? ? ? ? file.createNewFile(); ? ? ? ? ? ? ? ? ? ? Log.i("audioRecordTest", "創(chuàng)建錄音文件->" + FILE_NAME); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? os = new FileOutputStream(file); ? ? ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } ? ? ? ? ? ? int read; ? ? ? ? ? ? if (os != null) { ? ? ? ? ? ? ? ? while (isRecording) { ? ? ? ? ? ? ? ? ? ? read = audioRecord.read(data, 0, recordBufsize); ? ? ? ? ? ? ? ? ? ? if (AudioRecord.ERROR_INVALID_OPERATION != read) { ? ? ? ? ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ? ? ? ? os.write(data); ? ? ? ? ? ? ? ? ? ? ? ? ? ? Log.i("audioRecordTest", "寫錄音數(shù)據(jù)->" + read); ? ? ? ? ? ? ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? os.close(); ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? recordingThread.start(); ? ? } ? ? private void stopRecord() { ? ? ? ? isRecording = false; ? ? ? ? if (audioRecord != null) { ? ? ? ? ? ? audioRecord.stop(); ? ? ? ? ? ? Log.i("audioRecordTest", "停止錄音"); ? ? ? ? ? ? audioRecord.release(); ? ? ? ? ? ? audioRecord = null; ? ? ? ? ? ? recordingThread = null; ? ? ? ? } ? ? } }
布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent" ? ? android:orientation="vertical"> ? ? <Button ? ? ? ? android:id="@+id/start_record_btn" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text="開始錄音" /> ? ? <Button ? ? ? ? android:id="@+id/stop_record_btn" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text="結(jié)束錄音" /> </LinearLayout>
運(yùn)行程序,點(diǎn)擊開始錄音,本地會(huì)創(chuàng)建test.pcm文件并寫入錄音數(shù)據(jù)。
總結(jié)
通過上面的學(xué)習(xí),對AudioRecord有初步的了解,能使用AudioRecord來實(shí)現(xiàn)錄音功能保存到本地。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android獲取相冊圖片和路徑的實(shí)現(xiàn)方法
這篇文章主要介紹了android獲取相冊圖片和路徑的實(shí)現(xiàn)方法,本文介紹的是Android4.4后的方法,感興趣的小伙伴們可以參考一下2016-04-04android 6.0 權(quán)限授權(quán)方法
今天小編就為大家分享一篇android 6.0 權(quán)限授權(quán)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07一文帶你徹底搞懂Behavior實(shí)現(xiàn)復(fù)雜的視覺聯(lián)動(dòng)效果原理
這篇文章主要為大家介紹了一文帶你徹底搞懂Behavior實(shí)現(xiàn)復(fù)雜的視覺聯(lián)動(dòng)效果原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Android開發(fā)教程之Fragment定義、創(chuàng)建與使用方法詳解【包含Activity通訊,事務(wù)執(zhí)行等】
這篇文章主要介紹了Android開發(fā)教程之Fragment定義、創(chuàng)建與使用方法,詳細(xì)介紹了Fragment的概念、功能、定義、創(chuàng)建及使用方法,包括Fragment與Activity通訊,Fragment事務(wù)執(zhí)行及Fragment應(yīng)用示例等,需要的朋友可以參考下2017-11-11Android獲取與設(shè)置系統(tǒng)環(huán)境變量的方法指南
這篇文章主要給大家介紹了關(guān)于Android獲取與設(shè)置系統(tǒng)環(huán)境變量的方法指南,文中通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Android判斷手機(jī)是否是小米MIUI系統(tǒng)的方法
這篇文章主要介紹了Android判斷手機(jī)是否是小米MIUI系統(tǒng)的方法的相關(guān)資料,需要的朋友可以參考下2016-02-02Android App開發(fā)中RecyclerView控件的基本使用教程
這篇文章主要介紹了Android App開發(fā)中RecyclerView控件的基本使用教程,RecyclerView在Android 5.0之后伴隨著Material Design出現(xiàn),管理布局方面十分強(qiáng)大,需要的朋友可以參考下2016-04-04