Javacv: How to give Fade out effect to audio with FFmpegFrameFilter

Created on 2 Apr 2019  路  28Comments  路  Source: bytedeco/javacv

i want to give fade out effect to an audio at 3-5s of an 10s audio. i can change volume.

bug

All 28 comments

Duplicate of #928

i want audio fade-out effect not video.

Ah, well, tt's the same thing, just use "afade" instead of "fade":
https://ffmpeg.org/ffmpeg-filters.html#afade-1

Okay, but if i push all the frames to filter and then pull the frames from filter, how FFmpegFrameFilter will give fade out only to the expected frames in range?

This gives "org.bytedeco.javacv.FrameFilter$Exception: avfilter_graph_parse_ptr() error -22" error

FFmpegFrameFilter filter = new FFmpegFrameFilter("setpts=N,afade=t=out:st=2:d=1",frameGrabber.getAudioChannels());

And this is not working. No error but no effect at all.

FFmpegFrameFilter filter = new FFmpegFrameFilter("afade=t=out:st=0:d=1",frameGrabber.getAudioChannels());

Read the documentation of the filter, and check any warnings or errors in
the log.

Could you please give an example??? I am so lost.

I never used afade myself. What does it say in the log?

no log is given..... what should i do now?

Make sure to call FFmpegLogCallback.set() and try again.

In have set but again no log...

Ok then give me a complete example that fails.

FFmpegFrameFilter filter = new FFmpegFrameFilter("afade=t=out:st=0:d=1",frameGrabber.getAudioChannels());
filter.start();

                for(int i = 0 ;i<500; i++){
                    //recording video frame from bitmap
                    recorder.record(videoFrame);

                    //recording audio frame with filter
                    Frame audioFrame = frameGrabber.grabSamples();
                    filter.push(audioFrame);
                    audioFrame = filter.pull();
                    recorder.record(audioFrame); 
                }

It doesn't compile, what is "frameGrabber"?

// creating video recorder
                FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFilePath, 600, 600);
                recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                recorder.setFormat("mp4");
                recorder.setFrameRate(60);
                recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
                recorder.setVideoQuality(0);
                recorder.setAudioQuality(0);
                recorder.setVideoOption("crf", "14");
                recorder.setVideoOption("preset", "fast");
                recorder.setVideoOption("tune", "stillimage");

                //creating audio grabber
                FFmpegFrameGrabber audioFrameGrabber = new FFmpegFrameGrabber(audioStream);
                audioFrameGrabber.start();

                //setting audio channels to recorder from grabber
                recorder.setAudioChannels(audioFrameGrabber.getAudioChannels());

                //creating fade filter
                FFmpegFrameFilter filter = new FFmpegFrameFilter("afade=t=out:st=0:d=1",frameGrabber.getAudioChannels());
                filter.start();

                //starting recorder
                recorder.start();


                for(int i = 0 ;i<500; i++){
                    //recording video frame from bitmap
                    recorder.record(videoFrame);

                    //recording audio frame with filter
                    Frame audioFrame = frameGrabber.grabSamples();
                    filter.push(audioFrame);
                    audioFrame = filter.pull();
                    recorder.record(audioFrame);
                }

It still doesn't compile, what is audioStream?

audioStream is InputStream from android raw

String videoFilePath = Environment.getExternalStorageDirectory()+"/"+"output.mp4";
Uri audioUri = Uri.parse("android.resource://"+getPackageName()+"/raw/"+"my_audio_file_name");

            InputStream audioStream;
            try{
                audioStream = getContentResolver().openInputStream(audioUri);
            }catch(Exception e){

            }

            //creating android frame converter
            AndroidFrameConverter frameConverter = new AndroidFrameConverter();

            // creating video recorder
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFilePath, 600, 600);
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(60);
            recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
            recorder.setVideoQuality(0);
            recorder.setAudioQuality(0);
            recorder.setVideoOption("crf", "14");
            recorder.setVideoOption("preset", "fast");
            recorder.setVideoOption("tune", "stillimage");

            //creating audio grabber
            FFmpegFrameGrabber audioFrameGrabber = new FFmpegFrameGrabber(audioStream);
            audioFrameGrabber.start();

            //setting audio channels to recorder from grabber
            recorder.setAudioChannels(audioFrameGrabber.getAudioChannels());

            //creating fade filter
            FFmpegFrameFilter filter = new FFmpegFrameFilter("afade=t=out:st=0:d=1",frameGrabber.getAudioChannels());
            filter.start();

            //starting recorder
            recorder.start();


            for(int i = 0 ;i<500; i++){
                //recording video frame from bitmap
                Bitmap bitmap = Bitmap.createBitmap(600,600, Bitmap.Config.ARGB_8888);
                recorder.record(frameConverter.convert(bitmap));

                //recording audio frame with filter
                Frame audioFrame = frameGrabber.grabSamples();
                filter.push(audioFrame);
                audioFrame = filter.pull();
                recorder.record(audioFrame);
            }

            filter.stop();
            filter.release();

            audioFrameGrabber.stop();
            audioFrameGrabber.release();

            recorder.stop();
            recorder.release();

Ok, so give me an audio file that causes this problem.

Did you find???

I see what the issue is. For audio filters, we need to add asetpts=N instead of setpts=N. I've updated that in commit https://github.com/bytedeco/javacv/commit/bfaeb872898701e4a70c9aee4666a7937fe2aa87 so that we don't need to add it manually and afade is working fine now.

Please give it a try with the snapshots: http://bytedeco.org/builds/

new FFmpegFrameFilter("asetpts=N,afade=t=out:st=0:d=1",audioFrameGrabber.getAudioChannels())
will this work with my current biuld???

Almost, it looks like we need to give a dummy name for the output of
asetpts and the input of afade for some reason.

this is working...but i have questions...... Will i have to push and pull all the audio frames to the filter to get expected fade effect between certain duration ??? or Can i push only the certain frames that required to be affected??? Actually how does filter know which frames should get effect according to "st=0:d=1"?

That's what "setpts" and "asetpts" are for, they set the timestamps according to the number of frames/samples you've pushed: https://ffmpeg.org/ffmpeg-filters.html#setpts_002c-asetpts

oooooh, thanks a lot ....

Was this page helpful?
0 / 5 - 0 ratings