Я разрабатываю приложение для 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;
}