網(wǎng)站首頁 編程語言 正文
前言
Android使用AudioRecord實現(xiàn)錄音
提示:以下是本篇文章正文內容,下面案例可供參考
一、AudioRecord使用
Android平臺可以使用AudioRecord和MediaRecorder來實現(xiàn)錄音,因為AudioRecord更接近底層,并且錄制的數(shù)據(jù)為原始(pcm)數(shù)據(jù),pcm數(shù)據(jù)可以再進行處理轉換,直播中使用的都是處理后的pcm數(shù)據(jù),所以在這里面學習下使用AudioRecord。
- 構造AudioRecord
AudioRecord類的構造方法中有5個參數(shù)
/**
* audioSource 表示數(shù)據(jù)來源 一般為麥克風 MediaRecorder.AudioSource.MIC
* sampleRateInHz 表示采樣率 一般設置為 44100
* channelConfig 表示聲道 一般設置為 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);
? ? }
- 開始錄音
// 調用開始錄音
audioRecord.startRecording();
調用開始錄音后,需要從audioRecord中讀取錄音的數(shù)據(jù)
audioRecord.read(data, 0, recordBufsize);
- 結束錄音
audioRecord.stop();
- 釋放資源
audioRecord.release();
AudioRecord的關鍵方法已經(jīng)介紹了,下面貼上完整的代碼
二、使用步驟
清單文件聲明權限
<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" />
關于Android 6.0動態(tài)申請權限這里就不重復了,可自行百度
完整代碼
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="結束錄音" /> </LinearLayout>
運行程序,點擊開始錄音,本地會創(chuàng)建test.pcm文件并寫入錄音數(shù)據(jù)。
總結
通過上面的學習,對AudioRecord有初步的了解,能使用AudioRecord來實現(xiàn)錄音功能保存到本地。
原文鏈接:https://blog.csdn.net/zhe_ge_sha_shou/article/details/112393401
相關推薦
- 2023-01-30 VMware?Tools?啟動腳本未能在虛擬機中成功運行的兩種解決方法_VMware
- 2022-06-20 C語言三種方法解決輪轉數(shù)組問題_C 語言
- 2022-11-01 C語言strlen,strcpy,strcmp,strcat,strstr字符串操作函數(shù)實現(xiàn)_C 語
- 2022-01-10 cookie localstorage sessionstorage的區(qū)別
- 2022-09-07 python輸入、數(shù)據(jù)類型轉換及運算符方式_python
- 2022-06-25 Python編程批量實現(xiàn)md5加密pdf文件_python
- 2022-07-15 使用Android原生WebView+Highcharts實現(xiàn)可左右滑動的折線圖_Android
- 2022-12-21 Redis?RDB與AOF持久化方式詳細講解_Redis
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支