音频处理服务

This commit is contained in:
2025-10-31 08:50:08 +08:00
parent 07e60cf7f0
commit c4957aa3aa
6 changed files with 117 additions and 129 deletions

View File

@ -1,18 +1,18 @@
package com.fuyuanshen; package com.fuyuanshen;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
/** /**
* 启动程序 * 启动程序
* *
* @author Lion Li * @author Lion Li
*/ */
@SpringBootApplication @SpringBootApplication
@EnableScheduling @EnableScheduling
public class DromaraApplication { public class DromaraApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication application = new SpringApplication(DromaraApplication.class); SpringApplication application = new SpringApplication(DromaraApplication.class);
@ -21,4 +21,4 @@ public class DromaraApplication {
System.out.println("(♥◠‿◠)ノ゙ fys-Vue-Plus启动成功 ლ(´ڡ`ლ)゙"); System.out.println("(♥◠‿◠)ノ゙ fys-Vue-Plus启动成功 ლ(´ڡ`ლ)゙");
} }
} }

View File

@ -8,6 +8,7 @@ import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Arrays; import java.util.Arrays;
@ -101,6 +102,12 @@ public class AudioProcessService {
// log.info("测试文件已保存: {}", savedPath); // log.info("测试文件已保存: {}", savedPath);
// } // }
// 保存WAV文件到本地
String savedPath = saveByteArrayToFile(pcmData, "tts_output.wav");
if (savedPath != null) {
log.info("WAV文件已保存: {}", savedPath);
}
// 将byte[]转换为16进制字符串列表 // 将byte[]转换为16进制字符串列表
List<String> hexList = audioProcessUtil.bytesToHexList(pcmData); List<String> hexList = audioProcessUtil.bytesToHexList(pcmData);
@ -113,6 +120,55 @@ public class AudioProcessService {
} }
} }
public String saveWavFileLocally(String text, String filename) throws IOException {
// 参数校验
if (text == null || text.trim().isEmpty()) {
throw new IllegalArgumentException("文本内容不能为空");
}
if (filename == null || filename.trim().isEmpty()) {
filename = "tts_output.wav"; // 默认文件名
}
try {
// 生成PCM数据
byte[] rawPcmData = alibabaTTSUtil.generateStandardPcmData(text);
// 转换为标准WAV格式添加44字节头部
byte[] wavData = audioProcessUtil.rawPcmToStandardWav(rawPcmData);
// 保存到本地文件
String filePath = saveByteArrayToFile(wavData, filename);
log.info("WAV文件已保存: {}", filePath);
return filePath;
} catch (Exception e) {
log.error("保存WAV文件失败: {}", e.getMessage(), e);
throw new IOException("保存WAV文件失败", e);
}
}
private String saveByteArrayToFile(byte[] data, String filename) throws IOException {
// 确定保存路径(可以是临时目录或指定目录)
String directory = System.getProperty("java.io.tmpdir"); // 使用系统临时目录
File dir = new File(directory);
if (!dir.exists()) {
dir.mkdirs();
}
// 创建完整文件路径
File file = new File(dir, filename);
// 写入文件
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(data);
}
return file.getAbsolutePath();
}
/** /**
* 验证音频文件 * 验证音频文件
*/ */

View File

