解决byte[]数组转String、重命名等

一、解决byte[]数组转String类型失真

public class ByteConvertUtil {
    
    

    /**
     * 二进制转String
     * @param bArr
     * @return
     */
    public static String bytesToHexString(byte[] bArr) {
    
    
        StringBuffer sb = new StringBuffer(bArr.length);
        String sTmp;
        for (int i = 0; i < bArr.length; i++) {
    
    
            sTmp = Integer.toHexString(0xFF & bArr[i]);
            if (sTmp.length() < 2){
    
    
                sb.append(0);
            }
            sb.append(sTmp.toUpperCase());
        }
        return sb.toString();
    }
    /**
     * hex字符串转byte数组
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte数组结果
     */
    public static byte[] hexToByteArray(String inHex){
    
    
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1){
    
    
            //奇数
            hexlen++;
            result = new byte[(hexlen/2)];
            inHex="0"+inHex;
        }else {
    
    
            //偶数
            result = new byte[(hexlen/2)];
        }
        int j=0;
        for (int i = 0; i < hexlen; i+=2){
    
    
            result[j]=(byte)Integer.parseInt(inHex.substring(i,i+2),16);
            j++;
        }
        return result;
    }
}

二、解决重命名问题

 /**
     * 标签去重
     * @param labelString
     * @return
     */
    public static String deduplicateLabel(String labelString) {
    
    
        String[] labelArray = labelString.split(",");
        Set<String> stringSet = new HashSet<>();
        //去重
        for (String str : labelArray) {
    
    
            if (StringUtils.isBlank(str)) {
    
    
                continue;
            }
            stringSet.add(str);
        }
        //拼接
        StringBuffer deduplicatedString = new StringBuffer();
        for (String str : stringSet) {
    
    
            deduplicatedString.append(str).append(",");
        }
        return deduplicatedString.substring(0, deduplicatedString.length() - 1);
    }

    /**
     * 取别名
     * @param name 名称
     * @return
     */
    public static String aliasName(String name){
    
    
        if(Pattern.matches(".*([1-9][0-9]{0,100000})", name)){
    
    
            //拆分数据
            String substring = name.substring(name.indexOf("(") + 1, name.indexOf(")"));
            int number = Integer.parseInt(substring);
            String[] split = name.split("(");
            return split[0].concat("(").concat(String.valueOf(number+1)).concat(")");
        }else{
    
    
            return name.concat("(1)");
        }
    }

三、服务器成本计算

public class ServerCostUtils {
    
    

    public  static int vmCost(ServerCostVO serverCostVO) {
    
    
        // 服务器按3年折旧,1GB虚拟机使用成本约为11
        // 每核心cpu按0.5元计算
        int cost = 0;
        cost = serverCostVO.getCpu() / 2 + serverCostVO.getMemory() / 1024 * 11;
        return cost;
    }

    public static int ecsCost(ServerCostVO serverCostVO) {
    
    
        String ecsType = serverCostVO.getCpu() + "/" + serverCostVO.getMemory() / 1024;
        // cpu / memory(GB) 此费用在阿里云查询得到
        switch (ecsType) {
    
    
            case "1/1":
                return 105;
            case "1/2":
                return 129;
            case "2/4":
                return 237;
            case "4/8":
                return 437;
            case "8/16":
                return 825;
            case "16/32":
                return 1601;
            case "32/64":
                return 3153;
            default:
                return 0;
        }
    }
}

四、流式合成TTS

依赖

        <dependency>
            <groupId>com.alibaba.nls</groupId>
            <artifactId>nls-sdk-tts</artifactId>
            <version>2.1.6</version>
        </dependency>

代码

import com.alibaba.nls.client.AccessToken;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.OutputFormatEnum;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;
import com.citydo.xclouddesk.dialogflow.utils.BitUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

/**
 *
 * 语音合成API调用。
 * 动态获取token。
 * 流式合成TTS。
 * 首包延迟计算。
 *
 */
@Slf4j
public class SpeechUtils {
    
    

    private InputStream inputStream;

    private byte[] bytes;

    private String appKey;

    NlsClient client;
    /**
     * 初始化参数
     * @param appKey
     * @param accessKeyId
     * @param accessKeySecret
     * @param url
     */
    public SpeechUtils(String appKey, String accessKeyId, String accessKeySecret, String url) {
    
    
        this.appKey = appKey;
        AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
        try {
    
    
            accessToken.apply();
            if(url.isEmpty()) {
    
    
                client = new NlsClient(accessToken.getToken());
            }else {
    
    
                client = new NlsClient(url, accessToken.getToken());
            }
        } catch (IOException e) {
    
    
            log.error("客户端连接创建失败:{}", e);
        }
    }

