diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AudioProcessService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AudioProcessService.java index aa651624..9309bf06 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AudioProcessService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AudioProcessService.java @@ -14,6 +14,7 @@ import com.fuyuanshen.equipment.utils.AlibabaTTSUtil; import com.fuyuanshen.equipment.utils.AudioProcessUtil; import com.fuyuanshen.equipment.utils.FileHashUtil; import com.fuyuanshen.equipment.utils.Mp3Duration; +import com.fuyuanshen.global.mqtt.utils.FfmpegVolumeUtil; import com.fuyuanshen.system.domain.vo.SysOssVo; import com.fuyuanshen.system.service.ISysOssService; import lombok.RequiredArgsConstructor; @@ -195,6 +196,7 @@ public class AudioProcessService { fos.write(data); } + return file.getAbsolutePath(); } @@ -450,6 +452,7 @@ public class AudioProcessService { String accessKeySecret = "2F3sdoBJ08bYvJcuDgSkLnJwGXsvYH"; String appKey = "lbGuq5K5bEH4uxmT"; String savedPath = null; + String savedMp3VolumePath = null; try { // 使用HTTP方式调用 HttpTtsClient httpClient = new HttpTtsClient(accessKeyId, accessKeySecret, appKey); @@ -457,26 +460,31 @@ public class AudioProcessService { byte[] mp3Data = httpClient.synthesizeTextToMp3(text,fileSuffix); // byte[] mp3Data = alibabaTTSUtil.synthesizeTextToMp3(text); - SysOssVo upload = ossService.upload(mp3Data, generateRandomFileName(fileSuffix)); + + AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo(); + + savedPath = saveByteArrayToFile(mp3Data, generateRandomFileName(fileSuffix)); + + Integer mp3Duration = getMp3Duration2(savedPath); + appBusinessFileBo.setDuration(mp3Duration); + + String directory = System.getProperty("java.io.tmpdir"); // 使用系统临时目录 + File file = new File(directory, generateRandomFileName(fileSuffix)); + savedMp3VolumePath = file.getAbsolutePath(); + FfmpegVolumeUtil.increaseMp3Volume(savedPath, savedMp3VolumePath, 12); + + String fileHash = fileHashUtil.getFileHash(file,"SHA-256"); + SysOssVo upload = ossService.updateHash(file, fileHash); // 强制将HTTP替换为HTTPS if (upload.getUrl() != null && upload.getUrl().startsWith("http://")) { upload.setUrl(upload.getUrl().replaceFirst("^http://", "https://")); } - - AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo(); appBusinessFileBo.setFileId(upload.getOssId()); appBusinessFileBo.setBusinessId(deviceId); appBusinessFileBo.setFileType(3L); appBusinessFileBo.setCreateBy(AppLoginHelper.getUserId()); - savedPath = saveByteArrayToFile(mp3Data, generateRandomFileName(fileSuffix)); - if (savedPath != null) { - log.info("MP3文件已保存: {}", savedPath); - Integer mp3Duration = Mp3Duration.getMp3Duration(savedPath); - log.info("MP3文件时长: {} 秒", mp3Duration); - appBusinessFileBo.setDuration(mp3Duration); - } appBusinessFileService.insertByBo(appBusinessFileBo); if (upload != null) { return upload.getUrl(); @@ -488,10 +496,23 @@ public class AudioProcessService { if(savedPath != null){ deleteTempFile(new File(savedPath)); } + if(savedMp3VolumePath != null){ + deleteTempFile(new File(savedMp3VolumePath)); + } } return null; } + private Integer getMp3Duration2(String savedPath) { + if (savedPath != null) { + log.info("MP3文件已保存: {}", savedPath); + Integer mp3Duration = Mp3Duration.getMp3Duration(savedPath); + log.info("MP3文件时长: {} 秒", mp3Duration); + return mp3Duration; + } + return 0; + } + private static final Random random = new Random(); private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/utils/FfmpegVolumeUtil.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/utils/FfmpegVolumeUtil.java new file mode 100644 index 00000000..7dff8069 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/utils/FfmpegVolumeUtil.java @@ -0,0 +1,81 @@ +package com.fuyuanshen.global.mqtt.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class FfmpegVolumeUtil { + + /** + * 使用FFmpeg增加MP3文件的音量 + * + * @param inputFilePath 输入MP3文件路径 + * @param outputFilePath 输出MP3文件路径 + * @param volumeGain 音量增益(例如:1.5表示增加50%音量,2.0表示翻倍) + */ + public static void increaseMp3Volume(String inputFilePath, String outputFilePath, int volumeGain) { + boolean ffmpegAvailable = isFfmpegAvailable(); + if (!ffmpegAvailable) { + System.err.println("FFmpeg未安装或未找到!请安装FFmpeg并确保在系统路径中。"); + return; + } + Process process = null; + try { + // 构建FFmpeg命令 + String command = String.format( + "ffmpeg -i \"%s\" -af \"volume=%sdB\" \"%s\"", + inputFilePath, + volumeGain, + outputFilePath + ); + + System.out.println("执行命令: " + command); + + // 执行FFmpeg命令 + process = Runtime.getRuntime().exec(command); + + // 读取命令执行结果 + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + + // 等待命令执行完成 + int exitCode = process.waitFor(); + if (exitCode == 0) { + System.out.println("音量调整成功!输出文件:" + outputFilePath); + } else { + System.err.println("FFmpeg命令执行失败,退出码:" + exitCode); + } + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } finally { + if (process != null) { + process.destroy(); + } + } + } + + public static void main(String[] args) { + + // 示例用法 + String inputPath = "D:\\http_output9.mp3"; + String outputPath = "D:\\output17.mp3"; + int volumeGain = 12; + + increaseMp3Volume(inputPath, outputPath, volumeGain); + } + + private static boolean isFfmpegAvailable() { + try { + Process process = Runtime.getRuntime().exec("ffmpeg -version"); + int exitCode = process.waitFor(); + return exitCode == 0; + } catch (Exception e) { + return false; + } + } + +} + diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/FileHashUtil.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/FileHashUtil.java index 1e6666f2..f94f6d22 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/FileHashUtil.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/FileHashUtil.java @@ -4,6 +4,8 @@ import org.apache.commons.codec.digest.DigestUtils; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; @@ -67,4 +69,32 @@ public class FileHashUtil { throw new IllegalStateException("算法 " + ALGORITHM + " 不可用", e); } } + + /** + * 获取文件的哈希值 + * // 或者使用特定算法 + * String md5Hash = getFileHash(audioFile, "MD5"); + * String sha256Hash = getFileHash(audioFile, "SHA-256"); + * @param file 文件 + * @param algorithm 哈希算法 + * @return 文件的哈希值 + * @throws Exception 获取文件哈希值时发生的异常 + */ + public String getFileHash(File file, String algorithm) throws Exception { + MessageDigest md = MessageDigest.getInstance(algorithm); + try (FileInputStream fis = new FileInputStream(file)) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = fis.read(buffer)) != -1) { + md.update(buffer, 0, bytesRead); + } + } + byte[] hashBytes = md.digest(); + StringBuilder sb = new StringBuilder(); + for (byte b : hashBytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + } diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysOssService.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysOssService.java index 8adfcda8..cbc0003c 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysOssService.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysOssService.java @@ -68,6 +68,13 @@ public interface ISysOssService { */ SysOssVo updateHash(MultipartFile file, String hash); + /** + * 更新文件 hash 值 + * + * @param file 文件对象 + * @return 匹配的 SysOssVo 列表 + */ + SysOssVo updateHash(File file, String hash); /** * 上传 MultipartFile 到对象存储服务,并保存文件信息到数据库 * diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysOssServiceImpl.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysOssServiceImpl.java index 07bbf1a9..125e5996 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysOssServiceImpl.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysOssServiceImpl.java @@ -226,6 +226,22 @@ public class SysOssServiceImpl implements ISysOssService, OssService { return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, hash); } + @Override + public SysOssVo updateHash(File file, String hash) { + // 2. 先根据 hash 查库(秒传) + SysOssVo exist = baseMapper.selectByHash(hash); + if (exist != null) { + return exist; + } + + String originalfileName = file.getName(); + String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); + OssClient storage = OssFactory.instance(); + UploadResult uploadResult = storage.uploadSuffix(file, suffix); + // 保存文件信息 + return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, hash); + } + /** * 上传 MultipartFile 到对象存储服务,并保存文件信息到数据库