加入文字转语音免费版
This commit is contained in:
@@ -5,24 +5,14 @@ import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.jacob.activeX.ActiveXComponent;
|
||||
import com.jacob.com.Dispatch;
|
||||
import com.jacob.com.Variant;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
|
||||
import org.jaudiotagger.audio.mp3.MP3File;
|
||||
import org.jaudiotagger.tag.FieldDataInvalidException;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
@@ -46,15 +36,7 @@ public class BaiduVoicesUtils {
|
||||
// System.out.println("aaa: " + aaa);
|
||||
String text = "天地之道者 ,理也 ; 万物之始者 , 气也 ; 气之聚散者 , 象也; 物之终始者 ,数也 。为 医者尤需明理 ,理不明则法不清 , 法不清则 方药无凭 。 医之理者 ,病理也 , 然欲明病理 ,先知生理 ,故太湖无 中医基础理论课程而有生理 、病理 。生之理者 ,《 内经》 所谓人事 也 ,至于天人之学 , 尚需于太湖国学院求之 。经谓精光之论 , 大圣";
|
||||
// shortText("补充一点,桂枝的主要有效成分是挥发油,大概占桂枝 重量的0.7%左右,不到1%。桂枝挥发油有一个特点,它由呼 吸道排出,对呼吸道炎症有明显的抗炎、祛痰、止咳作用,所 以在麻黄汤里,桂枝既增强了麻黄的发汗作用,又增强了杏仁 的化痰止咳平喘作用。");
|
||||
JacobUtil.text("F:\\a.mp3",text,100,0);
|
||||
// List<String> urls = new ArrayList<>();
|
||||
// urls.add("https://ehh-private-01.oss-cn-beijing.aliyuncs.com/2024/12/09/f56a35760be042debd177dbaac5e4e2e.mp3");
|
||||
// urls.add("https://ehh-private-01.oss-cn-beijing.aliyuncs.com/2024/12/09/dc5ffa920a91485982bac19f788ce33b.mp3");
|
||||
// urls.add("https://ehh-private-01.oss-cn-beijing.aliyuncs.com/2024/12/09/dc5ffa920a91485982bac19f788ce33b.mp3");
|
||||
// urls.add("https://ehh-private-01.oss-cn-beijing.aliyuncs.com/2024/12/09/dc5ffa920a91485982bac19f788ce33b.mp3");
|
||||
// File file = File.createTempFile(UUID.randomUUID().toString(),".mp3",new File("..\\"));
|
||||
// mergeVoices(urls);
|
||||
|
||||
// System.out.println(JacobUtil.toVoice(text));
|
||||
|
||||
// MP3File file = new MP3File("F:/a.mp3");
|
||||
// MP3AudioHeader audioHeader = (MP3AudioHeader)file.getAudioHeader();
|
||||
|
||||
140
src/main/java/com/peanut/common/utils/JacobUtil.java
Normal file
140
src/main/java/com/peanut/common/utils/JacobUtil.java
Normal file
@@ -0,0 +1,140 @@
|
||||
package com.peanut.common.utils;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.jacob.activeX.ActiveXComponent;
|
||||
import com.jacob.com.Dispatch;
|
||||
import com.jacob.com.Variant;
|
||||
import net.sourceforge.lame.lowlevel.LameEncoder;
|
||||
import net.sourceforge.lame.mp3.Lame;
|
||||
import net.sourceforge.lame.mp3.MPEGMode;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
|
||||
import org.jaudiotagger.audio.mp3.MP3File;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
//<dependency>
|
||||
// <groupId>com.hynnet</groupId>
|
||||
// <artifactId>jacob</artifactId>
|
||||
// <version>1.18</version>
|
||||
// </dependency>
|
||||
|
||||
//文字转语音离线工具,windows平台
|
||||
public class JacobUtil {
|
||||
|
||||
public static String toVoice(String text) {
|
||||
try {
|
||||
File wavFile = File.createTempFile(UUID.randomUUID().toString(),".wav",new File("..\\"));
|
||||
text(wavFile.getAbsolutePath(),text,100,0);
|
||||
byte[] bytes = encodeToMp3(wavFile);
|
||||
File file = File.createTempFile(UUID.randomUUID().toString(),".mp3",new File("..\\"));
|
||||
FileCopyUtils.copy(bytes,file);
|
||||
|
||||
String fileUrl = uploadFile(file,".mp3");
|
||||
if (StringUtils.isNotBlank(fileUrl)){
|
||||
MP3File mp3File = new MP3File(file);
|
||||
MP3AudioHeader audioHeader = (MP3AudioHeader)mp3File.getAudioHeader();
|
||||
double intLen = audioHeader.getPreciseTrackLength();
|
||||
BigDecimal bd = new BigDecimal(intLen);
|
||||
bd = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
|
||||
file.delete();
|
||||
fileUrl+=","+bd.toString();
|
||||
}
|
||||
file.delete();
|
||||
return fileUrl;
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public static byte[] encodeToMp3(File wavFile) throws Exception {
|
||||
InputStream wavTestFileInputStream = new BufferedInputStream(new FileInputStream(wavFile));
|
||||
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(wavTestFileInputStream);
|
||||
// LameEncoder encoder = new LameEncoder(audioInputStream.getFormat(), 256, MPEGMode.STEREO, Lame.QUALITY_HIGHEST, false);
|
||||
LameEncoder encoder = new LameEncoder(audioInputStream.getFormat(), 128, MPEGMode.STEREO, Lame.QUALITY_HIGHEST, false);
|
||||
ByteArrayOutputStream mp3 = new ByteArrayOutputStream();
|
||||
byte[] inputBuffer = new byte[encoder.getPCMBufferSize()];
|
||||
byte[] outputBuffer = new byte[encoder.getPCMBufferSize()];
|
||||
int bytesRead;
|
||||
int bytesWritten;
|
||||
while(0 < (bytesRead = audioInputStream.read(inputBuffer))) {
|
||||
bytesWritten = encoder.encodeBuffer(inputBuffer, 0, bytesRead, outputBuffer);
|
||||
mp3.write(outputBuffer, 0, bytesWritten);
|
||||
}
|
||||
encoder.close();
|
||||
return mp3.toByteArray();
|
||||
}
|
||||
public static String uploadFile(File file, String fileName) {
|
||||
String endpoint = ConstantPropertiesUtils.END_POIND;
|
||||
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
|
||||
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
|
||||
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
|
||||
try {
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
fileName = uuid + fileName;
|
||||
String datePath = new DateTime().toString("yyyy/MM/dd");
|
||||
fileName = datePath + "/" + fileName;
|
||||
ossClient.putObject(bucketName, fileName, file);
|
||||
ossClient.shutdown();
|
||||
String url = "https://" + bucketName + "." + endpoint + "/" + fileName;
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean text(String path, String text, int volume, int speed) {
|
||||
try {
|
||||
// 调用dll朗读方法
|
||||
ActiveXComponent ax = new ActiveXComponent("Sapi.SpVoice");
|
||||
// 输入的语言内容
|
||||
Dispatch dispatch = ax.getObject();
|
||||
|
||||
//开始生成语音文件,构建文件流
|
||||
ax = new ActiveXComponent("Sapi.SpFileStream");
|
||||
Dispatch sfFileStream = ax.getObject();
|
||||
//设置文件生成格式
|
||||
ax = new ActiveXComponent("Sapi.SpAudioFormat");
|
||||
Dispatch fileFormat = ax.getObject();
|
||||
|
||||
// 设置音频流格式
|
||||
Dispatch.put(fileFormat, "Type", new Variant(22));
|
||||
// 设置文件输出流格式
|
||||
Dispatch.putRef(sfFileStream, "Format", fileFormat);
|
||||
// 调用输出文件流打开方法,创建一个音频文件
|
||||
Dispatch.call(sfFileStream, "Open", new Variant(path), new Variant(3), new Variant(true));
|
||||
// 设置声音对应输出流为输出文件对象
|
||||
Dispatch.putRef(dispatch, "AudioOutputStream", sfFileStream);
|
||||
// 设置音量 0 - 100
|
||||
Dispatch.put(dispatch, "Volume", new Variant(volume));
|
||||
// 设置速度 语音朗读速度 -10 到 +10
|
||||
Dispatch.put(dispatch, "Rate", new Variant(speed));
|
||||
// 执行朗读
|
||||
Dispatch.call(dispatch, "Speak", new Variant(text));
|
||||
// 关闭输出文件
|
||||
Dispatch.call(sfFileStream, "Close");
|
||||
Dispatch.putRef(dispatch, "AudioOutputStream", null);
|
||||
|
||||
// 关闭资源
|
||||
sfFileStream.safeRelease();
|
||||
fileFormat.safeRelease();
|
||||
// 关闭朗读的操作
|
||||
dispatch.safeRelease();
|
||||
ax.safeRelease();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,7 @@ import java.util.concurrent.Executors;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.peanut.common.utils.BaiduVoicesUtils;
|
||||
import com.peanut.common.utils.ConnUtil;
|
||||
import com.peanut.common.utils.*;
|
||||
import com.peanut.modules.book.service.*;
|
||||
import com.peanut.modules.common.entity.*;
|
||||
import com.peanut.modules.oss.service.OssService;
|
||||
@@ -29,8 +28,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.peanut.common.utils.PageUtils;
|
||||
import com.peanut.common.utils.R;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
||||
@@ -63,7 +60,8 @@ public class BookChapterContentController {
|
||||
@RequestMapping("/contentToVoices")
|
||||
public R contentToVoices(@RequestBody Map<String,Object> params){
|
||||
//调用百度语音合成 API
|
||||
String voices = BaiduVoicesUtils.shortText(params.get("content").toString());
|
||||
// String voices = BaiduVoicesUtils.shortText(params.get("content").toString());
|
||||
String voices = JacobUtil.toVoice(params.get("content").toString());
|
||||
if (StringUtils.isEmpty(voices)) {
|
||||
return R.error("语音上传失败");
|
||||
}
|
||||
@@ -83,7 +81,8 @@ public class BookChapterContentController {
|
||||
public void run() {
|
||||
try {
|
||||
//调用百度语音合成 API
|
||||
String voices = BaiduVoicesUtils.shortText(bcc.getContent());
|
||||
// String voices = BaiduVoicesUtils.shortText(bcc.getContent());
|
||||
String voices = JacobUtil.toVoice(bcc.getContent());
|
||||
if (voices.contains(",")){
|
||||
bcc.setVoices(voices.split(",")[0]);
|
||||
bcc.setVoicesSize(voices.split(",")[1]);
|
||||
|
||||
BIN
src/main/resources/lib/net.sourceforge.lame-3.98.4.jar
Normal file
BIN
src/main/resources/lib/net.sourceforge.lame-3.98.4.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user