1MedieCodec支持4.1以上系统使用,是谷歌SDK的一个类。
2能够对mp3,wma格式音频文件解码
3解码前,需要MediaExactor提取文件信息,包括文件类型,采样率,
package com.dawin.mediacodec; import java.io.IOException; import java.nio.ByteBuffer; import android.media.MediaCodec; import android.media.MediaExtractor; import android.media.MediaFormat; import android.media.MediaCodec.BufferInfo; public class MediaCodecTest { byte[] decodeData = new byte[1024 * 1024 * 20];// 20m MediaCodec mMediaCodec; MediaExtractor mediaExtractor; MediaFormat mMediaFormat; final int TIMEOUT_US = 1000; BufferInfo info; boolean sawOutputEOS = false; boolean sawInputEOS = false; ByteBuffer[] codecInputBuffers; ByteBuffer[] codecOutputBuffers; /** * 解码音频文件,返回最后解码的数据 * * @param url * @return */ public byte[] decode(String url) { url = ""; try { mediaExtractor.setDataSource(url); } catch (IOException e) { } mMediaFormat = mediaExtractor.getTrackFormat(0); String mime = mMediaFormat.getString(MediaFormat.KEY_MIME); try { mMediaCodec = MediaCodec.createDecoderByType(mime); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mMediaCodec.configure(mMediaFormat, null, null, 0); mMediaCodec.start(); codecInputBuffers = mMediaCodec.getInputBuffers(); codecOutputBuffers = mMediaCodec.getOutputBuffers(); info = new BufferInfo(); mediaExtractor.selectTrack(0); input(); output(); return decodeData; } private void output() { final int res = mMediaCodec.dequeueOutputBuffer(info, TIMEOUT_US); if (res >= 0) { int outputBufIndex = res; ByteBuffer buf = codecOutputBuffers[outputBufIndex]; final byte[] chunk = new byte[info.size]; buf.get(chunk); // Read the buffer all at once buf.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS // SAME BUFFER BAD THINGS WILL HAPPEN if (chunk.length > 0) { System.arraycopy(chunk, 0, decodeData, 0, chunk.length); // mAudioTrack.write(chunk, 0, chunk.length); } mMediaCodec.releaseOutputBuffer(outputBufIndex, false /* render */); if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { sawOutputEOS = true; } } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { codecOutputBuffers = mMediaCodec.getOutputBuffers(); } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { final MediaFormat oformat = mMediaCodec.getOutputFormat(); // Log.d(LOG_TAG, "Output format has changed to " + oformat); // mAudioTrack.setPlaybackRate(oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE)); } } private void input() { int inputBufIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_US); if (inputBufIndex >= 0) { ByteBuffer dstBuf = codecInputBuffers[inputBufIndex]; int sampleSize = mediaExtractor.readSampleData(dstBuf, 0); // Log.i(LOG_TAG, "sampleSize : "+sampleSize); long presentationTimeUs = 0; if (sampleSize < 0) { // .Log.i(LOG_TAG, "Saw input end of stream!"); sawInputEOS = true; sampleSize = 0; } else { presentationTimeUs = mediaExtractor.getSampleTime(); // Log.i(LOG_TAG, "presentationTimeUs "+presentationTimeUs); } mMediaCodec.queueInputBuffer(inputBufIndex, 0, // offset sampleSize, presentationTimeUs, sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0); if (!sawInputEOS) { // Log.i(LOG_TAG, "extractor.advance()"); mediaExtractor.advance(); } } } }
时间: 2024-12-18 11:36:50