首先添加录音权限
<uses-permission android:name="android.permission.RECORD_AUDIO"/>方式一:MediaRecorder
private MediaRecorder mediaRecorder;
private boolean isRecording;
设置存储路径
private final String FILE = Environment.getExternalStorageDirectory() + File.separator + "volomeDemo.aac";
初始化mediaRecorder
initMediaRecorder();
public void initMediaRecorder() { mediaRecorder = new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setOutputFile(FILE); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); Log.w("madiarecorder","初始化成功"); try{ mediaRecorder.prepare(); mediaRecorder.start(); isRecording=true; Log.w("madiarecorder","已启动"); }catch(Exception e) { Log.w("madiarecorder","异常"); } }
利用
mediaRecorder.getMaxAmplitude();
得到当前某一时刻检测到的音量,这个数值通常可以上万
创建一个可视的绘图线程,一会儿实时将音量绘制出来
class Draw_thread extends Thread { @Override public void run(){ while(true) { if (mediaRecorder == null) { initMediaRecorder(); } try{ myDraw(); Thread.sleep(30); } catch (Exception e) { Log.w("线程", "异常"); } } } }
利用
isRecording
记录是否在监听中
重写销毁方法
protected void onDestroy() { super.onDestroy(); if (mediaRecorder!=null&&isRecording) { isRecording = false; mediaRecorder.stop(); mediaRecorder.reset(); mediaRecorder.release(); mediaRecorder = null; } }
方法二:AudioRecord
声明变量
private AudioRecord audioRecord; private int bufferSize; private byte[] buffer;
初始化函数
public void initAudioRecord() { bufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO , AudioFormat.ENCODING_PCM_16BIT); audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); audioRecord.startRecording(); // 用于读取的 buffer buffer= new byte[bufferSize]; }
在绘图线程中获取某一时刻音量,和mediaRecorder.getMaxAmplitude();作用差不多
try { int r = audioRecord.read(buffer, 0, bufferSize); int v = 0; // 将 buffer 内容取出,进行平方和运算 for (int i = 0; i < buffer.length; i++) { // 这里没有做运算的优化,为了更加清晰的展示代码 v += buffer[i] * buffer[i]; } // 平方和除以数据总长度,得到音量大小。可以获取白噪声值,然后对实际采样进行标准化。 // 如果想利用这个数值进行操作,建议用 sendMessage 将其抛出,在 Handler 里进行处理。 double dB = 10*Math.log10(v/(double)r);
得到的db就是当前音量大小
但是这个数值基本只能用来判断有没有声音,
而分别不出来音量大小,所以建议使用第一种方式
绘图函数
canvas.drawColor(Color.BLACK);//背景 canvas.drawLine(200,250,200,250-6*(int)dB,paint);//子线程更新UI,如果是监听器等调用的函数,是属于主线程里的!!! canvas.drawText(7*(int)dB+"",150,30,paint); int maxa=mediaRecorder.getMaxAmplitude(); if(maxa<1600) { canvas.drawLine(100,250,100,250-maxa/8,paint); } else { canvas.drawLine(100,250,100,50,paint); paint.setColor(Color.RED); canvas.drawLine(150,250,150,250-maxa/100,paint); paint.setColor(Color.GREEN); } canvas.drawText(maxa+"",30,30,paint); mHandler.post(new Runnable() { @Override public void run() { iv_audio.setImageBitmap(bitmap); } });
用了draw和paint展示了一下两种方式的效果
我将第一种方法获得的音量用绿色(小数值时)+红色(大数值时)显示出来
这个绿色随着声音的增大,变化明显
而第二种方式,基本只要有点声音,绿色就满了
没声音时数值,还可能为负值
所以第一种好用