feat(file): 重构文件服务并优化音乐时长计算
-引入 mp3agic 库替换 jaudiotagger,使用纯 Java 解析 MP3 文件 - 修改 getMusicDuration 方法签名,使用 File 替代 MultipartFile -优化 uploadMusic 方法,返回音乐文件的物理路径 - 更新 MusicServiceImpl 中的音乐上传逻辑 -移除不必要的临时文件操作
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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("上传文件失败");
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user