使用mediacodec播放的代码
时间: 2024-02-12 07:08:23 浏览: 112
mediaplayer代码
以下是一个简单的使用MediaCodec进行视频解码和渲染的示例代码:
```java
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private static final String TAG = "MainActivity";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private MediaExtractor mMediaExtractor;
private MediaMuxer mMediaMuxer;
private MediaCodec mMediaCodec;
private int mTrackIndex;
private boolean mIsEOS;
private boolean mIsStarted;
private long mStartTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mMediaExtractor = new MediaExtractor();
try {
mMediaExtractor.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.mp4");
} catch (IOException e) {
e.printStackTrace();
}
int trackCount = mMediaExtractor.getTrackCount();
for (int i = 0; i < trackCount; i++) {
MediaFormat format = mMediaExtractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) {
mMediaExtractor.selectTrack(i);
try {
mMediaCodec = MediaCodec.createDecoderByType(mime);
} catch (IOException e) {
e.printStackTrace();
}
mMediaCodec.configure(format, holder.getSurface(), null, 0);
break;
}
}
if (mMediaCodec == null) {
return;
}
mMediaCodec.start();
mIsStarted = true;
mStartTime = System.currentTimeMillis();
new Thread(new DecodeRunnable()).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
private void release() {
if (mMediaCodec != null) {
mMediaCodec.stop();
mMediaCodec.release();
mMediaCodec = null;
}
if (mMediaExtractor != null) {
mMediaExtractor.release();
mMediaExtractor = null;
}
if (mMediaMuxer != null) {
mMediaMuxer.stop();
mMediaMuxer.release();
mMediaMuxer = null;
}
}
private class DecodeRunnable implements Runnable {
@Override
public void run() {
ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers();
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
while (!mIsEOS) {
int inputBufferIndex = mMediaCodec.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
int sampleSize = mMediaExtractor.readSampleData(inputBuffer, 0);
if (sampleSize < 0) {
mMediaCodec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
mIsEOS = true;
} else {
long presentationTimeUs = mMediaExtractor.getSampleTime();
mMediaCodec.queueInputBuffer(inputBufferIndex, 0, sampleSize, presentationTimeUs, 0);
mMediaExtractor.advance();
}
}
int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 10000);
switch (outputBufferIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
outputBuffers = mMediaCodec.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
MediaFormat newFormat = mMediaCodec.getOutputFormat();
mTrackIndex = mMediaMuxer.addTrack(newFormat);
mMediaMuxer.start();
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
break;
default:
if (!mIsStarted) {
mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
break;
}
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
mMediaMuxer.writeSampleData(mTrackIndex, outputBuffer, bufferInfo);
mMediaCodec.releaseOutputBuffer(outputBufferIndex, true);
break;
}
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
break;
}
}
release();
}
}
}
```
这段代码使用了MediaExtractor来获取视频的格式和轨道信息,使用MediaCodec来进行视频解码,使用SurfaceView来进行视频渲染。注意,这段代码还包括了将解码后的视频数据保存到本地的功能,但这个功能并不是本代码示例的重点。
阅读全文