Making ffmpeg/javacv less verbose in java
Asked Answered
S

3

8

I have a Java application that uses ffmpeg library and javacv to load and process video files.

I am currently using following code, for loading videofile to my data container.

public boolean add(String videofile) {
        FrameGrabber g = new OpenCVFrameGrabber( videofile );
        try{ 
            g.start();
        }
        catch(Exception e){
            g = new FFmpegFrameGrabber( videofile );
            try {
                g.start();
            }catch(Exception x){
                return false;
            }
        }
        grabbers.add( new Pair(videofile, g) );
        frames.add( 0 );
        preprocessed=false;
        return true;        
    }

Each time video is loaded, a library outputs a lot of meta information regarding video itself:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/lejlot/data/test.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2mp41 encoder : Lavf53.21.1 Duration: 00:04:36.27, start: 0.000000, bitrate: 305 kb/s Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 303 kb/s, 20,85 fps, 30 tbr, 1k tbn, 1k tbc Metadata: handler_name : VideoHandler

which obviously I do not want to see. I cannot (do not want) to modify the libraries source codes, but rather modify my own so it can intercept this log and discard it.

As far I tried to temporarly block the stdout/stderr streams through

private static final devnull = new PrintStream(new OutputStream() {
        @Override
        public void write(int b) {
            //DO NOTHING
        }
        @Override
        public void write(byte[] b,int x,int y){
        }
   });

   /**
   * Blocks messages to stdout
   */
   public static void silentStdOut(){
     System.setOut(devnull);
   }

   /**
   * Blocks messages to stderr
   */
   public static void silentStdErr(){
     System.setErr(devnull);
   }

but it does not seem to help, log message is still displayed

public boolean add(String videofile) {
    Utils.silentStdErr();
    Utils.silentStdOut();
    FrameGrabber g = new OpenCVFrameGrabber( videofile );
    try{ 
        g.start();
    }
    ,,,

"Raw" ffmpeg can be set to be less verbose using

ffmpeg -loglevel panic

but neither OpenCVFrameGrabber not FFmpegFrameGrabber give access to the tool's parameters.

To sum up - how can I discard these log messages without modifing the libraries' source codes?

Skulk answered 18/8, 2013 at 4:31 Comment(0)
S
9

had the same problem a few minutes ago, and also looked on the net, nothing except your question. Then i started digging in the ffmpeg sources and found a solution, add the import:

import com.googlecode.javacv.cpp.avutil;

and then just call:

avutil.av_log_set_level(avutil.AV_LOG_QUIET);

before you create the FFmpegFrameGrabber -> No more messages form ffmpeg.

Regards
Daniel

Selector answered 27/8, 2013 at 15:8 Comment(4)
this reminds me of xkcd.com/979 . Thank you for this answer, works perfectly.Skulk
2017 solution: It is now import org.bytedeco.javacpp.avutil;Steading
This helped me a huge amount just now, THANK YOU!Indistinct
2023, now you need import org.bytedeco.ffmpeg.global.avutil;Upbringing
C
5

This is updated solution(w.r.t. javacv from github)

add the import statement given below

import static org.bytedeco.javacpp.avutil.AV_LOG_PANIC;  
import static org.bytedeco.javacpp.avutil.av_log_set_level;

call the below statement before you create the FFmpegFrameGrabber -> No more messages form ffmpeg.

av_log_set_level(AV_LOG_PANIC);
Closer answered 7/3, 2018 at 7:4 Comment(0)
F
2

javacv v1.5.7, the avutil package is now located at org.bytedeco.ffmpeg.global.avutil. The av_log_set_level(...) answer works exactly the same, the package just moved.

Furfuraceous answered 16/10, 2022 at 6:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.