android下使用FFMpeg的VAAPI播放视频并显示到SurfaceView的代码
时间: 2024-03-19 22:45:17 浏览: 18
很抱歉,Android系统不支持 VAAPI,它是用于 Linux 等操作系统的视频加速 API。在 Android 中,可以使用硬件加速来加速视频播放,例如使用 MediaCodec 和 SurfaceView 进行视频解码和渲染。下面是一个简单的示例代码:
```java
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaCodec.BufferInfo;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import java.nio.ByteBuffer;
public class VideoPlayer implements SurfaceHolder.Callback {
private SurfaceView mSurfaceView;
private Surface mSurface;
private MediaExtractor mExtractor;
private MediaCodec mDecoder;
private boolean mIsPlaying;
public VideoPlayer(SurfaceView surfaceView) {
mSurfaceView = surfaceView;
mSurfaceView.getHolder().addCallback(this);
}
public void play(String videoPath) throws IOException {
mExtractor = new MediaExtractor();
mExtractor.setDataSource(videoPath);
int trackIndex = selectTrack(mExtractor);
mExtractor.selectTrack(trackIndex);
MediaFormat mediaFormat = mExtractor.getTrackFormat(trackIndex);
String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
mDecoder = MediaCodec.createDecoderByType(mime);
mDecoder.configure(mediaFormat, mSurface, null, 0);
mDecoder.start();
ByteBuffer[] inputBuffers = mDecoder.getInputBuffers();
ByteBuffer[] outputBuffers = mDecoder.getOutputBuffers();
BufferInfo bufferInfo = new BufferInfo();
mIsPlaying = true;
while (mIsPlaying) {
int inputBufferIndex = mDecoder.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
int sampleSize = mExtractor.readSampleData(inputBuffer, 0);
if (sampleSize < 0) {
mDecoder.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
mIsPlaying = false;
} else {
long presentationTimeUs = mExtractor.getSampleTime();
mDecoder.queueInputBuffer(inputBufferIndex, 0, sampleSize, presentationTimeUs, 0);
mExtractor.advance();
}
}
int outputBufferIndex = mDecoder.dequeueOutputBuffer(bufferInfo, 10000);
switch (outputBufferIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
outputBuffers = mDecoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
// do nothing
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
// do nothing
break;
default:
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
mDecoder.releaseOutputBuffer(outputBufferIndex, true);
break;
}
}
mDecoder.stop();
mDecoder.release();
mExtractor.release();
}
private int selectTrack(MediaExtractor extractor) {
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; i++) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) {
return i;
}
}
return -1;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mSurface = holder.getSurface();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// do nothing
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mSurface = null;
}
}
```
使用示例:
```java
VideoPlayer player = new VideoPlayer(surfaceView);
try {
player.play(videoPath);
} catch (IOException e) {
e.printStackTrace();
}
```