feat(file): 重构文件服务并优化音乐时长计算

-引入 mp3agic 库替换 jaudiotagger,使用纯 Java 解析 MP3 文件
- 修改 getMusicDuration 方法签名,使用 File 替代 MultipartFile
-优化 uploadMusic 方法,返回音乐文件的物理路径
- 更新 MusicServiceImpl 中的音乐上传逻辑
-移除不必要的临时文件操作
This commit is contained in:
ikmkj
2025-07-27 14:41:27 +08:00
parent a5e2d13435
commit 384b6b667f
4 changed files with 37 additions and 39 deletions

View File

@@ -124,11 +124,12 @@
<version>4.5.0</version>
</dependency>
<!-- 获取音乐文件信息 -->
<!-- 获取音乐文件信息 (使用 JAVE) -->
<!-- 获取音乐文件信息 (使用纯Java的mp3agic) -->
<dependency>
<groupId>org</groupId>
<artifactId>jaudiotagger</artifactId>
<version>2.0.3</version>
<groupId>com.mpatric</groupId>
<artifactId>mp3agic</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>

View File

@@ -2,6 +2,8 @@ package com.test.musichouduan.service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
/**
* 文件服务接口
*/
@@ -19,7 +21,7 @@ public interface FileService {
* 上传音乐
*
* @param file 音乐文件
* @return 音乐URL
* @return 音乐文件的物理路径
*/
String uploadMusic(MultipartFile file);
@@ -42,8 +44,8 @@ public interface FileService {
/**
* 获取音乐时长
*
* @param file 音乐文件
* @param musicFile 音乐文件
* @return 时长(秒)
*/
int getMusicDuration(MultipartFile file);
int getMusicDuration(File musicFile);
}

View File

@@ -3,8 +3,7 @@ package com.test.musichouduan.service.impl;
import com.test.musichouduan.dto.Result;
import com.test.musichouduan.exception.BusinessException;
import com.test.musichouduan.service.FileService;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import com.mpatric.mp3agic.Mp3File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
@@ -73,34 +72,21 @@ public class FileServiceImpl implements FileService {
throw new BusinessException("只能上传mp3、wav格式的音乐");
}
// 上传文件
// 上传文件并返回物理路径
return uploadFile(file, "musics");
}
@Override
public int getMusicDuration(MultipartFile file) {
if (file == null || file.isEmpty()) {
public int getMusicDuration(File musicFile) {
if (musicFile == null || !musicFile.exists()) {
return 0;
}
File tempFile = null;
try {
byte[] bytes = file.getBytes();
// 使用原始文件扩展名创建临时文件
String originalFilename = file.getOriginalFilename();
String extension = getFileExtension(originalFilename);
tempFile = File.createTempFile("music-duration-", "." + extension);
Files.write(tempFile.toPath(), bytes);
AudioFile audioFile = AudioFileIO.read(tempFile);
int duration = audioFile.getAudioHeader().getTrackLength();
return duration;
Mp3File mp3file = new Mp3File(musicFile);
return (int) mp3file.getLengthInSeconds();
} catch (Exception e) {
logger.error("获取音乐 '{}' 时长失败", file.getOriginalFilename(), e);
logger.error("获取音乐 '{}' 时长失败 (使用 mp3agic)", musicFile.getName(), e);
return 0;
} finally {
if (tempFile != null) {
tempFile.delete();
}
}
}
@@ -197,19 +183,18 @@ public class FileServiceImpl implements FileService {
if (!bizDir.exists()) {
boolean ok = bizDir.mkdirs(); // 递归创建
if (!ok) {
Result.error(500, "无法创建目录: " + bizDir.getAbsolutePath());
// 抛出异常而不是返回Result
throw new BusinessException("无法创建目录: " + bizDir.getAbsolutePath());
}
}
File targetFile = new File(bizDir, fileName);
// 保存文件
try {
file.transferTo(targetFile);
// Path path = Paths.get(uploadPath, directory, fileName);
// Files.write(path, file.getBytes());
return accessPath+directory + "/" + fileName;
// 返回文件的绝对物理路径
return targetFile.getAbsolutePath();
} catch (IOException e) {
logger.error("上传文件失败", e);
throw new BusinessException("上传文件失败");

View File

@@ -31,6 +31,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.Optional;
@@ -274,14 +275,23 @@ public class MusicServiceImpl implements MusicService {
@Override
@Transactional
public MusicDTO addMusic(MusicDTO musicDTO, MultipartFile file, MultipartFile cover) {
// 获取音乐时长
int duration = fileService.getMusicDuration(file);
// 1. 先上传音乐文件,获取其物理路径
String musicPhysicalPath = fileService.uploadMusic(file);
File musicFile = new File(musicPhysicalPath);
// 上传音乐文件
String musicUrl = fileService.uploadMusic(file);
// 2. 根据物理文件获取时长
int duration = fileService.getMusicDuration(musicFile);
// 3. 上传封面
String coverPhysicalPath = fileService.uploadImage(cover);
// 4. 将物理路径转换为可访问的URL (这一步需要根据您的配置调整)
// 假设 uploadPath 是 "music-houduan/upload"accessPath 是 "/upload/"
// 物理路径: music-houduan/upload/musics/uuid.mp3
// URL: /upload/musics/uuid.mp3
String musicUrl = musicPhysicalPath.replace(System.getProperty("user.dir") + File.separator + "music-houduan", "").replace(File.separator, "/");
String coverUrl = coverPhysicalPath.replace(System.getProperty("user.dir") + File.separator + "music-houduan", "").replace(File.separator, "/");
// 上传封面
String coverUrl = fileService.uploadImage(cover);
// 创建音乐实体
Music music = new Music();