Android javacv FFMpeg накладывает анимированный GIF на видео - PullRequest
0 голосов
/ 05 апреля 2019

Я разрабатываю приложение для Android, которое создает видео (из изображения плюс файл mp3) с javacv и FFMpeg, и часть создания видео работает нормально, но моя проблема возникает сейчас, когда я хочу перекрыть прозрачный фон анимационный GIF над видео, и я действительно застрял с ним, и до сих пор у меня не было успеха в каждой попытке.

Если честно, это мой первый опыт работы с javacv и FFMpeg, поэтому у меня мало знаний о том, как работать с фильтрами.

Ниже я приведу свой полный метод создания видео и посмотрим, сможет ли кто-нибудь мне помочь. Опять же, моя проблема заключается в перекрытии анимированного GIF, видео (удаление части фильтра) создается просто отлично. Максимум, чего мне удалось добиться, - это наложение статического (одного кадра) маленького GIF-файла (без прозрачности) в верхнем левом углу видео, но я хотел бы добиться прозрачного GIF-изображения с теми же размерами видео поверх него. .

Возможно, вы увидите бессмысленный код, но помните, что это из-за моего недостатка знаний о фильтрах javacv и FFMpeg.

Я надеюсь, что кто-нибудь может мне помочь.

Спасибо.

PS. Я прочитал этот пост: javaCV Android, странные цвета на оверлее при потоковой передаче на сервер RTMP

из @ schw4ndi, но я ничего не смог с этим поделать.

static String recordVideo(JSONObject objJSON) {

    try {
        fileName = objJSON.has("file_name") ? String.valueOf(objJSON.getString("file_name")) : "";
        videoPath = objJSON.has("video_path") ? String.valueOf(objJSON.getString("video_path")) : "";
    } catch (JSONException e) {
        ExceptionHandler.logException(e);
    }

    String strReturn = Enum.Result.OK;

    if (!fileName.equals("") && !videoPath.equals("")) {
        try {
            String outputFilename = videoPath + "/" + fileName;
            //video grabber
            FrameGrabber grabber1 = new FFmpegFrameGrabber(outputFilename + ".jpg");
            //audio grabber
            FrameGrabber grabber2 = new FFmpegFrameGrabber(outputFilename + ".mp3");

            grabber1.start();
            grabber2.start();

            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFilename + ".mp4", 1080, 1920,2);

            //video
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setVideoOption("tune", "zerolatency");
            recorder.setFrameRate(30);
            recorder.setVideoBitrate(128000);
            recorder.setVideoOption("crf", "28");
            recorder.setVideoQuality(0); //highest quality
            recorder.setVideoOption("preset", "fast");
            recorder.setFormat("mp4");

            //audio
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
            recorder.setSampleRate(44100);
            recorder.setAudioBitrate(128000);
            recorder.setAudioOption("crf", "0"); //no variable bitrate audio (constant rate factor)
            recorder.setAudioQuality(0); //highest quality

            FFmpegFrameFilter filter = null;
            try{
                filter = new FFmpegFrameFilter("movie=" + videoPath + "/anim01.gif [logo];[in][logo]overlay=0:0:format=yuv420 [out]",1080, 1920);
                filter.start();
            }catch (FrameFilter.Exception e){
                e.printStackTrace();
            }

            recorder.start();

            Frame frame1, frame2 = null, frame3 = null;

            while ((frame1 = grabber1.grabFrame()) != null ||
                    (frame2 = grabber2.grabFrame()) != null) {
                if (frame1 != null) filter.push(frame1);
                frame3 = filter.pull();
                //recorder.record(frame1);
                recorder.record(frame3, avutil.AV_PIX_FMT_YUV420P);
                recorder.record(frame2, avutil.AV_PIX_FMT_YUV420P);
            }

            recorder.stop();
            grabber1.stop();
            grabber2.stop();
            filter.stop();

        } catch (Exception e) {
            strReturn = Enum.Result.KO;
            ExceptionHandler.logException(e);
        }
    }

    return strReturn;
}
...