ChineseHelper.java 4.39 KB
package com.yanzuoguang.util;

import com.baidu.aip.speech.AipSpeech;
import com.baidu.aip.speech.TtsResponse;
import com.baidu.aip.util.Util;
import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.helper.JsonHelper;
import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.vo.BaiduConfig;
import com.yanzuoguang.util.vo.HanziVo;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 构造函数
 * <p>
 * 百度语音合成接口文档: https://ai.baidu.com/ai-doc/SPEECH/sk38y8hb7
 *
 * @author 颜佐光
 */
public class ChineseHelper {

    /***
     * ^[\u2E80-\u9FFF]+$ 匹配所有东亚区的语言
     * ^[\u4E00-\u9FFF]+$ 匹配简体和繁体
     * ^[\u4E00-\u9FA5]+$ 匹配简体
     */
    private static final Pattern pattern = Pattern.compile("^[\u4E00-\u9FFF]+$");

    /**
     * 获取汉字全拼
     *
     * @param from 来源汉字
     * @return
     */
    public static List<HanziVo> getPinyin(String from) {
        if (StringHelper.isEmpty(from)) {
            return new ArrayList<>(0);
        }

        List<HanziVo> rets = new ArrayList<>(from.length() / 2);
        for (int i = 0; i < from.length(); i++) {
            char unit = from.charAt(i);
            HanziVo hanzi = new HanziVo();
            hanzi.setFrom(unit);
            // 是汉字,则转拼音
            if (pattern.matcher(String.valueOf(unit)).find()) {
                try {
                    String[] items = PinyinHelper.toHanyuPinyinStringArray(unit);
                    hanzi.setTos(items);
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            }
            rets.add(hanzi);
        }
        return rets;
    }

    /**
     * 生成语音
     *
     * @param config 配置
     * @param from   语音文字 合成的文本,使用UTF-8编码, 请注意文本长度必须小于1024字节
     * @param to     目标文件
     */
    public static void saveVideo(BaiduConfig config, String from, File to) {
        // 初始化一个AipSpeech
        AipSpeech client = new AipSpeech(config.getAppId(), config.getApiKey(), config.getSecretKey());

        // 可选:设置网络连接参数
        if (config.getConnectionTimeoutInMillis() > 0) {
            client.setConnectionTimeoutInMillis(config.getConnectionTimeoutInMillis());
        }
        if (config.getSocketTimeoutInMillis() > 0) {
            client.setSocketTimeoutInMillis(config.getSocketTimeoutInMillis());
        }

        // 可选:设置代理服务器地址, http和socket二选一,或者均不设置
        // 设置http代理
        if (!StringHelper.isEmpty(config.getHttpProxyHost()) && config.getHttpProxyPort() > 0) {
            client.setHttpProxy(config.getHttpProxyHost(), config.getHttpProxyPort());
        }
        // 设置socket代理
        else if (!StringHelper.isEmpty(config.getSocketProxyHost()) && config.getSocketProxyPort() > 0) {
            client.setSocketProxy(config.getSocketProxyHost(), config.getSocketProxyPort());
        }

        // 可选:设置log4j日志输出格式,若不设置,则使用默认配置
        // 也可以直接通过jvm启动参数设置此环境变量
        // System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");

        // 设置可选参数
        HashMap<String, Object> options = new HashMap<String, Object>();
        options.put("spd", config.getSpd());
        options.put("pit", config.getPit());
        options.put("per", config.getPer());
        options.put("vol", config.getVol());

        // 调用接口
        TtsResponse res = client.synthesis(from, config.getLang(), config.getCtp(), options);
        byte[] data = res.getData();
        JSONObject res1 = res.getResult();
        if (data != null) {
            try {
                Util.writeBytesToFileSystem(data, to.getAbsolutePath());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            System.out.println(JsonHelper.serialize(res1, true));
            int code = res1.getInt("err_no");
            String message = res1.getString("err_msg");
            throw new CodeException(StringHelper.toString(code), message, res1);
        }
    }
}