Использование MediaCodec для сохранения серии изображений в качестве видео

Я пытаюсь использоватьMediaCodec сохранить серию изображений, сохраненных в виде байтовых массивов в файле, в видеофайл. Я проверил эти изображения наSurfaceView (играет их в серии), и я вижу их хорошо. Я посмотрел на множество примеров, используяMediaCodecи вот что я понимаю (пожалуйста, поправьте меня, если я ошибаюсь):

Получить InputBuffers из объекта MediaCodec -> заполните его рамкойданные изображения -> поставить в очередь входной буфер -> получить закодированный выходной буфер -> запишите это в файл -> увеличить время презентации и повторить

Тем не менее, я проверил это много, и я в конечном итоге один из двух случаев:

Все примеры проектов, которые я пытался имитировать, приводили к смерти Media Server при вызовеqueueInputBuffer во второй раз.Я пробовал звонитьcodec.flush() в конце (после сохранения выходного буфера в файл, хотя ни один из примеров, которые я видел, не сделал этого) и медиасервер не умер, однако я не могу открыть выходной видеофайл с помощью любого медиаплеера, поэтому что-то не так ,

Вот мой код:

MediaCodec codec = MediaCodec.createEncoderByType(MIMETYPE);
        MediaFormat mediaFormat = null;
        if(CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)){
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 1280 , 720);
        } else {
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 720, 480);
        }


        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 700000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 10);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
        codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

        codec.start();

        ByteBuffer[] inputBuffers = codec.getInputBuffers();
        ByteBuffer[] outputBuffers = codec.getOutputBuffers();
        boolean sawInputEOS = false;
        int inputBufferIndex=-1,outputBufferIndex=-1;
        BufferInfo info=null;

                    //loop to read YUV byte array from file

            inputBufferIndex = codec.dequeueInputBuffer(WAITTIME);
            if(bytesread= 0){
                if(!sawInputEOS){
                    int samplesiz=dat.length;
                    inputBuffers[inputBufferIndex].put(dat);
                    codec.queueInputBuffer(inputBufferIndex, 0, samplesiz, presentationTime, 0);
                    presentationTime += 100;

                    info = new BufferInfo();
                    outputBufferIndex = codec.dequeueOutputBuffer(info, WAITTIME);
                    Log.i("BATA", "outputBufferIndex="+outputBufferIndex);
                    if(outputBufferIndex >= 0){
                        byte[] array = new byte[info.size];
                        outputBuffers[outputBufferIndex].get(array);

                        if(array != null){
                            try {
                                dos.write(array);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }

                        codec.releaseOutputBuffer(outputBufferIndex, false);
                        inputBuffers[inputBufferIndex].clear();
                        outputBuffers[outputBufferIndex].clear();

                        if(sawInputEOS) break;
                    }
                }else{
                    codec.queueInputBuffer(inputBufferIndex, 0, 0, presentationTime, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

                    info = new BufferInfo();
                    outputBufferIndex = codec.dequeueOutputBuffer(info, WAITTIME);

                    if(outputBufferIndex >= 0){
                        byte[] array = new byte[info.size];
                        outputBuffers[outputBufferIndex].get(array);

                        if(array != null){
                            try {
                                dos.write(array);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }

                        codec.releaseOutputBuffer(outputBufferIndex, false);
                        inputBuffers[inputBufferIndex].clear();
                        outputBuffers[outputBufferIndex].clear();
                        break;
                    }
                }


            }
        }

        codec.flush();

        try {
            fstream2.close();
            dos.flush();
            dos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        codec.stop();
        codec.release();
        codec = null;

        return true;

    }

У меня вопрос, как я могу получить рабочее видео из потока изображений с помощью MediaCodec. Что я делаю неправильно?

Еще один вопрос (если я не слишком жадный), я хотел бы добавить звуковую дорожку к этому видео, это также можно сделать с помощью MediaCodec, или я должен использовать FFmpeg?

Заметка: Я знаю оMediaMux в Android 4.3, однако, это не вариант для меня, так как мое приложение должно работать на Android 4.1+.

Обновить Благодаря ответу Fadden, я смог достичь EOS без смерти Медиа-сервера (Выше код после модификации). Тем не менее, файл, который я получаю, производит бред. Вот снимок видео, которое я получаю (работает только как файл .h264).

Мой входной формат изображения - изображение YUV (NV21 от предварительного просмотра камеры). Я могу'Это любой воспроизводимый формат. Я перепробовал все форматы COLOR_FormatYUV420 и одинаковый бред. И я все еще могунайти (используя MediaCodec), чтобы добавить аудио.

Ответы на вопрос(1)

Ваш ответ на вопрос