首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Java程序中正确调用mkvmerge?

如何在Java程序中正确调用mkvmerge?
EN

Stack Overflow用户
提问于 2018-11-01 03:23:17
回答 1查看 455关注 0票数 3

我有几百集的动漫,我想把字幕和视频文件合并成一个。我决定编写一个简短的Java程序来遍历这些文件并合并它们。视频文件名为Bleach1.mkv,字幕为Bleach1.srt。为了避免任何潜在的空格问题,这些文件保存在我的C盘的根目录下。下面是我写的代码。

根据mkvmerge的文档,适当的命令行调用是"mkvmerge -o remux_Bleach1.mkv Bleach1.mkv Bleach1.srt“。我已经确认了,这实际上是有效的。我现在从不同的文件夹运行java程序,所以我对每个文件都使用了绝对路径。

我的代码中的命令打印为"C:\Program Files\MKVToolNix\mkvmerge.exe,-o C:\Bleach\remux_Bleach_1.mkv C:\Bleach\Bleach_1.mkv C:\Bleach\Bleach_1.srt“

我从mkvmerge返回的错误消息是“错误:没有给出目标文件名”。

我不清楚在使用ProcessBuilder时参数是如何传递的--我到底做错了什么?

代码语言:javascript
复制
import org.apache.commons.io.FilenameUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;


public class Main {

    private static String mkvmergePath = "C:\\Program Files\\MKVToolNix\\mkvmerge.exe";

    public static void mergeVideoAndSubtitles(final File folder, String videoExtension, String subtitleExtension) {
        for (final File fileEntry : folder.listFiles()) {
            if (fileEntry.isDirectory()) {
                listFilesForFolder(fileEntry, videoExtension, subtitleExtension);
                // for each mkv file that is found
            } else if (FilenameUtils.isExtension(fileEntry.getName(), videoExtension)) {
                String parentFolderPath = fileEntry.getParentFile().getPath();
                String baseName = FilenameUtils.getBaseName(fileEntry.getName());
                String outputFileAbsolutePath = parentFolderPath + "\\remux_" + fileEntry.getName();
                String inputVideoAbsolutePath = fileEntry.getAbsolutePath();
                String inputSubtitleAbsolutePath = parentFolderPath + "\\" + baseName + "." + subtitleExtension;
                String param1 = "-o " + outputFileAbsolutePath + " " + inputVideoAbsolutePath + " " + 
                        inputSubtitleAbsolutePath;
//                String param2 = "--default-track \"und\"";
//                String param3 = "--language 0:und " + baseName + "." + subtitleExtension + "\"";
//                System.out.println(param1);
//                System.out.println(param2);
//                System.out.println(param3);
                BufferedReader br = null;
                String line;
                try {
                List<String> list = new ArrayList<String>();
                list.add(mkvmergePath);
                list.add(param1);

                ProcessBuilder build = new ProcessBuilder(list);
                    System.out.println(build.command());
                                        Process process = build.start();

                    InputStream is = process.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    br = new BufferedReader(isr);

                    while ((line = br.readLine()) != null) {
                        System.out.println(line);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }


            }
        }
    }

    public static void main(String[] args) {
        final File folder = new File("C:\\Bleach");
        mergeVideoAndSubtitles(folder, "mkv", "srt");
    }
}
EN

回答 1

Stack Overflow用户

发布于 2019-04-15 00:53:24

我用Go写了一个类似的程序,也遇到了同样的错误。显然,参数中的空格(例如--language 0:eng)导致了这个问题。我试着把它们分成不同的论点,看起来很管用:

代码语言:javascript
复制
public static void main(String[] args) throws IOException {
    String mkvmerge = "C:\\Program Files\\MKVToolNix\\mkvmerge.exe";

    List<String> command = new ArrayList<String>();
    command.add(mkvmerge);

    command.add("--ui-language");
    command.add("en");
    command.add("--output");
    command.add("D:\\Dump\\test.mkv");
    command.add("--language");
    command.add("0:eng");
    command.add("--default-track");
    command.add("0:yes");
    command.add("--language");
    command.add("1:eng");
    command.add("--default-track");
    command.add("1:yes");
    command.add("--language");
    command.add("2:eng");
    command.add("D:\\Dump\\Game of Thrones\\Game.of.Thrones.S01.1080p.WEB-DL.DD5.1.H.264-SA89[rartv]\\Game.of.Thrones.S01E01.Winter.Is.Coming.1080p.WEB-DL.DD5.1.H.264-SA89.mkv");
    command.add("--sub-charset");
    command.add("0:UTF-8");
    command.add("--language");
    command.add("0:eng");
    command.add("D:\\Dump\\Game of Thrones\\Game.of.Thrones.S01.1080p.WEB-DL.DD5.1.H.264-SA89[rartv]\\Subs\\Game.of.Thrones.S01E01.Winter.Is.Coming.1080p.WEB-DL.DD5.1.H.264-SA89.srt");
    command.add("--track-order");
    command.add("0:0,0:1,0:2,1:0");

    ProcessBuilder builder = new ProcessBuilder(command);
    builder.redirectErrorStream(true);
    Process process = builder.start();

    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line = null;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

由于某些原因,这不适用于路径中的空格。这在Go中也是有效的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53090605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档