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; } } }