ws 2 years ago
parent
commit
df411e3354

+ 23 - 29
spring-cloud/server-basic/pom.xml

@@ -42,11 +42,8 @@
 			<artifactId>mysql-connector-java</artifactId>
 		</dependency>
 
-		<!--<dependency>
-			<groupId>org.mybatis.spring.boot</groupId>
-			<artifactId>mybatis-spring-boot-starter</artifactId>
-			<version>${mybatis-spring-boot-starter}</version>
-		</dependency>-->
+		<!--<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> 
+			<version>${mybatis-spring-boot-starter}</version> </dependency> -->
 		<dependency>
 			<groupId>com.alibaba</groupId>
 			<artifactId>fastjson</artifactId>
@@ -71,12 +68,12 @@
 			<groupId>org.springframework.cloud</groupId>
 			<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
 		</dependency>
-        <dependency>
-            <groupId>com.github.xiaoymin</groupId>
-            <artifactId>knife4j-spring-boot-autoconfigure</artifactId>
-            <version>2.0.3</version>
-            <scope>compile</scope>
-        </dependency>
+		<dependency>
+			<groupId>com.github.xiaoymin</groupId>
+			<artifactId>knife4j-spring-boot-autoconfigure</artifactId>
+			<version>2.0.3</version>
+			<scope>compile</scope>
+		</dependency>
 
 		<!-- Mybatis-Plus依赖 -->
 		<dependency>
@@ -84,7 +81,7 @@
 			<artifactId>mybatis-plus-boot-starter</artifactId>
 			<version>3.4.2</version>
 		</dependency>
-		<!--阿里云短信相关-->
+		<!--阿里云短信相关 -->
 		<dependency>
 			<groupId>com.aliyun</groupId>
 			<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
@@ -107,7 +104,15 @@
 			<groupId>org.seleniumhq.selenium</groupId>
 			<artifactId>selenium-java</artifactId>
 		</dependency>
-    </dependencies>
+		
+        <dependency>
+            <groupId>it.sauronsoftware</groupId>
+            <artifactId>jave</artifactId>
+            <version>1.0.2</version>
+        </dependency>
+		
+
+	</dependencies>
 
 	<build>
 		<plugins>
@@ -115,19 +120,10 @@
 				<groupId>org.springframework.boot</groupId>
 				<artifactId>spring-boot-maven-plugin</artifactId>
 			</plugin>
-			<!-- <plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-jar-plugin</artifactId>
-				<configuration>
-					<archive>
-						<manifest>
-							<addClasspath>true</addClasspath>
-							<classpathPrefix>lib/</classpathPrefix>
-							<mainClass>com.jd.ServerBasicApplication</mainClass>
-						</manifest>
-					</archive>
-				</configuration>
-			</plugin> -->
+			<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> 
+				<configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> 
+				<mainClass>com.jd.ServerBasicApplication</mainClass> </manifest> </archive> 
+				</configuration> </plugin> -->
 			<!-- 添加配置跳过测试 -->
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
@@ -140,9 +136,7 @@
 		<resources>
 			<resource>
 				<directory>src/main/resources</directory>
-				<!-- <excludes>
-					<exclude>**/**</exclude>
-				</excludes> -->
+				<!-- <excludes> <exclude>**/**</exclude> </excludes> -->
 			</resource>
 		</resources>
 	</build>

+ 140 - 75
spring-cloud/server-basic/src/main/java/com/jd/util/VoiceInitUtil.java

@@ -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 = "&lt;span class=\"layui-badge\"&gt;停顿";
-	
+
 	private static final String suffix = "秒&lt;/span&gt;";
-	
+
 	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();
+		}
 	}
 }

+ 162 - 0
voice/magic-api/src/main/java/com/magicapi/frame/SubFrame.java

