当前位置:   article > 正文

Android Audio——使用AudioRecord录制音频

audiorecord

一、android平台上的音频采集

Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的 API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如 AMR、MP3 等)并存成文件,而后者则更接近底层,能够更加自由灵活地控制,可以得到原始的一帧帧 PCM 音频数据。

二、AudioRecord音频采集的基本流程

  1. 构造一个 AudioRecord 对象。

  2. 开始采集。

  3. 读取采集的数据。

  4. 停止采集。

三、AudioRecord的基本参数

  •  audioSource 音频采集的来源,参考MediaRecorder.AudioSource

  •  sampleRateInHz 音频采样率

  •  channelConfig 声道,CHANNEL_IN_MONO(单声道),CHANNEL_IN_STEREO(双声道)

  •  audioFormat 音频采样精度,指定采样的数据的格式和每次采样的大小

  •  bufferSizeInBytes AudioRecord 采集到的音频数据所存放的缓冲区大小

四、AudioRecord类的主要方法

方法描述

AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

构造函数

static int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)

计算最小缓冲区大小,参数同构造函数中三个参数。

Builder setAudioSource(int audioSource)

设置音频采集来源

void startRecording()

开始录制

int read(byte[] audioData, int offsetInBytes, int sizeInBytes)

int read(ByteBuffer audioBuffer, int sizeInBytes)

int read(short[] audioData, int offsetInShorts, int sizeInShorts)

从硬件读取音频数据保存到缓冲区有三个方法,都返回读取的数据个数

void stop()

停止录制

void release()

释放资源

int getState()

获取状态

int getRecordingState()

获取录制状态

五、代码实现

1)权限

<uses-permission android:name="android.permission.RECORD_AUDIO" />

2)AudioRecord 类的接口简单封装

  1. public class AudioCapturer {
  2. private static final String TAG = "AudioCapturer";
  3. private static final int DEFAULT_SOURCE = MediaRecorder.AudioSource.MIC;
  4. private static final int DEFAULT_SAMPLE_RATE = 44100;
  5. private static final int DEFAULT_CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO;
  6. private static final int DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
  7. private AudioRecord mAudioRecord;
  8. private int mMinBufferSize = 0;
  9. private Thread mCaptureThread;
  10. private boolean mIsCaptureStarted = false;
  11. private volatile boolean mIsLoopExit = false;
  12. private OnAudioFrameCapturedListener mAudioFrameCapturedListener;
  13. public interface OnAudioFrameCapturedListener {
  14. public void onAudioFrameCaptured(byte[] audioData);
  15. }
  16. public boolean isCaptureStarted() {
  17. return mIsCaptureStarted;
  18. }
  19. public void setOnAudioFrameCapturedListener(OnAudioFrameCapturedListener listener) {
  20. mAudioFrameCapturedListener = listener;
  21. }
  22. public boolean startCapture() {
  23. return startCapture(DEFAULT_SOURCE, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_CONFIG,
  24. DEFAULT_AUDIO_FORMAT);
  25. }
  26. @SuppressLint("MissingPermission")
  27. public boolean startCapture(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat) {
  28. if (mIsCaptureStarted) {
  29. Log.e(TAG, "Capture already started !");
  30. return false;
  31. }
  32. mMinBufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig,audioFormat);
  33. if (mMinBufferSize == AudioRecord.ERROR_BAD_VALUE) {
  34. Log.e(TAG, "Invalid parameter !");
  35. return false;
  36. }
  37. Log.d(TAG , "getMinBufferSize = "+mMinBufferSize+" bytes !");
  38. mAudioRecord = new AudioRecord(audioSource,sampleRateInHz,channelConfig,audioFormat,mMinBufferSize);
  39. if (mAudioRecord.getState() == AudioRecord.STATE_UNINITIALIZED) {
  40. Log.e(TAG, "AudioRecord initialize fail !");
  41. return false;
  42. }
  43. mAudioRecord.startRecording();
  44. mIsLoopExit = false;
  45. mCaptureThread = new Thread(new AudioCaptureRunnable());
  46. mCaptureThread.start();
  47. mIsCaptureStarted = true;
  48. Log.d(TAG, "Start audio capture success !");
  49. return true;
  50. }
  51. public void stopCapture() {
  52. if (!mIsCaptureStarted) {
  53. return;
  54. }
  55. mIsLoopExit = true;
  56. try {
  57. mCaptureThread.interrupt();
  58. mCaptureThread.join(1000);
  59. }
  60. catch (InterruptedException e) {
  61. e.printStackTrace();
  62. }
  63. if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
  64. mAudioRecord.stop();
  65. }
  66. mAudioRecord.release();
  67. mIsCaptureStarted = false;
  68. mAudioFrameCapturedListener = null;
  69. Log.d(TAG, "Stop audio capture success !");
  70. }
  71. private class AudioCaptureRunnable implements Runnable {
  72. @Override
  73. public void run() {
  74. while (!mIsLoopExit) {
  75. byte[] buffer = new byte[mMinBufferSize];
  76. int ret = mAudioRecord.read(buffer, 0, mMinBufferSize);
  77. if (ret == AudioRecord.ERROR_INVALID_OPERATION) {
  78. Log.e(TAG , "Error ERROR_INVALID_OPERATION");
  79. }
  80. else if (ret == AudioRecord.ERROR_BAD_VALUE) {
  81. Log.e(TAG , "Error ERROR_BAD_VALUE");
  82. }
  83. else {
  84. if (mAudioFrameCapturedListener != null) {
  85. mAudioFrameCapturedListener.onAudioFrameCaptured(buffer);
  86. }
  87. Log.d(TAG , "OK, Captured "+ret+" bytes !");
  88. }
  89. SystemClock.sleep(10);
  90. }
  91. }
  92. }
  93. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/980093
推荐阅读
相关标签
  

闽ICP备14008679号