MediaExtractor/MediaCodec 把 mp3 转化 pcm ,解码 为类似麦克输入的 数据byte源文件

public boolean Start() {
    mExtractor = new MediaExtractor();
    try {
        mExtractor.setDataSource(Environment.getExternalStorageDirectory() + "/8000PCM16.mp3");
        mExtractor.selectTrack(0);
        MediaFormat inputFormat = mExtractor.getTrackFormat(0);// 设置轨道0
        if (!inputFormat.getString(MediaFormat.KEY_MIME).startsWith("audio")) {
            LUtils.e(TAG, "not audio");
            return false;
        }
        mDecoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
        mDecoder.configure(inputFormat, null, null, 0);
        mDecoder.start();
    } catch (IOException e) {
        e.printStackTrace();
    }

    super.start();
    LUtils.d(TAG, "Start=====");
    return true;

}
public void run() {

    ByteBuffer[] inputBuffers = mDecoder.getInputBuffers();
    ByteBuffer[] outputBuffers = mDecoder.getOutputBuffers();
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); //缓冲区
    //            info.size = 640; //设置output buffer 的大小
    while (true) {
        int inIndex = mDecoder.dequeueInputBuffer(TIMEOUT_US);
        if (inIndex >= 0) {
            ByteBuffer buffer = inputBuffers[inIndex];
            //从MediaExtractor中读取一帧待解的数据
            int sampleSize = mExtractor.readSampleData(buffer, 0);
            //小于0 代表所有数据已读取完成
            if (sampleSize < 0) {
                Log.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");
                mDecoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            } else {
                //插入一帧待解码的数据
                mDecoder.queueInputBuffer(inIndex, 0, sampleSize, mExtractor.getSampleTime(), 0);
                //MediaExtractor移动到下一取样处
                mExtractor.advance();
            }
        }
        int outIndex = mDecoder.dequeueOutputBuffer(info, TIMEOUT_US);
        Log.i(TAG, "1111run: info.size" + info.size);
        Log.i(TAG, "1111run: info.flags" + info.flags);
        switch (outIndex) {
            case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
                outputBuffers = mDecoder.getOutputBuffers();
                break;
            case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
                //  MediaFormat format = mDecoder.getOutputFormat();
                //  audioTrack.setPlaybackRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
                break;
            case MediaCodec.INFO_TRY_AGAIN_LATER:
                break;
            default:
                ByteBuffer outBuffer = outputBuffers[outIndex];
                //BufferInfo内定义了此数据块的大小
                final byte[] chunk = new byte[info.size];
                Log.i(TAG, "run: info.size" + info.size);
                //  createFileWithByte(chunk);
                //将Buffer内的数据取出到字节数组中
                outBuffer.get(chunk);
                //数据取出后一定记得清空此Buffer MediaCodec是循环使用这些Buffer的,不清空下次会得到同样的数据
                outBuffer.clear();
                try {
                    //TODO 在这里处理解码后的数据
                    //将解码出来的PCM数据IO流存入本地文件。
                    //fos.write(chunk);
                    int vnum;
                    if (chunk.length % 640 == 0) {
                        //                // ==0
                        vnum = chunk.length / 640;
                    } else {
                        vnum = chunk.length / 640 + 1;
                    }
                    byte[] bytes = new byte[640];
                    for (int v = 0; v < vnum; v++) {
                        if (v != vnum - 1) {
                            //1 初始数据 2  从元数据的起始位置开始 3 目标数组 4 目标数组的开始起始位置 5  要copy的数组的长度
                            System.arraycopy(chunk, v * 640, bytes, 0, 640);
                        } else {
                            System.arraycopy(chunk, v * 640, bytes, 0, chunk.length - v * 640);
                            LUtils.d(TAG, "buffer.length - v * 640=====" + (chunk.length - v * 640));
                        }
                        LUtils.d(TAG, "buffer.length=====" + bytes.length);
                        LUtils.d(TAG, "buffer.length=====" + Arrays.toString(bytes));
                        FunSupport.getInstance().requestDeviceSendTalkData(
                                mFunDevice, bytes, bytes.length);
                        Log.d(TAG, "1111111111111111111" + Arrays.toString(bytes));
                        Log.d(TAG, "1111111111111111111=========" + bytes.length);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                //此操作一定要做,不然MediaCodec用完所有的Buffer后 将不能向外输出数据
                mDecoder.releaseOutputBuffer(outIndex, false);
                break;
        }
        if (info.flags != 0) {
            Log.i(TAG, "解码完毕++++++++++++++");
            break;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/xiaoniu_my/article/details/85343671