親手擼一個錄音分貝波浪圖展示view

效果圖

最近做到這個需求,在網上找不到類似的就自己擼了一個

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地址---------------------

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章