Open Hosseinyzr opened 5 years ago
Check the logs to make sure the same codec gets used in both cases.
You mean grabber and recorder? They are not the same! And I don't think it's about it. Because once I convert the final Frame objects to bitmap again and the quality was good. But i tested with the same codecs , the result was like before... Actually I think it's about ffmpeg and quality settings. And those filters I mentioned. Isn't any way to implement those filters? Could you please explain more?🙏
You're not using filters. If you're using the same codecs with the same settings, the quality will be the same.
Ah, I see what you mean, we can't set the palette as part of the settings of the codec, we need to go through filters. Sounds like issue #287. Try to do something similar to what is shown there.
Thanks, Yes I have seen that issue before, and it get me the idea... But didn't know how exactly do this...
I thnik palettegen needs the whole video, but we extract frame by frame... and actually I have the gif in byte[] (because of encryption/decryption). I think doing paletteuse is ok but what about palettegen...
We don't need to pass the whole video, and there's a single-frame mode too: https://ffmpeg.org/ffmpeg-filters.html#palettegen-1
Aha.
I really did'nt find the solution to generate palette.
I have this exception:
E/FrameFilter.Exception: avfilter_graph_parse_ptr() error -22
any body can provide me the sample code to genearte palette?
No idea? @saudet Are you sure that is possible to implement palettegen with FfmplegFrameFilter? or we should write our own classes?
Yes, it's possible, make sure you're trying to use the right names for the input and output, you shouldn't need anything else than "in" and "out".
@saudet Ok, I will Try again and report the result. You are one of the bests, thank you for your responses🌹
I have tried in many ways but no success.
one of trys: filterCommand = " palettegen [myout]; [0:v][myout] paletteuse "; FFmpegFrameFilter paletteFilter = new FFmpegFrameFilter(filterCommand, w,h); paletteFilter.setPixelFormat(fFmpegFrameGrabber.getPixelFormat()); paletteFilter.setSampleFormat(fFmpegFrameGrabber.getSampleFormat()); try { paletteFilter.start(); paletteFilter.push(myFrame); Frame frame = paletteFilter.pull(); paletteFilter.stop(); paletteFilter.release(); } catch (FrameFilter.Exception e) { Logger.e("FrameFilter.Exception ", e.getMessage()); }
but it trows this exception: FrameFilter.Exception: avfilter_graph_config() error -22 ...... another thing that we cant pass the file path for output of frame filter, is it true?
I don't think they were meant to be used together like that. In any case, try to follow what the documentation says...
I don't think it is possible to do this with ffmpegframefilter! I had tried another ways but no success!
I'm pretty sure it's possible, we just need to spend more time trying things out... It would probably help to check the debug log of FFmpeg.
How can i get the log of this library? whats the pckagename to search the logs for it? I hava a lot of og logs in my logcat .. I don't see any special loggs for ffmpeg... ........................... I don't have problem to spending times on it but I do;nt have a clue! ............................ the command base way is simpe:
ffmpeg -i StickAround.mp4 -filter_complex "[0:v] palettegen" palette.png ffmpeg -i StickAround.mp4 -i palette.png -filter_complex "[0:v][1:v] paletteuse" prettyStickAround.gif
I think we should do this in two step, once generating palette and the use it. for generating , when I try: //pathOfImage is something like this: /storage/emulated..../a.png filterCommand = " palettegen "+pathOfImage;
I have this exception: avfilter_graph_parse_ptr() error -22
so what should I do? any other users have any idea?
@saudet You have written this library and you know it better than me... Could you please take some time to help me? I really need it.
@zhengxuzeng You have tried this before, Do have any Idea?
Please provide more information, such as the messages that appear on the console.
If you don't see anything there, make sure to call FFmpegLogCallback.set()
.
I did as You said , and these are results:
FFmpegLogCallback.set();
String myPath = G.APPLICATION_DIR + "/aatempPalletteGen.png";
String filterCommand = "";
filterCommand = " palettegen [myout]; [0:v][myout] paletteuse ";
FFmpegFrameFilter paletteFilter = new FFmpegFrameFilter(filterCommand, frames.get(0).getW(), frames.get(0).getH());
try {
paletteFilter.start();
paletteFilter.push(myFrame);
Frame frame = paletteFilter.pull();
paletteFilter.stop();
paletteFilter.release();
FileOutputStream fileOutputStream = new FileOutputStream(new File(myPath));
new AndroidFrameConverter().convert(frame)
.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
} catch (FrameFilter.Exception e) {
Log.e("FrameFilter.Exception ", e.getMessage());
} catch (FileNotFoundException e) {
Log.e("FileNotFoundException ", e.getMessage());
}
//Logs:
W/System.err: Error: Input pad "default" with type video of the filter instance "Parsed_paletteuse_1" of paletteuse not connected to any source
E/FrameFilter.Exception: avfilter_graph_config() error -22
I/System.out: Output #0, gif, to '':
I/System.out: Metadata:
I/System.out: encoder :
I/System.out: Lavf58.12.100
I/System.out: Stream #0:0
I/System.out: : Video: gif, bgr8, 420x322, q=2-31, 400 kb/s
I/System.out: ,
I/System.out: 100 tbn
Second Try:
FFmpegLogCallback.set();
String myPath = G.APPLICATION_DIR + "/aatempPalletteGen.png";
String myPalette = G.APPLICATION_DIR + "/MytempPalletteGen.png";
String filterCommand = "";
filterCommand = " palettegen "+myPalette ;
FFmpegFrameFilter paletteFilter = new FFmpegFrameFilter(filterCommand, frames.get(0).getW(), frames.get(0).getH());
try {
paletteFilter.start();
paletteFilter.push(myFrame);
Frame frame = paletteFilter.pull();
paletteFilter.stop();
paletteFilter.release();
FileOutputStream fileOutputStream = new FileOutputStream(new File(myPath));
new AndroidFrameConverter().convert(frame)
.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
} catch (FrameFilter.Exception e) {
Log.e("FrameFilter.Exception ", e.getMessage());
} catch (FileNotFoundException e) {
Log.e("FileNotFoundException ", e.getMessage());
}
//Logs:
W/System.err: Warning: Invalid return value 0 for stream protocol
I/System.out: Input #0, gif, from 'java.io.ByteArrayInputStream@160d30c':
I/System.out: Duration:
I/System.out: N/A
I/System.out: , bitrate:
I/System.out: N/A
I/System.out: Stream #0:0
I/System.out: : Video: gif, bgra, 420x322
I/System.out: ,
I/System.out: 10 tbr,
I/System.out: 100 tbn,
I/System.out: 100 tbc
W/System.err: Warning: Invalid return value 0 for stream protocol
W/System.err: Warning: Invalid return value 0 for stream protocol
W/System.err: Error: No such filter: 'palettegen /storage/emulated/0/.MyToonAppDir/.nomedia/MytempPalletteGen.png'
E/FrameFilter.Exception: avfilter_graph_parse_ptr() error -22
I/System.out: Output #0, gif, to '':
I/System.out: Metadata:
I/System.out: encoder :
I/System.out: Lavf58.12.100
I/System.out: Stream #0:0
I/System.out: : Video: gif, bgr8, 420x322, q=2-31, 400 kb/s
I/System.out: ,
I/System.out: 100 tbn
Do you have a filter command that works with ffmpeg on the command line? If so, try to start by using that!
Do you have a filter command that works with ffmpeg on the command line? If so, try to start by using that!
I don't understand what you mean? you mean test another command?
I have tested palletgen in command line and it worked...
So try to use the same exact command with FFmpegFrameFilter. Don't add any filename or anything.
So try to use the same exact command with FFmpegFrameFilter. Don't add any filename or anything.
this is simple command: ffmpeg -i movie.mp4 -filter_complex "[0:v] palettegen" palette.png it needs one output. and the out put will be used by paletteuse command. so what did I added and is extra?
You're adding filenames and what not to the filter command itself: That won't work! You're not doing that with ffmpeg on the command line, so don't do it with FFmpegFrameFilter either.
What do you mean I'm not using file name in ffmpeg command line?
this is the command and it needs the out put file name and works fine:
Can you provide some piece of code ? or test it yourself?
That's the output filename, FFmpegFrameFilter doesn't support that. You'll need to use FFmpegFrameRecorder for that.
I already gave you a complete example above.
Actually, no, I didn't, here are examples: https://github.com/bytedeco/javacv/blob/master/platform/src/test/java/org/bytedeco/javacv/FrameFilterTest.java
That's the output filename, FFmpegFrameFilter doesn't support that. You'll need to use FFmpegFrameRecorder for that.
I already gave you a complete example above.
Yes, I pointed that does FFmpegFrameFilter can do this filter ? and you said yes ... https://github.com/bytedeco/javacv/issues/1112#issuecomment-450372821
And I'm currently using FfmpegframeRecorder! Every thing is ok , but the problem is ffmpeg itself needs palettegen and paletuse to generate high quality gifs. and as I found from my searches this is the correct way to make high quality gifs. the pixel format and other things are effective but they aren't sufficient to make the most high quality ones.
Actually, no, I didn't, here are examples: https://github.com/bytedeco/javacv/blob/master/platform/src/test/java/org/bytedeco/javacv/FrameFilterTest.java
I see this now, and I update my javacv and ffmpeg to latest version. thank for your update.but it seems it does'nt help in this case.
FrameFilterTest
works, see on Travis CI: https://travis-ci.org/bytedeco/javacv
If it doesn't work for you, you're doing something else wrong that is unrelated to your filters.
FrameFilterTest
works, see on Travis CI: https://travis-ci.org/bytedeco/javacvIf it doesn't work for you, you're doing something else wrong that is unrelated to your filters.
what was the clue in here?
I don't understand...
You mean FrameFilter can perform all of filters?! And it's not about Framefilter defect?
I really need it man... Although this repository is good and perfect but unfortunately it doesn't have good documentation. so please take some time or explain better...
Happy to help, but I won't do everything for you. Start by getting the code from FrameFilterTest
to run on your machine, and then start making modifications to it for your needs.
Hi, I'm using FfmpegFrameGrabber and FfmpegFrameRecorder to making Gif. First I extract Gif frames by grabber and convert them to bitmaps by
Bitmap frameBitmap = new AndroidFrameConverter().convert(frame );
then I do some Edits on Them and convert them to Frame object again. and then make gif of them by recorder. I have tested different PixelFormat But the quality is still bad. also set videoquality to 1. .... from ffmpeg documentation I have found these commands make the Gif with high quality..
ffmpeg -i StickAround.mp4 -filter_complex "[0:v] palettegen" palette.png
ffmpeg -i StickAround.mp4 -i palette.png -filter_complex "[0:v][1:v] paletteuse" prettyStickAround.gif
is it possible to do this? I know it may be done by FrameFilter but I dont know how...