jeecgboot/JeecgBoot · error · RuntimeException

edge-tts 执行失败,退出码: {exitCode}

Error message

edge-tts 执行失败,退出码: {exitCode}

What it means

Thrown by VideoGenerationServiceImpl.generateTtsAudio() after spawning the edge-tts command-line tool as a subprocess. edge-tts is a Python CLI that synthesizes speech through Microsoft Edge's online TTS endpoint. The error fires when the process exits with a non-zero code -- the binary is missing, the server has no outbound internet, or the argument list is malformed. The captured stdout/stderr (redirectErrorStream=true) is logged but NOT included in the thrown message.

Source

Thrown at jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/video/service/impl/VideoGenerationServiceImpl.java:553

    }

    /**
     * 使用 edge-tts 将文本转为语音
     */
    private void generateTtsAudio(String text, Path audioPath) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder(
                edgeTtsPath,
                "--voice", "zh-CN-YunyangNeural",
                "--text", text,
                "--write-media", audioPath.toAbsolutePath().toString()
        );
        pb.redirectErrorStream(true);
        Process process = pb.start();
        String output = new String(process.getInputStream().readAllBytes());
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            log.error("edge-tts 执行失败: {}", output);
            throw new RuntimeException("edge-tts 执行失败,退出码: " + exitCode);
        }
    }

    /**
     * 视频生成成功后,自动生成语音并合并(参照 addVoiceover 逻辑)
     * 使用 TTS API(VoiceApiHelper)生成语音,ffmpeg 合并
     * 失败时降级返回无声视频,不影响主流程
     *
     * @param taskId         任务ID
     * @param prompt         用户原始prompt
     * @param localVideoPath 本地无声视频相对路径(如 video/video_xxx.mp4)
     * @param result         结果对象,成功时更新 videoUrl 和 narration
     */
    private void autoAddVoiceover(String taskId, String prompt, String localVideoPath, VideoTaskResultVo result) {
        log.info(">>> autoAddVoiceover 开始: taskId={}, ffmpeg={}, localVideoPath={}", taskId, ffmpegPath, localVideoPath);
        if (ffmpegPath == null) {
            log.info("ffmpeg不可用,跳过自动配音: taskId={}", taskId);
            return;

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Find the captured process output in the log line 'edge-tts 执行失败: {}' -- it holds the real stderr.
  2. Run the binary at edgeTtsPath manually: `edge-tts --voice zh-CN-YunyangNeural --text test --write-media /tmp/t.mp3` to reproduce.
  3. Confirm outbound HTTPS to speech.platform.bing.com / the edge-tts endpoint works from the server.
  4. Install or upgrade edge-tts (`pip install -U edge-tts`) and align edgeTtsPath to the working binary.
  5. Guard empty/oversized text before calling generateTtsAudio.

Example fix

// before
int exitCode = process.waitFor();
if (exitCode != 0) {
    log.error("edge-tts 执行失败: {}", output);
    throw new RuntimeException("edge-tts 执行失败,退出码: " + exitCode);
}
// after - surface the captured output and validate inputs
if (text == null || text.isBlank()) {
    throw new IllegalArgumentException("edge-tts 文本为空");
}
int exitCode = process.waitFor();
if (exitCode != 0) {
    throw new RuntimeException("edge-tts 执行失败,退出码: " + exitCode + ",输出: " + output);
}
Defensive patterns

Strategy: validation

Validate before calling

// run before calling generateTtsAudio
private void ensureEdgeTtsReady(String edgeTtsPath, String text) throws IOException {
    if (text == null || text.isBlank()) {
        throw new IllegalArgumentException("edge-tts 文本为空");
    }
    Path bin = Paths.get(edgeTtsPath);
    if (!Files.isExecutable(bin)) {
        throw new IllegalStateException("edge-tts 不可执行: " + edgeTtsPath);
    }
}

Try / catch

// caller already degrades gracefully -- keep this pattern
try {
    generateTtsAudio(text, audioPath);
} catch (Exception e) {
    log.error(">>> edge-tts 失败,降级返回无声视频: taskId={}", taskId, e);
    // do NOT rethrow -- fall back to silent video
}

Prevention

When it happens

Trigger: generateTtsAudio() runs edgeTtsPath with a fixed voice 'zh-CN-YunyangNeural' and the supplied text. A non-zero exit occurs when: edgeTtsPath is unset/wrong; edge-tts cannot reach speech.platform.bing.com; the text is empty or exceeds edge-tts limits; the Python environment/edge-tts version is broken.

Common situations: Production server without edge-tts installed; edgeTtsPath pointing to a venv that no longer exists; egress firewall blocking the Microsoft TTS host; very long narration text; edge-tts package updated and CLI flags changed.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/48ae7de08eeb51ca. Report an issue: GitHub.