使用mediacodec从位图文件创建视频

时间:2015-06-05 04:34:49

标签: android video bitmap mediacodec

我的SD卡上有Bitmap文件列表。现在,我想使用mediacodec创建视频。我检查了MediaCodec个文档。我找不到创建视频的方法。我不想使用FFmpeg。我试过下面的代码。任何帮助,将不胜感激!!

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);
        }

1 个答案:

答案 0 :(得分:3)

你错过了几件。 this question的答案包含您需要的一些信息,但它是为那些特别想要API 16支持的人编写的。如果您愿意以API 18及更高版本为目标,那么您的生活将更加轻松。< / p>

你遇到的最大问题是来自ByteBuffer的MediaCodec输入总是处于未压缩的YUV格式,但你似乎正在传递压缩的PNG图像。你需要将位图转换为YUV。这样做的确切布局和最佳方法因设备而异(有些使用平面,有些使用半平面),但您可以找到这样做的代码。或者只看一下EncodeDecodeTest的缓冲区到缓冲区中生成帧的方式。

或者,使用Surface输入到MediaCodec。将Canvas附加到输入表面并在其上绘制位图。 EncodeAndMuxTest基本上就是这样,但使用OpenGL ES。

一个潜在的问题是您为帧时间戳传入0。您应该传入一个真实的(生成的)时间戳,以便将值与编码帧一起转发到MediaMuxer。

在最近的设备(API 21+)上,MediaRecorder可以接受Surface输入。这可能比MediaCodec更容易使用。