前言
相关文章摘抄过,但由于不是自己写的或者敲过代码,后面就忘了。
本站主要简单的介绍AudioRecord的使用。
好记性不如烂笔头
正文
Android录音的流程:
- 构造一个AudioRecord对象,其中需要的最小录音缓存buffer大小可以通过getMinBufferSize方法得到。如果buffer容量过小,将导致对象构造的失败。
- 初始化一个buffer,该buffer大于等于AudioRecord对象用于写声音数据的buffer大小。
- 开始录音
- 创建一个数据流,一边从AudioRecord中读取声音数据到初始化的buffer,一边将buffer中数据导入数据流。
- 关闭数据流
- 停止录音
AudioRecord参数简介
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,int bufferSizeInBytes)
- audioSource 音频采集的输入源。
public static final int MIC = 1; //表示手机麦克风输入
- sampleRateInHz采样率
录音设备1S内对声音信号的采集次数,单位Hz
目前44100Hz是唯一可以保证兼容所有Android手机的采样率。
- channelConfig 通道数的配置
AudioFormat中有如下定义:
public static final int CHANNEL_IN_LEFT = 0x4; public static final int CHANNEL_IN_RIGHT = 0x8; public static final int CHANNEL_IN_FRONT = 0x10; //单通道 public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT; //双通道 public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
- audioFormat 音频数据位宽配置
用来配置数据位宽,有如下选项:
public static final int ENCODING_PCM_16BIT = 2; public static final int ENCODING_PCM_8BIT = 3;
- bufferSizeInBytes 音频缓冲区大小
该值不能低于一帧音频帧的大小。
计算方式:
int size = 采样率 * 采样时间 * 位宽 * 通道数
其中采样时间一般取2.5ms~120ms,具体取多少由厂商或者应用决定。
每一帧采样的时间越短,产生的延时越小,但碎片化的数据也会越多。
这个值有接口直接获取,不需要我们计算。
static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)
AudioRecord的主要方法
//开始录制 audioRecord.startRecording(); //停止录制 audioRecord.stop(); //读取录音数据 audioRecord.read(bytes,0,bytes.length);
代码片段
权限配置和获取
- AndroidManifest.xml 配置需要的权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
- 动态申请权限
由于Android 6.0后,权限申请严格,因此需要手动申请权限:
在Activity中主动申请
//2 是requestCode PermissionUtils.requestPermission(this, 2); //重写(下面只是打印日志) @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); Log.d(TAG, "onRequestPermissionsResult requestCode : " + requestCode); if (requestCode == 2) { for (int i = 0; i < permissions.length; i++) { Log.d(TAG, "onRequestPermissionsResult : " + permissions[i] + " grantResults : " + grantResults[i]); } } }
public class PermissionUtils { private static final String TAG = MyApp.TAG + PermissionUtils.class.getSimpleName(); /** * 需要申请的权限 */ public static final String REQUEST_MANIFEST_PERMISSION[] = new String[]{ Manifest.permission.RECORD_AUDIO }; /** * Android 6.0后非系统应用需要申请权限 * * @param activity * @param requestCode */ public static void requestPermission(Activity activity, int requestCode) { if (null == activity) { Log.d(TAG, "requestPermission null : "); return; } Log.d(TAG, "requestPermission requestCode : " + requestCode); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ActivityCompat.requestPermissions(activity, REQUEST_MANIFEST_PERMISSION, requestCode); } return; } }
AudioRecord封装代码
下面是封装的RecordUtils代码。
public class RecordUtils { private static String TAG = MyApp.TAG + RecordUtils.class.getSimpleName(); private static final int DEFAULT_SOURCE = MediaRecorder.AudioSource.MIC; //麦克风 private static final int DEFAULT_RATE = 44100; //采样率 private static final int DEFAULT_CHANNEL = AudioFormat.CHANNEL_IN_STEREO; //双通道(左右声道) private static final int DEFAULT_FORMAT = AudioFormat.ENCODING_PCM_16BIT; //数据位宽16位 private static AudioRecord mAudioRecord = null; private static int mMinBufferSize = 0; private static boolean isRecording = false; private static RecordThread mRecordThread = null; private static IRecordBufferListener mIRecordBufferListener = null; /** * start record */ public static void startRecord() { mMinBufferSize = AudioRecord.getMinBufferSize(DEFAULT_RATE, DEFAULT_CHANNEL, DEFAULT_FORMAT); Log.d(TAG, "startRecord mMinBufferSize : " + mMinBufferSize); if (mMinBufferSize == AudioRecord.ERROR_BAD_VALUE) { Log.d(TAG, "startRecord error 1 "); return; } mAudioRecord = new AudioRecord(DEFAULT_SOURCE, DEFAULT_RATE, DEFAULT_CHANNEL, DEFAULT_FORMAT, mMinBufferSize); if (null == mAudioRecord || mAudioRecord.getState() == AudioRecord.STATE_UNINITIALIZED) { Log.d(TAG, "startRecord error 2 "); return; } //启动录音 mAudioRecord.startRecording(); //设置录音标志位 isRecording = true; //使用线程读取录音数据 mRecordThread = new RecordThread(); mRecordThread.start(); return; } /** * stop record */ public static void stopRecord() { Log.d(TAG, "stopRecord mAudioRecord : " + mAudioRecord); isRecording = false; //暂停录音线程 if (null != mRecordThread) { try { mRecordThread.join(); mRecordThread = null; } catch (InterruptedException e) { e.printStackTrace(); } } //停止录音 if (null != mAudioRecord) { Log.d(TAG, "stopRecord getRecordingState() : " + mAudioRecord.getRecordingState()); mAudioRecord.stop(); mAudioRecord.release(); mAudioRecord = null; Log.d(TAG, "stopRecord: "); } return; } /** * 录音线程 */ private static class RecordThread extends Thread { @Override public void run() { super.run(); byte[] buffer = null; while (isRecording) { buffer = new byte[mMinBufferSize]; int result = mAudioRecord.read(buffer, 0, buffer.length); Log.d(TAG, "startRecord result : " + result + " isRecording : " + isRecording); } } } }
参考文章
历史上的今天
暂无评论...
随机推荐
You must not call setTag() on a view Glide is targeting
前言记录一下,在使用Glide 老的版本(相对于4之前的)出现如下一下,记录于此,方便自己查阅。正文异常日志:AndroidRuntime( 4299): FATAL EXCEPTION: mainAndroidRuntime( 4299): Process: com.biumall.v...
[转]Android音频: 如何使用AudioTrack播放一个WAV格式文件?
抱歉,这篇文章代码不全,转载时没有尝试实现推荐看我新写的文章《AudioTrack简单简介之四:wav去掉文件头之解决爆音》如果你已经成功地了解了关于AudioTrack的一些话题,那么你可能享受它带来的好处,例如低延迟(在STATIC(静态)模式),能够生成流式音频(在STREAM(流)模...
常用的简单monkey测试命令集合
前言Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行测试。Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。正文下面整理了一下黑名单和白名单...
[代码片段]MediaCode 播放Video中的视频帧[无声]
前言这就只做使用MediaCodec+SurfaceView播放视频PS 这里不涉及音频播放,只显示视频帧出来。正文这里只简单记录一下,推荐看我参考的文章,我用的就是他的代码。原理通过MediaExtractor获取媒体的编码信息[Track索引,MediaMime,MediaFor...
Android studio优先引用framework.jar
前言记录一下Android Studio中编译apk优先使用自己编译的framework_classes.jar,这样就不会提示找不到资源啥的。网上也很多,但我这没成功,猜测可能跟Android Studio版本有关系。下面时我当前使用的版本,虽然又新版本,懒得更新。Android St...
U盘分区格式的优缺点简介
FAT16、FAT32、NTFS、ExFAT正文FAT16:优点:兼容性最好,某些数码设备可能对FAT32和NTFS格式的存储卡支持不太好,因此只能使用FAT16。缺点:最大仅支持2GB分区,空间浪费大。FAT32:优点:兼容性好。缺点:单个文件不能超过4GB,不支...