bramp / ffmpeg-cli-wrapper

Java wrapper around the FFmpeg command line tool
BSD 2-Clause "Simplified" License
1.68k stars 411 forks source link

how to catch ffmpeg exception? #232

Open ChengHoHang opened 3 years ago

ChengHoHang commented 3 years ago

as title. I try to catch exception from ffmpeg outputstream, not FFcommon.throwOnError 's exceptions,they are difference,right?

for example, I exec the command "ffmpeg -i xxx.mp4 yyy.mp4",FFcommon.throwOnError only throws message "ffmpeg returned non-zero exit status"

but the ffmpeg outputstream return the full error message such as "xxx No such file or directory", this message is what i need

can i get ffmpeg outputstream in some way? thanks

ChengHoHang commented 3 years ago

@bramp @ziodave please give some help~~

ChengHoHang commented 3 years ago

ok.. My project needs to record the error log from ffmpeg log,let me show my thought

my way is create a class that extends FFmpeg and overwrite its run() method,and use a ThreadLocal(FFmpegLogHolder) to save the log,the reason i use threadLocal is that CustomizeFFmpeg is set as a Singleton Bean

@Slf4j
public class CustomizeFFmpeg extends FFmpeg {

    final RunProcessFunction runFunc;

    private String path;

    public CustomizeFFmpeg(String path) throws IOException {
        this(path, new RunProcessFunction());
        this.path = path;
    }

    public CustomizeFFmpeg(String path, RunProcessFunction runFunc) throws IOException {
        super(path, runFunc);
        this.runFunc = runFunc;
    }

    @Override
    public void run(List<String> args) throws IOException {
        if (!isFFmpeg()) {
            throw new IllegalArgumentException(
                    "This binary '" + super.getPath() + "' is not a supported version of ffmpeg");
        }
        checkNotNull(args);

        Process p = runFunc.run(path(args));

        assert (p != null);
        StringBuilder logStringBuilder = new StringBuilder();
        try {
            // CharStreams.copy(wrapInReader(p), System.out);

            CharStreams.copy(wrapInReader(p), logStringBuilder);
            log.info(logStringBuilder.toString());

            throwOnError(p);

        } catch (Exception e) {
            // only catch exception,use threadLocal record
            FFmpegLogHolder.setLog(path + " " + String.join(" ", args).concat("\n").concat(logStringBuilder.toString()).concat("\n"));
            throw e;
        } finally {
            p.destroy();
        }
    }

    public String getFfmpegLog() {
        String log = FFmpegLogHolder.getLog();
        FFmpegLogHolder.clear();
        return log;
    }
}

this way seems a little silly.... is there any api to get errorLog efficiently and elegantly?

barnettj commented 3 years ago

There are two PRs to handle accessing standard out for ffmpeg/ffprobe:

https://github.com/bramp/ffmpeg-cli-wrapper/pull/214 https://github.com/bramp/ffmpeg-cli-wrapper/pull/225

No movement though...