  public SpeechSynthesizerListener SpeechUtilBuffer() {
    
    
        SpeechSynthesizerListener listener = null;
        try {
    
    
             listener = new SpeechSynthesizerListener() {
    
    
                private boolean firstRecvBinary = true;
                private StringBuffer buffer = new StringBuffer();
                //语音合成结束
                @Override
                public void onComplete(SpeechSynthesizerResponse response) {
    
    
                    bytes = ByteConvertUtil.hexToByteArray(buffer.toString());
                }
                //语音合成的语音二进制数据
                @Override
                public void onMessage(ByteBuffer message) {
    
    
                    try {
    
    
                        if (firstRecvBinary) {
    
    
                            //计算首包语音流的延迟,收到第一包语音流时,即可以进行语音播放,以提升响应速度(特别是实时交互场景下)。
                            firstRecvBinary = false;
                        }
                        byte[] bytesArray = new byte[message.remaining()];
                        message.get(bytesArray, 0, bytesArray.length);
                        buffer.append(ByteConvertUtil.bytesToHexString(bytesArray));
                    } catch (Exception e) {
    
    
                        log.error("语音合成流失败:{}", e);
                    }
                }
                @Override
                public void onFail(SpeechSynthesizerResponse response) {
    
    }
            };
        } catch (Exception e) {
    
    
            log.error("TTS调用失败:{}",e);
        }
        return listener;
   }


    public SpeechSynthesizerListener SpeechUtilStream() {
    
    
        SpeechSynthesizerListener listener = null;
        try {
    
    
            listener = new SpeechSynthesizerListener() {
    
    
                private boolean firstRecvBinary = true;
                private ByteArrayOutputStream buf = new ByteArrayOutputStream();
                //语音合成结束
                @Override
                public void onComplete(SpeechSynthesizerResponse response) {
    
    
                    inputStream = new ByteArrayInputStream(buf.toByteArray());
                }
                //语音合成的语音二进制数据
                @Override
                public void onMessage(ByteBuffer message) {
    
    
                    try {
    
    
                        if (firstRecvBinary) {
    
    
                            //计算首包语音流的延迟,收到第一包语音流时,即可以进行语音播放,以提升响应速度(特别是实时交互场景下)。
                            firstRecvBinary = false;
                        }
                        byte[] bytesArray = new byte[message.remaining()];
                        message.get(bytesArray, 0, bytesArray.length);
                        buf.write(bytesArray, 0, bytesArray.length);
                        buf.flush();
                    } catch (Exception e) {
    
    
                        log.error("语音合成流失败:{}", e);
                    }
                }
                @Override
                public void onFail(SpeechSynthesizerResponse response) {
    
    }
            };
        } catch (Exception e) {
    
    
            log.error("TTS调用失败:{}",e);
        }
        return listener;
    }


    /**
     * 初始化参数
     * @param text
     * @param voice
     * @param volume
     * @param speechRate
     * @param pitchRate
     */
    public void process(String text, String voice, Integer volume, Integer speechRate, Integer pitchRate, boolean isType) {
    
    
        SpeechSynthesizer synthesizer = null;
        try {
    
    
            //创建实例,建立连接。
            if(isType){
    
    
                synthesizer = new SpeechSynthesizer(client, SpeechUtilBuffer());
            }else {
    
    
                synthesizer = new SpeechSynthesizer(client, SpeechUtilStream());
            }
            synthesizer.setAppKey(appKey);
            //设置返回音频的编码格式
            synthesizer.setFormat(OutputFormatEnum.WAV);
            //设置返回音频的采样率
            synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
            //发音人
            synthesizer.setVoice(StringUtils.isEmpty(voice) ? "xiaoyun" :voice);
            //语调,范围是-500~500,可选,默认是0。
            synthesizer.setPitchRate(StringUtils.isEmpty(pitchRate) ? 0 : pitchRate);
            //语速,范围是-500~500,默认是0。
            synthesizer.setSpeechRate(StringUtils.isEmpty(speechRate) ? 0 : speechRate);
            //音量
            synthesizer.setVolume(StringUtils.isEmpty(volume) ? 50 : volume);
            //设置用于语音合成的文本
            synthesizer.setText(text);
            // 是否开启字幕功能(返回相应文本的时间戳),默认不开启,需要注意并非所有发音人都支持该参数。
            synthesizer.addCustomedParam("enable_subtitle", false);
            synthesizer.start();
            synthesizer.waitForComplete();
        } catch (Exception e) {
    
    
            log.error("TTS合成语音失败:{}",e);
        } finally {
    
    
            //关闭连接
            if (null != synthesizer) {
    
    
                synthesizer.close();
            }
        }
    }

    public void shutdown() {
    
    
        client.shutdown();
    }


    public void setAppKey(String appKey) {
    
    
        this.appKey = appKey;
    }

    public String getAppKey() {
    
    
        return appKey;
    }

    public byte[] getBytes() {
    
    
        return bytes;
    }

    public void setBytes(byte[] bytes) {
    
    
        this.bytes = bytes;
    }

    public InputStream getInputStream() {
    
    
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
    
    
        this.inputStream = inputStream;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32447301/article/details/108230814