|
@@ -7,34 +7,36 @@ import java.util.HashMap;
|
|
|
|
|
|
import cn.hutool.core.convert.Convert;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
+import cn.hutool.core.io.file.FileWriter;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.http.HtmlUtil;
|
|
|
import cn.hutool.http.HttpUtil;
|
|
|
import cn.hutool.json.JSONArray;
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
+import it.sauronsoftware.jave.AudioAttributes;
|
|
|
+import it.sauronsoftware.jave.Encoder;
|
|
|
+import it.sauronsoftware.jave.EncoderException;
|
|
|
+import it.sauronsoftware.jave.EncodingAttributes;
|
|
|
|
|
|
/**
|
|
|
* 初始化流程音频
|
|
|
+ *
|
|
|
* @author 王帅
|
|
|
*
|
|
|
*/
|
|
|
public class VoiceInitUtil {
|
|
|
-
|
|
|
- public static void main(String[] args) {
|
|
|
- init(1, "D:\\cgj\\xfyunAudio");
|
|
|
- }
|
|
|
-
|
|
|
+
|
|
|
private static final String AREA_CODE = "dpq";
|
|
|
-
|
|
|
+
|
|
|
private static final String prefix = "<span class=\"layui-badge\">停顿";
|
|
|
-
|
|
|
+
|
|
|
private static final String suffix = "秒</span>";
|
|
|
-
|
|
|
+
|
|
|
private static final String VOCIE_HTTP = "http://23.37.100.80:8093";
|
|
|
|
|
|
public static boolean init(Integer planId, String path) {
|
|
|
-
|
|
|
+
|
|
|
String result = HttpUtil.get("http://23.37.100.80:8084/basic/plan/getPlanAreaByPlanId?planId=" + planId);
|
|
|
if (!Blank.notBlank(result)) {
|
|
|
return false;
|
|
@@ -65,83 +67,119 @@ public class VoiceInitUtil {
|
|
|
// 转存音频文件
|
|
|
String audio = "dpq-auto_" + process.get("plan_id") + "_" + process.get("id");
|
|
|
saveAudio(caption, path, audio);
|
|
|
+ getSubtitles(path, audio);
|
|
|
}
|
|
|
return true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成字幕文件
|
|
|
+ * @param path
|
|
|
+ * @param audio
|
|
|
+ */
|
|
|
+ private static void getSubtitles(String path, String audio) {
|
|
|
+ wavToMp3(path + "/uploadFiles/autoAudio/" + audio + ".wav", path + "/uploadFiles/autoAudio/" + audio + ".mp3");
|
|
|
|
|
|
+ HashMap<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("file", FileUtil.file(path + "/uploadFiles/autoAudio/" + audio + ".mp3"));
|
|
|
+ String result = HttpUtil.post(VOCIE_HTTP + "/awaken/transfer", paramMap);
|
|
|
+ JSONObject obj = JSONUtil.parseObj(result);
|
|
|
+ new File(path + "/uploadFiles/autoAudio/" + audio + ".mp3").delete();
|
|
|
+ if (obj.getInt("code") == 0) {
|
|
|
+ String taskId = obj.getStr("data");
|
|
|
+ try {
|
|
|
+ while (true) {
|
|
|
+ result = HttpUtil.get(VOCIE_HTTP + "/awaken/getResult?taskId=" + taskId);
|
|
|
+ obj = JSONUtil.parseObj(result);
|
|
|
+ if (obj.getInt("code") == 0) {
|
|
|
+ FileWriter writer = new FileWriter(path + "/uploadFiles/autoAudio/" + audio + ".json");
|
|
|
+ writer.write(obj.get("data").toString());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Thread.sleep(5000);
|
|
|
+ }
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static void saveAudio(String txt, String path, String audio) {
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
HashMap<String, Object> paramMap = new HashMap<>();
|
|
|
- paramMap.put("txt", txt);
|
|
|
- String result = HttpUtil.post(VOCIE_HTTP + "/awaken/tts", paramMap);
|
|
|
- if (!StrUtil.isBlank(result)) {
|
|
|
- JSONObject obj = JSONUtil.parseObj(result);
|
|
|
- System.err.println(obj);
|
|
|
- // 下载音频文件
|
|
|
- HttpUtil.downloadFile(VOCIE_HTTP + "/download/file?name=" + obj.getStr("data"), FileUtil.file(path + "/uploadFiles/autoAudio/"));
|
|
|
- // 转换格式
|
|
|
- audio = path + "/uploadFiles/autoAudio/" + audio + ".wav";
|
|
|
- try {
|
|
|
+ paramMap.put("txt", txt);
|
|
|
+ String result = HttpUtil.post(VOCIE_HTTP + "/awaken/tts", paramMap);
|
|
|
+ if (!StrUtil.isBlank(result)) {
|
|
|
+ JSONObject obj = JSONUtil.parseObj(result);
|
|
|
+ System.err.println(obj);
|
|
|
+ // 下载音频文件
|
|
|
+ HttpUtil.downloadFile(VOCIE_HTTP + "/download/file?name=" + obj.getStr("data"),
|
|
|
+ FileUtil.file(path + "/uploadFiles/autoAudio/"));
|
|
|
+ // 转换格式
|
|
|
+ audio = path + "/uploadFiles/autoAudio/" + audio + ".wav";
|
|
|
+ try {
|
|
|
convertPcm2Wav(path + "/uploadFiles/autoAudio/" + obj.getStr("data"), audio);
|
|
|
new File(path + "/uploadFiles/autoAudio/" + obj.getStr("data")).delete();
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- System.err.println("转换耗时:"+(System.currentTimeMillis() - startTime));
|
|
|
- }
|
|
|
+ System.err.println("转换耗时:" + (System.currentTimeMillis() - startTime));
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 转换音频文件
|
|
|
- * @param src 需要转换的pcm音频路径
|
|
|
- * @param target 保存转换后wav格式的音频路径
|
|
|
- * @throws Exception
|
|
|
- */
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换音频文件
|
|
|
+ *
|
|
|
+ * @param src 需要转换的pcm音频路径
|
|
|
+ * @param target 保存转换后wav格式的音频路径
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
private static void convertPcm2Wav(String src, String target) throws Exception {
|
|
|
- FileInputStream fis = new FileInputStream(src);
|
|
|
- FileOutputStream fos = new FileOutputStream(target);
|
|
|
-
|
|
|
- //计算长度
|
|
|
- byte[] buf = new byte[1024 * 4];
|
|
|
- int size = fis.read(buf);
|
|
|
- int PCMSize = 0;
|
|
|
- while (size != -1) {
|
|
|
- PCMSize += size;
|
|
|
- size = fis.read(buf);
|
|
|
- }
|
|
|
- fis.close();
|
|
|
-
|
|
|
- //填入参数,比特率等等。这里用的是16位单声道 8000 hz
|
|
|
- WaveHeader header = new WaveHeader();
|
|
|
- //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
|
|
|
- header.fileLength = PCMSize + (44 - 8);
|
|
|
- header.FmtHdrLeth = 16;
|
|
|
- header.BitsPerSample = 16;
|
|
|
- header.Channels = 2;
|
|
|
- header.FormatTag = 0x0001;
|
|
|
- header.SamplesPerSec = 8000;
|
|
|
- header.BlockAlign = (short)(header.Channels * header.BitsPerSample / 8);
|
|
|
- header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
|
|
|
- header.DataHdrLeth = PCMSize;
|
|
|
-
|
|
|
- byte[] h = header.getHeader();
|
|
|
-
|
|
|
- assert h.length == 44; //WAV标准,头部应该是44字节
|
|
|
- //write header
|
|
|
- fos.write(h, 0, h.length);
|
|
|
- //write data stream
|
|
|
- fis = new FileInputStream(src);
|
|
|
- size = fis.read(buf);
|
|
|
- while (size != -1) {
|
|
|
- fos.write(buf, 0, size);
|
|
|
- size = fis.read(buf);
|
|
|
- }
|
|
|
- fis.close();
|
|
|
- fos.close();
|
|
|
- System.out.println("Convert OK!");
|
|
|
- }
|
|
|
-
|
|
|
+ FileInputStream fis = new FileInputStream(src);
|
|
|
+ FileOutputStream fos = new FileOutputStream(target);
|
|
|
+
|
|
|
+ // 计算长度
|
|
|
+ byte[] buf = new byte[1024 * 4];
|
|
|
+ int size = fis.read(buf);
|
|
|
+ int PCMSize = 0;
|
|
|
+ while (size != -1) {
|
|
|
+ PCMSize += size;
|
|
|
+ size = fis.read(buf);
|
|
|
+ }
|
|
|
+ fis.close();
|
|
|
+
|
|
|
+ // 填入参数,比特率等等。这里用的是16位单声道 8000 hz
|
|
|
+ WaveHeader header = new WaveHeader();
|
|
|
+ // 长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
|
|
|
+ header.fileLength = PCMSize + (44 - 8);
|
|
|
+ header.FmtHdrLeth = 16;
|
|
|
+ header.BitsPerSample = 16;
|
|
|
+ header.Channels = 2;
|
|
|
+ header.FormatTag = 0x0001;
|
|
|
+ header.SamplesPerSec = 8000;
|
|
|
+ header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
|
|
|
+ header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
|
|
|
+ header.DataHdrLeth = PCMSize;
|
|
|
+
|
|
|
+ byte[] h = header.getHeader();
|
|
|
+
|
|
|
+ assert h.length == 44; // WAV标准,头部应该是44字节
|
|
|
+ // write header
|
|
|
+ fos.write(h, 0, h.length);
|
|
|
+ // write data stream
|
|
|
+ fis = new FileInputStream(src);
|
|
|
+ size = fis.read(buf);
|
|
|
+ while (size != -1) {
|
|
|
+ fos.write(buf, 0, size);
|
|
|
+ size = fis.read(buf);
|
|
|
+ }
|
|
|
+ fis.close();
|
|
|
+ fos.close();
|
|
|
+ System.out.println("Convert OK!");
|
|
|
+ }
|
|
|
+
|
|
|
private static void changeTxt(JSONObject obj) {
|
|
|
String caption = obj.getStr("caption");
|
|
|
if (caption.indexOf(prefix) == -1) {
|
|
@@ -150,17 +188,44 @@ public class VoiceInitUtil {
|
|
|
String start = caption.substring(caption.indexOf(prefix) + prefix.length());
|
|
|
int time = Convert.toInt(start.substring(0, start.indexOf(suffix)), 0);
|
|
|
String pause = time == 0 ? "" : "[p" + (time * 1000) + "]";
|
|
|
- caption = caption.substring(0, caption.indexOf(prefix)) + pause + start.substring(start.indexOf(suffix) + suffix.length());
|
|
|
+ caption = caption.substring(0, caption.indexOf(prefix)) + pause
|
|
|
+ + start.substring(start.indexOf(suffix) + suffix.length());
|
|
|
obj.set("caption", caption);
|
|
|
if (caption.indexOf(prefix) != -1) {
|
|
|
changeTxt(obj);
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
private static String getChangeTxt(String caption) {
|
|
|
JSONObject obj = new JSONObject();
|
|
|
obj.set("caption", caption);
|
|
|
changeTxt(obj);
|
|
|
return HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(obj.getStr("caption")));
|
|
|
-
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param source
|
|
|
+ * @param desFileName
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static void wavToMp3(String source, String desFileName) {
|
|
|
+ File target = new File(desFileName);
|
|
|
+ AudioAttributes audio = new AudioAttributes();
|
|
|
+ audio.setCodec("libmp3lame");
|
|
|
+ audio.setBitRate(new Integer(36000)); // 音频比率 MP3默认是1280000
|
|
|
+ audio.setChannels(new Integer(2));
|
|
|
+ audio.setSamplingRate(new Integer(44100));
|
|
|
+ EncodingAttributes attrs = new EncodingAttributes();
|
|
|
+ attrs.setFormat("mp3");
|
|
|
+ attrs.setAudioAttributes(audio);
|
|
|
+ Encoder encoder = new Encoder();
|
|
|
+ try {
|
|
|
+ encoder.encode(new File(source), target, attrs);
|
|
|
+ } catch (IllegalArgumentException | EncoderException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
}
|
|
|
}
|