I am adding image watermark to video with help of FFmpeg but FFmpeg takes an inordinate amount of time with the below command-
String[] cmd = {"-i",videoPath, "-i", waterMark.toString(),"-filter_complex","overlay=5:5","-codec:a", "copy", outputPath};
so i tried another command which was little bit faster but increase output file size(which i do not want)
String[] cmd = {"-y","-i", videoPath, "-i", waterMark.toString(), "-filter_complex", "overlay=5:5", "-c:v","libx264","-preset", "ultrafast", outputPath};
Some one please explain to me how to increase the speed of FFmpeg watermarking speed without increasing the size of output. Thanks.
You mentioned that a 7MB video takes between 30-60 seconds.
There is always a trade off when choosing between speed and quality.
I tested on my phone using a 7MB file and it took 13 seconds, still slow, but we can't expect much better then that.
Ways to increase speed:
-r
command-b:v
and-b:a
commands-crf
. The default value is21
This is what I have found works the best on most android devices:
I reduced my framerate slightly, you can experiment what works best for you. I'm using Google's
mp4parser
to retrieve the frame rate.I have to give credit to @Gyan that provided me with a way to perfectly scale images that is being placed on top of a video, you can look at the question I asked here.
Also, you can remove the
-g
command that I used above, that is for changing the GOP.Here is your command edited:
If you are unsure about the frame rate, you can remove it from the command and first test if your speed is reduced.
Try it, if you have any questions, please ask.
OP opted to go with the following command:
Edit
Just to add on the command I mentioned and provide a detailed explanation of how to use it etc:
This is for device's that has a display aspect ratio of
16:9
. If you want this filter to work on all device's you will have to get the aspect ratio of the device and change the filter16/9/2
respectively.You can get the device aspect ratio by creating this methods:
Now you have the correct aspect ratio and you can change the filter accordingly.
Next, create a watermark and add it to a view, make that view the size of the device (
match_parent
) and scale/place the watermark where you would like it to be. You can then get the bitmap by calling:and create a file from the
Bitmap
, like this:The watermark is created and can be reused, or you can delete it when you are done with it.
Now you can call the command mentioned above.
This is a very common question here. The simple answer is that you can't increase the encoding speed of
ffmpeg
on Android. You're encoding on a phone, so you don't expect desktop/server performance using an encoder and no hardware acceleration support.There are a few things users can do:
Stream copy the audio with
-c:a copy
(you're already doing that).Use
-preset ultrafast
to give up encoding efficiency for encoding speed (you're also already doing that).Make the output width x height smaller with the scale filter (probably not an acceptable option for you).
Make sure your x264 was not compiled with
--disable-asm
so you can take advantage of the various ARM and NEON optimizations in x264 for a significant increase in encoding speed. However, I don't know which Android devices support that, but it's something to look into. For a quick check to see if you are using any optimizations refer to the console output fromffmpeg
and search forusing cpu capabilities
. Ifnone!
then it is not using any optimizations, otherwise it may sayARMv7 NEON
or something like that.Offload the encoding to a server. Saves your users' battery life too.
All this for an annoying watermark? Avoid re-encoding and use a player to overlay the watermark.
Apparently FFmpeg has MediaCodec decoding support on Android, but encoding is the bottleneck here. However maybe it will save a few fps.
Send a patch to FFmpeg that enables MediaCodec encoding support or wait a few years for someone else to do so.
Forget
ffmpeg
and use MediaCodec directly. I am clueless about this and too lazy to look it up, but I assume it uses hardware to encode and I'll guess you can use it to make an overlay. Someone correct me if I am wrong.