Android 使用mediacodec从位图文件创建视频
我的sd卡上有位图文件列表。现在,我想使用mediacodec创建视频。我已经检查了文档。我找不到创建视频的方法。我不想使用FFmpeg。我试过下面的代码。任何帮助都将不胜感激Android 使用mediacodec从位图文件创建视频,android,video,bitmap,android-mediacodec,Android,Video,Bitmap,Android Mediacodec,我的sd卡上有位图文件列表。现在,我想使用mediacodec创建视频。我已经检查了文档。我找不到创建视频的方法。我不想使用FFmpeg。我试过下面的代码。任何帮助都将不胜感激 protected void MergeVideo() throws IOException { // TODO Auto-generated method stub MediaCodec mMediaCodec; MediaFormat mMediaFormat;
protected void MergeVideo() throws IOException {
// TODO Auto-generated method stub
MediaCodec mMediaCodec;
MediaFormat mMediaFormat;
ByteBuffer[] mInputBuffers;
mMediaCodec = MediaCodec.createEncoderByType("video/avc");
mMediaFormat = MediaFormat.createVideoFormat("video/avc", 320, 240);
mMediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
mMediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
mMediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
mMediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mMediaCodec.configure(mMediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mMediaCodec.start();
mInputBuffers = mMediaCodec.getInputBuffers();
//for (int i = 0; i<50; i++) {
int i=0;
int j=String.valueOf(i).length()<1?Integer.parseInt("0"+i) : i;
File imagesFile = new File(Environment.getExternalStorageDirectory() + "/VIDEOFRAME/","frame-"+j+".png");
Bitmap bitmap = BitmapFactory.decodeFile(imagesFile.getAbsolutePath());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); // image is the bitmap
byte[] input = byteArrayOutputStream.toByteArray();
int inputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = mInputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(input);
mMediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, 0, 0);
}
受保护的void MergeVideo()引发IOException{
//TODO自动生成的方法存根
媒体编解码器;
媒体格式;
ByteBuffer[]mInputBuffers;
mMediaCodec=MediaCodec.createEncoderByType(“视频/avc”);
mMediaFormat=MediaFormat.createVideoFormat(“视频/avc”,320240);
mMediaFormat.setInteger(MediaFormat.KEY\u比特率,125000);
mMediaFormat.setInteger(MediaFormat.KEY\u FRAME\u RATE,15);
mMediaFormat.setInteger(MediaFormat.KEY\u COLOR\u格式,MediaCodecInfo.CodecCapabilities.COLOR\u格式YUV420平面);
mMediaFormat.setInteger(MediaFormat.KEY\u I\u FRAME\u INTERVAL,5);
mMediaCodec.configure(mMediaFormat、null、null、MediaCodec.configure\u FLAG\u ENCODE);
mMediaCodec.start();
mInputBuffers=mMediaCodec.getInputBuffers();
//对于(int i=0;i您缺少了一些内容。的答案包含您需要的一些信息,但它是为特别希望获得API 16支持的人编写的。如果您愿意以API 18及更高版本为目标,您的生活将更轻松
您遇到的最大问题是,从ByteBuffer输入的MediaCodec始终是未压缩的YUV格式,但您似乎正在传入压缩的PNG图像。您需要将位图转换为YUV。具体布局和最佳方法因设备而异(有些使用平面,有些使用半平面),但您可以找到执行此操作的代码。或者只需查看帧在缓冲区中生成的方式即可
或者,使用MediaCodec的表面输入。将画布附加到输入表面并在其上绘制位图。基本上是这样做的,但使用OpenGL ES
一个潜在的问题是,您正在为帧时间戳传入0。您应该传入一个真实(生成)的时间戳,以便该值与编码的帧一起转发到MediaMuxer
在最新的设备(API 21+)上,MediaRecorder可以接受表面输入。这可能比MediaCodec更容易使用。我建议您使用“将画布附加到输入表面并在其上绘制位图。EncodeAndMuxTest基本上可以做到这一点,但使用OpenGL ES。”-这是100个答案中第一个真正回答了这个问题。“曲面必须使用硬件加速API进行渲染,例如OpenGL ES.Surface.lockCanvas(android.graphics.Rect)可能会失败或产生意外结果。”-您不能使用画布来完成此操作。使用OpenGL ES需要使用EGL_RECORDABLE_ANDROID来录制OpenGL ES中的视频。这意味着您必须使用API level 26,目前只有60%的设备使用此API level 26。