diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 63ca34f..c1d5207 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,12 @@
spring-boot-starter-thymeleaf
+
+ net.jthink
+ jaudiotagger
+ 3.0.1
+
+
diff --git a/src/main/java/top/baogutang/music/client/NetEaseMusicClient.java b/src/main/java/top/baogutang/music/client/NetEaseMusicClient.java
index 94e58ad..a8580b0 100644
--- a/src/main/java/top/baogutang/music/client/NetEaseMusicClient.java
+++ b/src/main/java/top/baogutang/music/client/NetEaseMusicClient.java
@@ -8,6 +8,7 @@ import top.baogutang.music.domain.req.search.MusicSearchReq;
import top.baogutang.music.domain.res.download.MusicDownloadRes;
import top.baogutang.music.domain.res.search.*;
import top.baogutang.music.enums.ChannelEnum;
+import top.baogutang.music.processor.AbstractAudioProcessor;
import top.baogutang.music.properties.NetEaseMusicProperties;
import top.baogutang.music.service.IMusicRecordService;
import top.baogutang.music.utils.OkHttpUtil;
@@ -101,19 +102,13 @@ public class NetEaseMusicClient implements ChannelClient StringUtils.equalsIgnoreCase(fileType, f.name()))
+ .findFirst()
+ .orElse(OTHERS);
+ }
+}
diff --git a/src/main/java/top/baogutang/music/processor/AbstractAudioProcessor.java b/src/main/java/top/baogutang/music/processor/AbstractAudioProcessor.java
new file mode 100644
index 0000000..1bd1a9b
--- /dev/null
+++ b/src/main/java/top/baogutang/music/processor/AbstractAudioProcessor.java
@@ -0,0 +1,85 @@
+package top.baogutang.music.processor;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jaudiotagger.audio.exceptions.CannotReadException;
+import org.jaudiotagger.audio.exceptions.CannotWriteException;
+import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
+import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
+import org.jaudiotagger.tag.TagException;
+import top.baogutang.music.domain.res.download.MusicDownloadRes;
+import top.baogutang.music.enums.AudioFileTypeEnum;
+import top.baogutang.music.exceptions.BusinessException;
+
+import java.io.*;
+import java.net.URL;
+
+/**
+ *
+ * @description:
+ *
+ * @author: N1KO
+ * @date: 2024/12/12 : 12:15
+ */
+@Slf4j
+public abstract class AbstractAudioProcessor {
+
+ public static AbstractAudioProcessor getAudioProcessor(String fileType) {
+ AudioFileTypeEnum fileTypeEnum = AudioFileTypeEnum.parse(fileType);
+ switch (fileTypeEnum) {
+ case FLAC:
+ return new FlacAudioProcessor();
+ case MP3:
+ return new Mp3AudioProcessor();
+ default:
+ throw new BusinessException("不支持文件格式");
+ }
+ }
+
+ public InputStream processAudioTags(InputStream inputStream, MusicDownloadRes res) {
+ File file = null;
+ try {
+ file = convertInputStreamToTempFile(inputStream);
+ return process(file, res);
+ } catch (Exception e) {
+ log.error(">>>>>>>>>>processAudioTags error:{}<<<<<<<<<<", e.getMessage(), e);
+ return null;
+ } finally {
+ if (file != null && file.exists()) {
+ file.delete();
+ }
+ }
+ }
+
+ abstract InputStream process(File file, MusicDownloadRes res) throws TagException, CannotWriteException, IOException, CannotReadException, InvalidAudioFrameException, ReadOnlyFileException;
+
+
+ protected byte[] fetchImageData(String imageUrl) {
+ try (InputStream inputStream = new URL(imageUrl).openStream();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ return outputStream.toByteArray();
+ } catch (IOException e) {
+ log.error("Error downloading image from URL: {}", imageUrl, e);
+ return new byte[0];
+ }
+ }
+
+
+ private File convertInputStreamToTempFile(InputStream inputStream) throws IOException {
+ // 创建临时文件
+ File tempFile = File.createTempFile("tempFile", ".tmp");
+ // 写入 InputStream 数据到临时文件
+ try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ }
+ return tempFile;
+ }
+}
diff --git a/src/main/java/top/baogutang/music/processor/FlacAudioProcessor.java b/src/main/java/top/baogutang/music/processor/FlacAudioProcessor.java
new file mode 100644
index 0000000..d31f0a0
--- /dev/null
+++ b/src/main/java/top/baogutang/music/processor/FlacAudioProcessor.java
@@ -0,0 +1,49 @@
+package top.baogutang.music.processor;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jaudiotagger.audio.AudioFile;
+import org.jaudiotagger.audio.exceptions.CannotReadException;
+import org.jaudiotagger.audio.exceptions.CannotWriteException;
+import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
+import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
+import org.jaudiotagger.audio.flac.FlacFileReader;
+import org.jaudiotagger.audio.flac.FlacFileWriter;
+import org.jaudiotagger.tag.FieldDataInvalidException;
+import org.jaudiotagger.tag.FieldKey;
+import org.jaudiotagger.tag.Tag;
+import org.jaudiotagger.tag.TagException;
+import org.jaudiotagger.tag.images.StandardArtwork;
+import top.baogutang.music.domain.res.download.MusicDownloadRes;
+
+import java.io.*;
+
+/**
+ *
+ * @description:
+ *
+ * @author: N1KO
+ * @date: 2024/12/12 : 10:40
+ */
+@Slf4j
+public class FlacAudioProcessor extends AbstractAudioProcessor {
+
+
+ @Override
+ InputStream process(File file, MusicDownloadRes res) throws TagException, CannotWriteException, IOException, CannotReadException, InvalidAudioFrameException, ReadOnlyFileException {
+ FlacFileReader flacFileReader = new FlacFileReader();
+ AudioFile audioFile = flacFileReader.read(file);
+ Tag tag = audioFile.getTag();
+ tag.setField(FieldKey.TITLE, res.getName());
+ tag.setField(FieldKey.ALBUM, res.getAlbumName());
+ tag.setField(FieldKey.ARTIST, res.getArtistName());
+ tag.setField(FieldKey.LYRICS, res.getLyric());
+ StandardArtwork artwork = new StandardArtwork();
+ artwork.setImageUrl(res.getPic());
+ artwork.setBinaryData(fetchImageData(res.getPic()));
+ tag.setField(artwork);
+ FlacFileWriter flacFileWriter = new FlacFileWriter();
+ flacFileWriter.write(audioFile);
+ return new FileInputStream(file);
+ }
+}
+
diff --git a/src/main/java/top/baogutang/music/processor/Mp3AudioProcessor.java b/src/main/java/top/baogutang/music/processor/Mp3AudioProcessor.java
new file mode 100644
index 0000000..5acdec3
--- /dev/null
+++ b/src/main/java/top/baogutang/music/processor/Mp3AudioProcessor.java
@@ -0,0 +1,48 @@
+package top.baogutang.music.processor;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jaudiotagger.audio.AudioFile;
+import org.jaudiotagger.audio.exceptions.CannotReadException;
+import org.jaudiotagger.audio.exceptions.CannotWriteException;
+import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
+import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
+import org.jaudiotagger.audio.flac.FlacFileWriter;
+import org.jaudiotagger.audio.mp3.MP3FileReader;
+import org.jaudiotagger.tag.FieldKey;
+import org.jaudiotagger.tag.Tag;
+import org.jaudiotagger.tag.TagException;
+import org.jaudiotagger.tag.images.StandardArtwork;
+import top.baogutang.music.domain.res.download.MusicDownloadRes;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ *
+ * @description:
+ *
+ * @author: N1KO
+ * @date: 2024/12/12 : 13:32
+ */
+@Slf4j
+public class Mp3AudioProcessor extends AbstractAudioProcessor {
+ @Override
+ InputStream process(File file, MusicDownloadRes res) throws TagException, CannotWriteException, IOException, CannotReadException, InvalidAudioFrameException, ReadOnlyFileException {
+ MP3FileReader fileReader = new MP3FileReader();
+ AudioFile audioFile = fileReader.read(file);
+ Tag tag = audioFile.getTag();
+ tag.setField(FieldKey.TITLE, res.getName());
+ tag.setField(FieldKey.ALBUM, res.getAlbumName());
+ tag.setField(FieldKey.ARTIST, res.getArtistName());
+ tag.setField(FieldKey.LYRICS, res.getLyric());
+ StandardArtwork artwork = new StandardArtwork();
+ artwork.setImageUrl(res.getPic());
+ artwork.setBinaryData(fetchImageData(res.getPic()));
+ tag.setField(artwork);
+ FlacFileWriter flacFileWriter = new FlacFileWriter();
+ flacFileWriter.write(audioFile);
+ return new FileInputStream(file);
+ }
+}
diff --git a/src/main/java/top/baogutang/music/service/AbstractMusicService.java b/src/main/java/top/baogutang/music/service/AbstractMusicService.java
index 1b5b917..691e2c5 100644
--- a/src/main/java/top/baogutang/music/service/AbstractMusicService.java
+++ b/src/main/java/top/baogutang/music/service/AbstractMusicService.java
@@ -1,6 +1,7 @@
package top.baogutang.music.service;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import top.baogutang.music.client.ChannelClient;
import top.baogutang.music.domain.req.AbstractMusicReq;
import top.baogutang.music.domain.req.search.MusicSearchReq;
@@ -68,21 +69,28 @@ public abstract class AbstractMusicService channelClient = channelClientFactory.getClient(channelEnum);
MusicDownloadRes res = channelClient.download(id);
- channelClient.saveMusic(res);
-// CompletableFuture.runAsync(() -> {
-// try {
-// channelClient.processFile(res);
-// } catch (IOException e) {
-// log.error(">>>>>>>>>>download error:{}<<<<<<<<<<", e.getMessage(), e);
-// throw new BusinessException("下载异常");
-// }
-// }, commonExecutor);
- try {
- channelClient.processFile(res);
- } catch (IOException e) {
- log.error(">>>>>>>>>>download error:{}<<<<<<<<<<", e.getMessage(), e);
- throw new BusinessException("下载异常");
+ if (StringUtils.isNotBlank(res.getArtistName())) {
+ String[] split = res.getArtistName().split("/");
+ String artistName = String.join(",", split);
+ res.setArtistName(artistName);
}
+
+ channelClient.saveMusic(res);
+ CompletableFuture.runAsync(() -> {
+ try {
+ channelClient.processFile(res);
+ log.info(">>>>>>>>>>download file:{} success<<<<<<<<<<", res.getName());
+ } catch (IOException e) {
+ log.error(">>>>>>>>>>download error:{}<<<<<<<<<<", e.getMessage(), e);
+ throw new BusinessException("下载异常");
+ }
+ }, commonExecutor);
+// try {
+// channelClient.processFile(res);
+// } catch (IOException e) {
+// log.error(">>>>>>>>>>download error:{}<<<<<<<<<<", e.getMessage(), e);
+// throw new BusinessException("下载异常");
+// }
return res;
}
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 0a65245..556eb77 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -45,5 +45,5 @@ baogutang:
album-base-url: http://117.72.78.133:5173/album?id=%d
artist-base-url: http://117.72.78.133:5173/artists?id=%d
download-base-url: https://api.sooooooooooooooooootheby.top/Netease_url/Song_V1?level=jymaster&type=json&ids=%d
- download-path: /baogutang-music/download/music
+ download-path: /Users/nikooh/Desktop/Download