最近做到這個需求,在網上找不到類似的就自己擼了一個
1.首先獲取錄音的分貝值
private void updateMicStatus() {
if(recorder != null && isRecord) {
int ratio = recorder.getMaxAmplitude() / BASE;
int db = 0;// 分貝
if(ratio > 1)
db = (int) (20 * Math.log10(ratio));
final double finalDb = db;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
((VoiceWave) activity.findViewById(R.id.videoView)).setDecibel((int) finalDb);
}
});
mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
}
}
2.創建數據源
private void initData(int decibel) {
int quietDecibel;
if(isHeadSetOn) {
quietDecibel = 70;//耳機比較敏感
} else {
quietDecibel = 60;
}
boolean isQuiet;
if(decibel < quietDecibel) {
isQuiet = true;
} else {
isQuiet = false;
}
int base = (int) ((decibel-quietDecibel) / 30f * 100);//quietDecibel是最低分貝 40是最高90分貝-50分貝,90是基數區間0-90的最大值
if(base < 0) {
base = 0;
}
Logger.i(TAG, "分貝:"+decibel);
if(dataList != null) {
dataList.clear();
}
dataList.add(new Bean(1, 20, 30));
dataList.add(new Bean(2, 20, 30));
dataList.add(new Bean(3, isQuiet ? 30 : base+35, 20));//v
dataList.add(new Bean(4, 20, 30));
dataList.add(new Bean(5, 30, isQuiet ? 20 : base+20));
dataList.add(new Bean(6, isQuiet ? 20 : base+20, 30));//v
dataList.add(new Bean(7, 30, isQuiet ? 20 : base+20));//v
dataList.add(new Bean(8, isQuiet ? 20 : base+50, 30));//10
dataList.add(new Bean(9, 20, isQuiet ? 30 : base+30));
dataList.add(new Bean(10, isQuiet ? 20 : base+20, 30));//
dataList.add(new Bean(11, 30, isQuiet ? 20 : base+50));//35
dataList.add(new Bean(12, isQuiet ? 20 : base+50, 30));//50
//-----------------------------------------------------
dataList.add(new Bean(13, 30, isQuiet ? 20 : base+70));//70
//-----------------------------------------------------
dataList.add(new Bean(14, isQuiet ? 20 : base+50, 30));//50
dataList.add(new Bean(15, 30, isQuiet ? 20 : base+50));//35
dataList.add(new Bean(16, isQuiet ? 20 : base+20, 30));//35
dataList.add(new Bean(17, 20, isQuiet ? 30 : base+30));
dataList.add(new Bean(18, isQuiet ? 20 : base+50, 30));//20
dataList.add(new Bean(19, 30, isQuiet ? 20 : base+20));//50
dataList.add(new Bean(20, isQuiet ? 20 : base+20, 30));//20
dataList.add(new Bean(21, 30, isQuiet ? 20 : base+20));//20
dataList.add(new Bean(22, 20, 30));
dataList.add(new Bean(23, isQuiet ? 30 : base+35, 20));
dataList.add(new Bean(24, 20, 30));//20
dataList.add(new Bean(25, 20, 30));
}
3.繪製wave
根據分貝值循環繪製每一幀,比如說話的分貝值是80,那麼在獲取分貝值的回調裏就會持續傳入80給view,在這裏繪製,把這個80分成四段,第一段繪製最短的(20),然後次短(40),次長(60),最長(80),繪製四次形成動畫,
那麼當分貝持續變化的時候,音浪也就波動出現啦
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
Resources resources = getContext().getResources();
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
float rate = displayMetrics.scaledDensity;
int baseX = getMeasuredWidth() / 2-((7+3) * 25 / 2);
canvas.translate(0, getMeasuredHeight() / 2);
for(int i = 0; i < dataList.size(); i++) {
final Bean bean = dataList.get(i);
//間隔間距
int grep = 10;
if(flag1) {//2 6 繪製次短
int m1 = (int) (bean.getShortV() * heightRate+((bean.getLongV() * heightRate-bean.getShortV() * heightRate) / 3));
canvas.drawLine(baseX+grep * i, m1 / 2 / 2f * rate, baseX+grep * i, -m1 / 2 / 2f * rate, paint);
if(i == dataList.size()-1) {
flag1 = false;
}
} else {//
if(flag2) {//3 5 繪製次長
if(i == dataList.size()-1) {
flag2 = false;
if(!flag3) {
flag1 = true;
}
}
int m2 = (int) (bean.getLongV() * heightRate-((bean.getLongV() * heightRate-bean.getShortV() * heightRate) / 3));
canvas.drawLine(baseX+grep * i, m2 / 2 / 2f * rate, baseX+grep * i, -m2 / 2 / 2f * rate, paint);
} else {
if(flag3) {//4 繪製最長
if(i == dataList.size()-1) {
flag3 = false;
flag2 = true;
}
canvas.drawLine(baseX+grep * i, bean.getLongV() * heightRate / 2 / 2f * rate, baseX+grep * i, -bean.getLongV() * heightRate / 2 / 2f * rate, paint);
} else {//1 7 繪製最短
canvas.drawLine(baseX+grep * i, bean.getShortV() * heightRate / 2 / 2f * rate, baseX+grep * i, -bean.getShortV() * heightRate / 2 / 2f * rate, paint);
if(i == dataList.size()-1) {
flag3 = true;
flag2 = true;
flag1 = true;
}
}
}
}
}
}
------------------------免費的demo地址---------------------