gpt4 book ai didi

安卓 MediaCodec 解码器 : Slow Down Video Playback

转载 作者:行者123 更新时间:2023-11-29 15:56:59 31 4
gpt4 key购买 nike

我已经搜索过,但仍然找不到答案。

我正在使用 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

}
};

}

最佳答案

Grafika中有一对简单的视频播放器,一种用于 SurfaceView,一种用于 TextureView。他们都使用 SpeedControlCallback管理播放速度的类。关键是使用每一帧的呈现时间戳来确定在显示下一帧之前要等待多长时间。

仅当视频使用固定帧速率时,使用固定值作为播放速度才有意义。有关可变帧率视频的示例,请参阅 Grafika 中生成的电影。其中一位玩家有一个“以 60fps 播放”按钮,该按钮会导致玩家忽略时间戳,以便您观察差异。

顺便说一句,将播放循环放在 surfaceChanged() 中并不是一个好主意。使用回调来触发 Activity ,不要在其中构建整个播放器。

关于安卓 MediaCodec 解码器 : Slow Down Video Playback,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27531205/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com