我有一串H264视频,需要在我的Android应用程序中显示。如果我将MediaCodec与表面配置在一起,那么视频就会被解码到我的应用中,没有问题,我可以在这个表面看到它。将H264帧解码为字节数组
但我还需要在某些时刻获取视频的位图(即将某些帧存储在SD卡上)。是否有可能配置MediaCodec库返回一个字节数组,而不是直接面向表面?
另一种选择是直接从表面获取位图,但我在SDK上也找不到这个选项。
我有一串H264视频,需要在我的Android应用程序中显示。如果我将MediaCodec与表面配置在一起,那么视频就会被解码到我的应用中,没有问题,我可以在这个表面看到它。将H264帧解码为字节数组
但我还需要在某些时刻获取视频的位图(即将某些帧存储在SD卡上)。是否有可能配置MediaCodec库返回一个字节数组,而不是直接面向表面?
另一种选择是直接从表面获取位图,但我在SDK上也找不到这个选项。
您可以使用MediaMetadataRetriever:
MediaMetadataRetriever mediaMetadataRetriever=new MediaMetadataRetriever(); //should be stored as an instance variable
mediaMetadataRetriever.setDataSource(mVideo.getVideoUrl(Video.SD));
int time = videoView.getCurrentPosition()* 1000; //micro-to-milliseconds
Bitmap bmFrame = mediaMetadataRetriever.getFrameAtTime(time);
编辑:
要获取原始字节数据,而UI的参与,您可以通过帧前进的时间框架,得到了位图,并将其转换为字节数组。
为了更有效率,考虑分叉FFmpegMediaMetadataRetriever,其FFmpegMediaMetadataRetriever.java
方法private native byte [] _getFrameAtTime(long timeUs, int option);
跳过整个位图转换过程。
试试这个:
public class GameView extends SurfaceView {
private Bitmap bmp;
private SurfaceHolder holder;
public GameView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas(null);
onDraw(c);
holder.unlockCanvasAndPost(c);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(bmp, 10, 10, null);
}
}
这与我的问题无关。 –
但这并不做什么,我什么:我有一个H264流,我想直接解码为字节的缓冲区,避免任何UI组件。 –
这个问题没有提到目标作为字节数据的检索和UI的缺席,你应该让你的问题更清楚。无论如何,检查修改的答案,看看它是否符合您的需求。 – Kai
我想你是对的,我的问题没有妥善制定。我需要抓取用户当前正在查看的任何东西(在由MediaCodec渲染的SurfaceView中)作为快照。 –