安卓开发笔记Android的数据处理方案音视频

Android MP3录制,波形显示,音频权限兼容与播放

2016-11-15  本文已影响8883人  恋猫月亮
我又来掀桌子了(ノಠ益ಠ)ノ彡┻━┻,这次是MP3录制和显示声音波形的一个故事。

</p>
Demo :https://github.com/CarGuo/RecordWave

先看看效果┑( ̄Д  ̄)┍

2 1

增加权限提示

</p>

···
try {
    mAudioRecord.startRecording();
} catch (Exception ex) {
    ex.printStackTrace();
}
···
while (mIsRecording) {
    int readSize = mAudioRecord.read(mPCMBuffer, 0, mBufferSize);
    if (readSize == AudioRecord.ERROR_INVALID_OPERATION ||
            readSize == AudioRecord.ERROR_BAD_VALUE) {
        if (errorHandler != null && !sendError) {
            sendError = true;
            errorHandler.sendEmptyMessage(ERROR_TYPE);
            mIsRecording = false;
            isError = true;
        }
    } else {

        if (readSize > 0) {
            mEncodeThread.addTask(mPCMBuffer, readSize);
            calculateRealVolume(mPCMBuffer, readSize);
            sendData(mPCMBuffer, readSize);
        } else {
            if (errorHandler != null && !sendError) {
                sendError = true;
                errorHandler.sendEmptyMessage(ERROR_TYPE);
                mIsRecording = false;
                isError = true;
            }
        }
    }
}

再采样(这个词看起来很高端的样子)

private void sendData(short[] shorts, int readSize) {
  if (dataList != null) {
        int length = readSize / 300;
        short resultMax = 0, resultMin = 0;
        for (short i = 0, k = 0; i < length; i++, k += 300) {
            for (short j = k, max = 0, min = 1000; j < k + 300; j++) {
                if (shorts[j] > max) {
                    max = shorts[j];
                    resultMax = max;
                } else if (shorts[j] < min) {
                    min = shorts[j];
                    resultMin = min;
                }
            }
            if (dataList.size() > maxSize) {
                dataList.remove(0);
            }
            dataList.add(resultMax);
        }
    }
}

根据音频数据绘制波形

</p>
1、首先,你得有一个女····呸呸呸,你要有一个View,自定义一个View用来绘制,绘制的逻辑有这么几个:

是不是很简单呢?是啊~确实很简单( ̄o ̄) .那到这里就结束88咯。

咦,下面还有啊 (ˉ▽ ̄~) 切~~

@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
    super.onVisibilityChanged(changedView, visibility);
    if (visibility == VISIBLE && mBackgroundBitmap == null) {
        ViewTreeObserver vto = getViewTreeObserver();
        vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                if (getWidth() > 0 && getHeight() > 0) {
                    mWidthSpecSize = getWidth();
                    mHeightSpecSize = getHeight();
                    mBaseLine = mHeightSpecSize / 2;
                    mBackgroundBitmap = Bitmap.createBitmap(mWidthSpecSize, mHeightSpecSize, Bitmap.Config.ARGB_8888);
                    mBitmap = Bitmap.createBitmap(mWidthSpecSize, mHeightSpecSize, Bitmap.Config.ARGB_8888);
                    mBackCanVans.setBitmap(mBackgroundBitmap);
                    mCanvas.setBitmap(mBitmap);
                    ViewTreeObserver vto = getViewTreeObserver();
                    vto.removeOnPreDrawListener(this);
                }
                return true;
            }
        });
    }
}
/**
 * 根据当前块数据来判断缩放音频显示的比例
 *
 * @param list 音频数据
 */
private void resolveToWaveData(ArrayList<Short> list) {
    short allMax = 0;
    for (Short sh : list) {
        if (sh > allMax) {
            allMax = sh;
        }
    }
    int curScale = allMax / mBaseLine;
    if (curScale > mScale) {
        mScale = ((curScale == 0) ? 1 : curScale);
    }
}

首先把bitmap洗干净drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);,然后绘制基线,接着就是for循环绘制音频线了。
绘制以基线为轴,每个音频数据除以缩放系数(需要考虑乘的情况?反正我bu care~),然后绘制上下的竖线,之后把这个bitmap绘制到要完整显示的mBackgroundBitmap,最后通知界面更新(发到UI线程),然后界面把要显示的mBackgroundBitmap贴出来。

 if (mBackCanVans != null) {
    //洗白白
    mBackCanVans.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    mBackCanVans.drawLine(0, mBaseLine, mWidthSpecSize, mBaseLine, mPaint);
    int drawBufsize = dataList.size();
    //判断大小,是否改变显示的比例
    for (int i = 0, j = 0; i < drawBufsize; i++, j += mOffset) {
        Short sh = dataList.get(i);
        short max = (short) (mBaseLine - sh / mScale);
        short min;
        if (mWaveCount == 2) {
            min = (short) (sh / mScale + mBaseLine);
        } else {
            min = (short) (mBaseLine);
        }
        mBackCanVans.drawLine(j, mBaseLine, j, max, mPaint);
        mBackCanVans.drawLine(j, min, j, mBaseLine, mPaint);

    }
    synchronized (mLock) {
        mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        mCanvas.drawBitmap(mBackgroundBitmap, 0, 0, mPaint);
    }
    Message msg = new Message();
    msg.what = 0;
    handler.sendMessage(msg);
}

···
@Override
protected void onDraw(Canvas c) {
    super.onDraw(c);
    if (mIsDraw && mBitmap != null) {
        synchronized (mLock) {
            c.drawBitmap(mBitmap, 0, 0, mViewPaint);
        }
    }
}

音频播放AudioPlayer

</p>

最后~欢迎来个人的<a href="https://github.com/CarGuo">Github</a>

一定要来哈
上一篇下一篇

猜你喜欢

热点阅读