【发布时间】:2019-08-29 23:04:19
【问题描述】:
我已经搜索过,但仍然找不到答案。
我正在使用 API 21 中的 androids MediaCodec(使用解码器和表面)制作一个简单的视频播放器。但是,视频播放速度非常快。如何以正常速度播放视频?
这是我的代码:
package com.bd.mediacodec;
import java.io.IOException;
import java.nio.ByteBuffer;
import android.app.Activity;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaCodec.CodecException;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class DecodeActivity extends Activity implements SurfaceHolder.Callback {
private static final String SAMPLE = Environment.getExternalStorageDirectory() + "/video.mp4";
private Surface surface;
private MediaExtractor extractor;
private MediaCodec decoder;
boolean isEOS = false;
long extractorSampleTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SurfaceView sv = new SurfaceView(this);
sv.getHolder().addCallback(this);
setContentView(sv);
}
protected void onDestroy() {
super.onDestroy();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
extractor = new MediaExtractor();
try {
extractor.setDataSource(SAMPLE);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (int i = 0; i < extractor.getTrackCount(); i++) {
MediaFormat mediaFormat = extractor.getTrackFormat(i);
String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) {
extractor.selectTrack(i);
try {
decoder = MediaCodec.createDecoderByType(mime);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
surface = holder.getSurface();
decoder.configure(mediaFormat, surface, null, 0);
break;
}
}
if (decoder == null) {
Log.e("DecodeActivity", "Can't find / Open Video");
return;
}
// Adding Callback
decoder.setCallback(mDecoderCallback);
decoder.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
decoder.stop();
decoder.release();
extractor.release();
}
MediaCodec.Callback mDecoderCallback = new MediaCodec.Callback() {
@Override
public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
// TODO Auto-generated method stub
}
@Override
public void onOutputBufferAvailable(MediaCodec codec, int index,
BufferInfo info) {
// TODO Auto-generated method stub
// Release output buffer.
codec.releaseOutputBuffer(index, true);
}
@Override
public void onInputBufferAvailable(MediaCodec codec, int index) {
// TODO Auto-generated method stub
if(!isEOS){
ByteBuffer buffer = codec.getInputBuffer(index);
int sampleSize = extractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
Log.d("DecodeActivity", "InputBuffer BUFFER_FLAG_END_OF_STREAM");
decoder.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
isEOS = true;
} else {
extractorSampleTime = extractor.getSampleTime();
decoder.queueInputBuffer(index, 0, sampleSize, extractorSampleTime, 0);
extractor.advance();
}
}
}
@Override
public void onError(MediaCodec codec, CodecException e) {
// TODO Auto-generated method stub
}
};
}
【问题讨论】:
标签: android video android-video-player android-mediacodec