Java – Convert video using HandBrakeCLI

agosto 19, 2016

If you need to convert a video there’s a great tool called HandBrake. There’s also a command line utility called HandBrakeCLI which we can call from our java program as any other executable program.

Executing an external program from Java should be trivial, but it is not. There are several articles on the web and questions on stackoverflow about this. And remember that its platform specific.

Our environment is Ubuntu 16.04 with HanbrakeCLI 0.10.2 and JDK 8.

We needed to convert some video file and replace it with the new converted file. From CLI it would be

mv {fullPath} {fullPath}.converting
HandBrakeCLI -i {fullPath}.converting -o {fullPath} --preset 'Normal'
rm {fullPath}.converting

from Java we changed the command because it was not taking the ‘preset’ parameter, so instead of using the Normal preset we explicitly set the same parameters used by the preset

HandBrakeCLI -i {fullPath}.converting -o {fullPath} -e x264 -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 –audio-copy-mask aac,ac3,dtshd,dts,mp3 –audio-fallback ffac3 -f mp4 –loose-anamorphic –modulus 2 -m –x264-preset veryfast –h264-profile main –h264-level 4.0

We ended up with this code

public void convertVideo(String fullPath) throws IOException, InterruptedException {
    log.debug("Converting video: " + fullPath);
    Runtime.getRuntime().exec(String.format("mv %s %s.converting", fullPath, fullPath)).waitFor();
    /**
     * Invoke HandBrakeCLI
     * epxlicitly set parameters from --preset 'Normal'
     * https://trac.handbrake.fr/wiki/BuiltInPresets#normal
     */
    String cmd = new StringBuilder(String.format("HandBrakeCLI -i %s.converting -o %s -e x264  -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback ffac3 -f mp4 --loose-anamorphic --modulus 2 -m --x264-preset veryfast --h264-profile main --h264-level 4.0", fullPath, fullPath)).append(" 2>&1").toString();
    log.debug(String.format("Command used: %s", cmd));
    Process p = Runtime.getRuntime().exec(cmd);
    /**
     * Cleanup async the streams to not block the main thread
     * http://stackoverflow.com/a/8596996/961652
     */
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                BufferedReader rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String rdrLine;
                while (((rdrLine = rdr.readLine()) != null)) {
//                    System.out.println("out: " + rdrLine);
                }
                /**
                 * After converting the file, delete the created temporal file
                 */
                Runtime.getRuntime().exec(String.format("rm %s.converting", fullPath));
            } catch (IOException e) {
                log.error(String.format("Tehre was a problem converting the video: %s", fullPath), e);
            }
        }
    }).start();
    log.debug("Video conversion process invoked");
}

notice that we didn’t take care of other things that could possibly go wrong, like spaces in filenames or paths. This was sufficient for our needs.

sources:
http://stackoverflow.com/a/3403259/961652
http://stackoverflow.com/a/25735681/961652
https://trac.handbrake.fr/wiki/BuiltInPresets#normal

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: