You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS下Java程序打包为Jar后无法找到yt-dlp路径的问题

问题分析与解决方案

核心问题在于:打包成Jar后,yt-dlp作为嵌入Jar的资源文件无法直接通过文件系统路径访问,且Mac系统下执行外部程序需要可执行权限,这两点是原代码的关键遗漏。

关键修正点

  1. 嵌入Jar的资源必须提取到临时文件,且赋予执行权限
  2. 避免用bash -c拼接命令,改用ProcessBuilder参数列表防止解析错误
  3. 确保资源路径从Jar根目录正确读取

修正后的代码

1. 资源提取与临时文件处理

private Path getFilePath(String resourcePath) {
    try {
        // 从Jar根目录读取资源,路径前加斜杠确保定位正确
        InputStream inputStream = getClass().getResourceAsStream("/" + resourcePath);
        if (inputStream == null) {
            throw new IOException("资源不存在: " + resourcePath);
        }
        // 创建临时文件,命名前缀保留yt-dlp标识
        Path tempFilePath = Files.createTempFile("yt-dlp-", null);
        Files.copy(inputStream, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
        // 赋予执行权限(Mac/Linux下必须,否则无法运行yt-dlp)
        tempFilePath.toFile().setExecutable(true);
        // JVM退出时自动删除临时文件,避免残留
        tempFilePath.toFile().deleteOnExit();
        return tempFilePath.toAbsolutePath();
    } catch (IOException e) {
        throw new RuntimeException("提取资源到临时文件失败: " + resourcePath, e);
    }
}

2. 下载方法重构

private void download() {
    Process process = null;
    try {
        Path ytDlpPath = getFilePath("Zasoby/yt-dlp");
        
        // 用ProcessBuilder参数列表传递命令,避免bash解析引号/特殊字符的问题
        ProcessBuilder processBuilder = new ProcessBuilder(
                ytDlpPath.toString(),
                "-f", "bestaudio",
                "-x",
                "--audio-format", chosenFormat,
                "--no-playlist",
                "--output", outputPath + "/%(title)s.%(ext)s",
                linkYT
        );
        
        processBuilder.inheritIO();
        process = processBuilder.start();
        int exitCode = process.waitFor();

        System.out.println(exitCode + " EXIT CODE");

        if (exitCode != 0) {
            InfoFrame ef = new InfoFrame(2);
            ef.setVisible(true);
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
        InfoFrame ef = new InfoFrame(2);
        ef.setVisible(true);
    } finally {
        // 确保进程被销毁,避免资源泄漏
        if (process != null) {
            process.destroy();
        }
    }
}

额外打包注意事项

  • 确保打包Jar时Zasoby/yt-dlp被正确包含:如果用Maven/Gradle,需将src/Zasoby配置为资源目录,让打包工具自动将其复制到Jar根路径。
  • 若后续打包为Mac App(如用jpackage),可将yt-dlp放在App的Contents/Resources目录下,通过System.getProperty("java.class.path")或App资源路径直接读取,无需每次提取临时文件。

内容的提问来源于stack exchange,提问作者user21588222

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:03:40