@@ -0,0 +1,162 @@
+package com.magicapi.frame;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import javax.swing.JFrame;
+
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import javafx.scene.control.Label;
+import javafx.application.Platform;
+import javafx.embed.swing.JFXPanel;
+import javafx.scene.Scene;
+import javafx.scene.text.Font;
+import javafx.scene.text.Text;
+import javafx.scene.Group;
+
+public class SubFrame extends JFrame {
+	public static void main(String[] args) {
+		new SubFrame("http://127.0.0.1:8848/fz/5i50tdlsx3tnub1ex77vy3t567frltjj.mp3");
+	}
+
+	private static final long serialVersionUID = 1L;
+	private int width = 0;
+	private int height = 300;
+	private int x = 0;
+	private int y = 0;
+	private final JFXPanel jfxPanel;
+
+	private Thread thread;
+
+	private JSONArray array;
+
+	private int index;
+
+	JFrame frame;
+
+	private Label label;
+	
+	private int isStatis = 0;
+
+	public SubFrame(String path) {
+		Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
+		y = screensize.height - height - 200;
+		frame = this;
+		jfxPanel = new JFXPanel();
+		frame.setLayout(new BorderLayout());
+		frame.add(jfxPanel, BorderLayout.CENTER);
+		array = getSubs(path);
+		isStatis = 0;
+		Platform.runLater(new Runnable() {
+
+			@Override
+			public void run() {
+				Group group = new Group();
+				Scene scene = new Scene(group);
+				scene.setFill(javafx.scene.paint.Color.TRANSPARENT);
+				jfxPanel.setScene(scene);
+
+				Text text = new Text(array.getJSONObject(0).getStr("onebest"));
+				text.setFont(Font.font("微软雅黑", 70));
+				width = (int) Math.ceil(text.getLayoutBounds().getWidth());
+				label = new Label("");
+				label.setFont(Font.font("微软雅黑", 70));
+				label.setPrefHeight(300);
+				label.setTextFill(javafx.scene.paint.Color.rgb(223, 250, 255));
+				group.getChildren().add(label);
+
+				thread = new Thread(new Runnable() {
+					@Override
+					public void run() {
+						// TODO Auto-generated method stub
+						while (true) {
+							for (index = 0; index < array.size(); index++) {
+								if (isStatis < 0) {
+									isStatis++;
+									index = 0;
+								}
+								System.err.println(index);
+								JSONObject obj = array.getJSONObject(index);
+								text.setText(obj.getStr("onebest"));
+								int nw = (int) Math.ceil(text.getLayoutBounds().getWidth());
+								width = nw;
+								Platform.runLater(new Runnable() {
+									@Override
+									public void run() {
+										// 更新JavaFX的主线程的代码放在此处
+										frame.setSize(width, height);
+										x = (screensize.width - width) / 2;
+										frame.setLocation(x, y);
+										label.setPrefWidth(nw);
+										label.setText(obj.getStr("onebest"));
+									}
+								});
+								try {
+									Thread.sleep(obj.getInt("ed") - obj.getInt("bg"));
+								} catch (Exception e) {
+									e.printStackTrace();
+								}
+							}
+						}
+					}
+				});
+				thread.start();
+			}
+
+		});
+		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		frame.setSize(width, height);
+		x = (screensize.width - width) / 2;
+		frame.setLocation(x, y);
+		frame.setAlwaysOnTop(true);
+		frame.setUndecorated(true);
+		frame.setBackground(new Color(0, 0, 0, 0));
+		frame.setVisible(array == null ? false : true);
+	}
+
+	public void setNewPath(String path) {
+		thread.suspend();
+		Platform.runLater(new Runnable() {
+			@Override
+			public void run() {
+				label.setText("");
+			}
+		});
+		array = getSubs(path);
+		index = 0;
+		isStatis = -2;
+		thread.resume();
+		thread.interrupt();
+		frame.setVisible(array == null ? false : true);
+	}
+
+	public void stop() {
+		thread.suspend();
+		Platform.runLater(new Runnable() {
+			@Override
+			public void run() {
+				label.setText("");
+			}
+		});
+		frame.setVisible(false);
+	}
+
+	private JSONArray getSubs(String path) {
+		String name = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
+		String subPath = path.substring(0, path.lastIndexOf("/") + 1) + name + ".json";
+		String result = HttpUtil.get(subPath);
+		try {
+			JSONObject obj = JSONUtil.parseObj(result);
+			JSONArray array = JSONUtil.parseArray(obj.getStr("data"));
+			return array;
+		} catch (Exception e) {
+			System.err.println("没有找到字幕文件!");
+		}
+		return null;
+	}
+
+}

