Jacob 文字转语音

1.导入依赖

<dependency>
    <groupId>com.hynnet</groupId>
    <artifactId>jacob</artifactId>
    <version>1.18</version>
</dependency>

2.下载 jacob.dll 文件,将 dll 拷贝到 jdk 的 bin 目录

3.工具类

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import lombok.extern.slf4j.Slf4j;

/**
 * 语音工具
 *
 * @author dev
 */
@Slf4j
public class VoiceUtil {

    /**
     * 阅读文本并输出文件
     *
     * @param text   需要阅读的文本
     * @param speed  阅读速度
     * @param output 输出文件
     */
    public static void speak(String text, Integer speed, String output) {
        ActiveXComponent voiceComponent = null;
        ActiveXComponent fileStreamComponent = null;
        ActiveXComponent audioComponent = null;
        Dispatch voiceDispatch = null;
        Dispatch fileStreamDispatch = null;
        Dispatch audioFormatDispatch = null;
        try {
            voiceComponent = new ActiveXComponent("Sapi.SpVoice");
            fileStreamComponent = new ActiveXComponent("Sapi.SpFileStream");
            audioComponent = new ActiveXComponent("Sapi.SpAudioFormat");
            voiceDispatch = voiceComponent.getObject();
            fileStreamDispatch = fileStreamComponent.getObject();
            audioFormatDispatch = audioComponent.getObject();

            Dispatch.put(audioFormatDispatch, "Type", new Variant(22));
            Dispatch.putRef(fileStreamDispatch, "Format", audioFormatDispatch);
            Dispatch.call(fileStreamDispatch, "Open", new Variant(output), new Variant(3), new Variant(true));
            Dispatch.putRef(voiceDispatch, "AudioOutputStream", fileStreamDispatch);

            voiceComponent.setProperty("Volume", new Variant(100));
            voiceComponent.setProperty("Rate", new Variant(speed));
            Dispatch.call(voiceDispatch, "Speak", new Variant(text));

            Dispatch.call(fileStreamDispatch, "Close");
            Dispatch.putRef(voiceDispatch, "AudioOutputStream", null);
        } catch (Exception e) {
            log.error("朗读文本异常", e);
            throw e;
        } finally {
            if (voiceComponent != null) {
                voiceComponent.safeRelease();
            }
            if (fileStreamComponent != null) {
                fileStreamComponent.safeRelease();
            }
            if (audioComponent != null) {
                audioComponent.safeRelease();
            }
            if (voiceDispatch != null) {
                voiceDispatch.safeRelease();
            }
            if (fileStreamDispatch != null) {
                fileStreamDispatch.safeRelease();
            }
            if (audioFormatDispatch != null) {
                audioFormatDispatch.safeRelease();
            }
        }
    }

}

4.接口

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.cloudbeing.api.util.VoiceUtil;
import com.cloudbeing.framework.common.controller.BaseController;
import com.cloudbeing.framework.web.util.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;

/**
 * 语音播放模块
 *
 * @author dev
 */
@Slf4j
@RestController
@RequestMapping("/test/voice")
public class PortalVoiceController {

    private String voiceOutput = "D:\\data0\\voice\\";

    @GetMapping("/speak")
    public void speak(String text, Integer speed) throws IOException {
        if (StrUtil.isEmpty(text)) {
            return;
        }
        HttpServletResponse response = Response.getResponse();
        response.setContentType("audio/wav");
        Integer s = speed != null ? speed : -2;
        String output = voiceOutput + MD5.create().digestHex(text) + s + ".wav";
        if (!FileUtil.exist(output)) {
            VoiceUtil.speak(text, s, output);
        }
        BufferedInputStream in = null;
        try {
            in = FileUtil.getInputStream(output);
            IoUtil.copy(in, response.getOutputStream());
        } finally {
            IoUtil.close(in);
        }
    }

}

5.测试
image

posted @   ohmok  阅读(192)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示