Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用mediacodec从位图文件创建视频_Android_Video_Bitmap_Android Mediacodec - Fatal编程技术网

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

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;

我的sd卡上有位图文件列表。现在,我想使用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);
        }
受保护的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。