@ -52,32 +52,32 @@ spring:
url: jdbc:mysql://47.120.79.150:3306/fys-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true url: jdbc:mysql://47.120.79.150:3306/fys-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root username: root
password: Jq_123456# password: Jq_123456#
# # 从库数据源 # # 从库数据源
# slave: # slave:
# lazy: true # lazy: true
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver # driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username: # username:
# password: # password:
# oracle: # oracle:
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver # driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE # url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT # username: ROOT
# password: root # password: root
# postgres: # postgres:
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver # driverClassName: org.postgresql.Driver
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root # username: root
# password: root # password: root
# sqlserver: # sqlserver:
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver # driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true # url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA # username: SA
# password: root # password: root
hikari: hikari:
# 最大连接池数量 # 最大连接池数量
maxPoolSize: 20 maxPoolSize: 20
@ -182,7 +182,7 @@ sms:
#模板变量 上述模板的变量 #模板变量 上述模板的变量
templateName: code templateName: code
signature: 湖北星汉研创科技 signature: 湖北星汉研创科技
# sdk-app-id: 您的sdkAppId # sdk-app-id: 您的sdkAppId
config2: config2:
# 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 # 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分
supplier: tencent supplier: tencent
@ -210,7 +210,7 @@ justauth:
client-id: 449c4*********937************759 client-id: 449c4*********937************759
client-secret: ac7***********1e0************28d client-secret: ac7***********1e0************28d
redirect-uri: ${justauth.address}/social-callback?source=topiam redirect-uri: ${justauth.address}/social-callback?source=topiam
scopes: [openid, email, phone, profile] scopes: [ openid, email, phone, profile ]
qq: qq:
client-id: 10**********6 client-id: 10**********6
client-secret: 1f7d08**********5b7**********29e client-secret: 1f7d08**********5b7**********29e
@ -276,27 +276,6 @@ justauth:
redirect-uri: ${justauth.address}/social-callback?source=gitea redirect-uri: ${justauth.address}/social-callback?source=gitea
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
linux:
path: /home/eladmin/file/
avatar: /home/eladmin/avatar/
windows:
path: C:\eladmin\file\
avatar: C:\eladmin\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5
device:
pic: C:\eladmin\file\ #设备图片存储路径
ip: http://fuyuanshen.com:81/ #服务器地址
app_avatar:
pic: C:\eladmin\file\ #设备图片存储路径
#ip: http://fuyuanshen.com:81/ #服务器地址
ip: https://fuyuanshen.com/ #服务器地址
# MQTT配置 # MQTT配置
mqtt: mqtt:
username: admin username: admin
@ -306,3 +285,11 @@ mqtt:
subTopic: A/# subTopic: A/#
pubTopic: B/# pubTopic: B/#
pubClientId: fys_pubClient pubClientId: fys_pubClient
# TTS语音交互配置
alibaba:
tts:
appKey: KTwSUKMrf2olFfjC
akId: LTAI5t6RsfCvQh57qojzbEoe
akSecret: MTqvK2mXYeCRkl1jVPndiNumyaad0R

View File

@ -294,24 +294,3 @@ alibaba:
akId: LTAI5t6RsfCvQh57qojzbEoe akId: LTAI5t6RsfCvQh57qojzbEoe
akSecret: MTqvK2mXYeCRkl1jVPndiNumyaad0R akSecret: MTqvK2mXYeCRkl1jVPndiNumyaad0R
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
linux:
path: /home/eladmin/file/
avatar: /home/eladmin/avatar/
windows:
path: C:\eladmin\file\
avatar: C:\eladmin\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5
device:
pic: C:\eladmin\file\ #设备图片存储路径
ip: http://fuyuanshen.com:81/ #服务器地址
app_avatar:
pic: C:\eladmin\file\ #设备图片存储路径
#ip: http://fuyuanshen.com:81/ #服务器地址
ip: https://fuyuanshen.com/ #服务器地址

View File

@ -3,7 +3,7 @@ package com.fuyuanshen.equipment.domain.vo;
import lombok.Data; import lombok.Data;
/** /**
* 数据总览 * 首页数据总览
* *
* @author: 默苍璃 * @author: 默苍璃
* @date: 2025-09-0114:24 * @date: 2025-09-0114:24

View File

@ -66,11 +66,6 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
private final ISysRoleService roleService; private final ISysRoleService roleService;
@Value("${file.device.pic}")
private String filePath;
@Value("${file.device.ip}")
private String ip;
private final DeviceMapper deviceMapper; private final DeviceMapper deviceMapper;
private final DeviceTypeMapper deviceTypeMapper; private final DeviceTypeMapper deviceTypeMapper;
private final CustomerMapper customerMapper; private final CustomerMapper customerMapper;
@ -301,35 +296,6 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
} }
/**
* 保存设备图片并返回访问路径
*
* @param file MultipartFile
* @param deviceMac 设备MAC用于生成唯一文件名
* @return 文件存储路径 URL 形式
*/
private String saveDeviceImage(MultipartFile file, String deviceMac) throws IOException {
if (file == null || file.isEmpty()) {
return null;
}
String originalFileName = file.getOriginalFilename();
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
String newFileName = "PS_" + deviceMac + "." + fileExtension;
File newFile = new File(filePath + DeviceConstants.FILE_ACCESS_ISOLATION + File.separator + newFileName);
if (!newFile.getParentFile().exists()) {
newFile.getParentFile().mkdirs();
}
log.info("图片保存路径: {}", newFile.getAbsolutePath());
file.transferTo(newFile);
return ip + DeviceConstants.FILE_ACCESS_PREFIX + "/" + DeviceConstants.FILE_ACCESS_ISOLATION + "/" + newFileName;
}
/** /**
* 删除设备 * 删除设备
* *