+ 54 - 0
voice/magic-api/src/main/java/com/magicapi/util/SimplyPlayerHttp.java

@@ -27,12 +27,34 @@ import javax.swing.JPanel;
 import javax.swing.UIManager;
 import javax.swing.UnsupportedLookAndFeelException;
 
+import com.magicapi.frame.SubFrame;
+
 public class SimplyPlayerHttp {
+	public static void main(String[] args) throws InterruptedException {
+		SimplyPlayerHttp http = new SimplyPlayerHttp("");
+		Thread thread = new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				// TODO Auto-generated method stub
+				http.setPath("http://127.0.0.1:8848/fz/5i50tdlsx3tnub1ex77vy3t567frltjj.wav");
+			}
+		});
+		thread.start();
+		Thread.sleep(5000);
+		http.stopAudio();
+		thread.interrupt();
+		Thread.sleep(5000);
+		http.setPath("http://127.0.0.1:8848/fz/5i50tdlsx3tnub1ex77vy3t567frltjj.wav");
+		thread.resume();
+	}
 
 	private TestPane testPane;
 	
 	private JFrame frame;
 	
+	private SubFrame subFrame;
+	
 	public SimplyPlayerHttp(String path) {
 		EventQueue.invokeLater(new Runnable() {
 			@Override
@@ -91,6 +113,7 @@ public class SimplyPlayerHttp {
 	
 	public void stopAudio() {
 		testPane.stopPlay();
+		subFrame.stop();
 	}
 
 	public void setPath(String path) {
@@ -114,6 +137,11 @@ public class SimplyPlayerHttp {
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 				}
+				if (subFrame == null) {
+					subFrame = new SubFrame(path);
+				} else {
+					subFrame.setNewPath(path);
+				}
 				testPane.play.doClick();
 			}
 		});
@@ -174,6 +202,7 @@ public class SimplyPlayerHttp {
 							clip.addLineListener(new LineListener() {
 								@Override
 								public void update(LineEvent event) {
+									System.err.println(event);
 									if (event.getType().equals(Type.START)) {
 										play.setText("||");
 									} else if (event.getType().equals(Type.OPEN)) {
@@ -229,6 +258,31 @@ public class SimplyPlayerHttp {
 			DataLine.Info info = new DataLine.Info(Clip.class, format);
 			this.clip = (Clip) AudioSystem.getLine(info);
 			this.clip.open(audioStream);
+			
+			 int frameLength = clip.getFrameLength();
+	            //progressBar与frameLength之间的映射关系
+			 System.err.println(frameLength);
+	            new Thread(new Runnable() {
+					
+					@Override
+					public void run() {
+						// TODO Auto-generated method stub
+			                //获取当前播放点
+						while (true) {
+							if (clip.getFrameLength() == clip.getFramePosition()) {
+								subFrame.stop();
+							}
+							try {
+								Thread.sleep(1000);
+							} catch (InterruptedException e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							}
+						}
+			 
+					}
+				}).start();
+
 
 		}
 	}

+ 2 - 2
xfyun-api/src/main/java/com/jd/util/TtsTool.java

@@ -29,8 +29,8 @@ public class TtsTool {
         if (mTts != null) {
             // 设置发音人
             mTts.setParameter(SpeechConstant.VOICE_NAME, "aisjinger");
-            mTts.setParameter(SpeechConstant.SPEED, "150");//设置语速
-            mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100
+            mTts.setParameter(SpeechConstant.SPEED, "80");//设置语速
+            mTts.setParameter(SpeechConstant.VOLUME, "50");//设置音量,范围0~100
         } else {
             LOGGER.error("tts handler init fail");
         }