add kugou search

This commit is contained in:
N1KO 2024-12-16 21:22:09 +08:00
parent 167e16fb0b
commit 853064813f
7 changed files with 434 additions and 6 deletions

View File

@ -0,0 +1,238 @@
package top.baogutang.music.client;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import top.baogutang.music.annos.ChannelInfo;
import top.baogutang.music.dao.entity.MusicDownloadRecordEntity;
import top.baogutang.music.dao.entity.MusicRecordEntity;
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.enums.SearchTypeEnum;
import top.baogutang.music.exceptions.BusinessException;
import top.baogutang.music.properties.KuGouMusicProperties;
import top.baogutang.music.service.IMusicDownloadRecordService;
import top.baogutang.music.service.IMusicRecordService;
import top.baogutang.music.utils.OkHttpUtil;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
*
* @description:
*
* @author: N1KO
* @date: 2024/12/16 : 18:24
*/
@Slf4j
@Component
@ChannelInfo(ChannelEnum.KU_GOU_MUSIC)
public class KuGouMusicClient implements ChannelClient<MusicSearchReq, MusicSearchRes> {
@Resource
private KuGouMusicProperties kuGouMusicProperties;
@Resource
private IMusicRecordService musicRecordService;
@Resource
private IMusicDownloadRecordService musicDownloadRecordService;
@Override
public MusicSearchRes search(MusicSearchReq req) {
Integer pageNo = (req.getOffset() / req.getLimit()) + 1;
SearchTypeEnum searchType = SearchTypeEnum.parseKuGouMusicCode(req.getType());
if (searchType == null) {
throw new BusinessException("不支持的搜索类型");
}
String searchUrl = String.format(kuGouMusicProperties.getQueryBaseUrl(), req.getKeywords(), pageNo, req.getLimit(), searchType.getKuGouMusicCode());
switch (searchType) {
case SONG:
return searchSong(searchUrl, pageNo, req.getLimit());
case ALBUM:
return searchAlbum(searchUrl, pageNo, req.getLimit());
case PLAYLIST:
return searchPlayList(searchUrl, pageNo, req.getLimit());
case SINGER:
return searchSinger(searchUrl, pageNo, req.getLimit());
default:
throw new BusinessException("不支持的搜索类型");
}
}
private MusicSearchRes searchSinger(String searchUrl, Integer pageNo, Integer pageSize) {
KuGouMusicSearchCommonRes<KuGouMusicSearchCommonRes.PageData<KuGouMusicSearchCommonRes.Author>> kuGouMusicSearchCommonRes = OkHttpUtil.get(searchUrl, null, null, new TypeReference<>() {
});
if (Objects.isNull(kuGouMusicSearchCommonRes) || Objects.isNull(kuGouMusicSearchCommonRes.getData()) || kuGouMusicSearchCommonRes.getData().getTotal() <= 0) {
return null;
}
MusicSearchRes musicSearchRes = new MusicSearchRes();
musicSearchRes.setCode(200);
MusicSearchRes.SearchResult searchResult = new MusicSearchRes.SearchResult();
searchResult.setHasMore(pageNo * pageSize < kuGouMusicSearchCommonRes.getData().getTotal());
List<MusicSearchRes.Artist> artistList = kuGouMusicSearchCommonRes.getData().getLists().stream()
.map(a -> {
MusicSearchRes.Artist artist = new MusicSearchRes.Artist();
artist.setId(a.getAuthorId());
artist.setName(a.getAuthorName());
artist.setPicUrl(a.getAvatar());
return artist;
})
.collect(Collectors.toList());
searchResult.setArtists(artistList);
musicSearchRes.setResult(searchResult);
return musicSearchRes;
}
private MusicSearchRes searchPlayList(String searchUrl, Integer pageNo, Integer pageSize) {
KuGouMusicSearchCommonRes<KuGouMusicSearchCommonRes.PageData<KuGouMusicSearchCommonRes.Playlist>> kuGouMusicSearchCommonRes = OkHttpUtil.get(searchUrl, null, null, new TypeReference<>() {
});
if (Objects.isNull(kuGouMusicSearchCommonRes) || Objects.isNull(kuGouMusicSearchCommonRes.getData()) || kuGouMusicSearchCommonRes.getData().getTotal() <= 0) {
return null;
}
MusicSearchRes musicSearchRes = new MusicSearchRes();
musicSearchRes.setCode(200);
MusicSearchRes.SearchResult searchResult = new MusicSearchRes.SearchResult();
searchResult.setHasMore(pageNo * pageSize < kuGouMusicSearchCommonRes.getData().getTotal());
List<MusicSearchRes.PlayList> playLists = kuGouMusicSearchCommonRes.getData().getLists().stream()
.map(p -> {
MusicSearchRes.PlayList playList = new MusicSearchRes.PlayList();
playList.setId(p.getGid());
playList.setName(p.getSpecialname());
playList.setCoverImgUrl(p.getImg());
return playList;
})
.collect(Collectors.toList());
searchResult.setPlaylists(playLists);
musicSearchRes.setResult(searchResult);
return musicSearchRes;
}
private MusicSearchRes searchAlbum(String searchUrl, Integer pageNo, Integer pageSize) {
KuGouMusicSearchCommonRes<KuGouMusicSearchCommonRes.PageData<KuGouMusicSearchCommonRes.Album>> kuGouMusicSearchCommonRes = OkHttpUtil.get(searchUrl, null, null, new TypeReference<>() {
});
if (Objects.isNull(kuGouMusicSearchCommonRes) || Objects.isNull(kuGouMusicSearchCommonRes.getData()) || kuGouMusicSearchCommonRes.getData().getTotal() <= 0) {
return null;
}
MusicSearchRes musicSearchRes = new MusicSearchRes();
musicSearchRes.setCode(200);
MusicSearchRes.SearchResult searchResult = new MusicSearchRes.SearchResult();
searchResult.setHasMore(pageNo * pageSize < kuGouMusicSearchCommonRes.getData().getTotal());
List<MusicSearchRes.Album> albumList = kuGouMusicSearchCommonRes.getData().getLists().stream()
.map(a -> {
MusicSearchRes.Album album = new MusicSearchRes.Album();
album.setId(a.getAlbumId());
album.setName(a.getAlbumName());
album.setBlurPicUrl(a.getImg());
return album;
})
.collect(Collectors.toList());
searchResult.setAlbums(albumList);
musicSearchRes.setResult(searchResult);
return musicSearchRes;
}
private MusicSearchRes searchSong(String searchUrl, Integer pageNo, Integer pageSize) {
KuGouMusicSearchCommonRes<KuGouMusicSearchCommonRes.PageData<KuGouMusicSearchCommonRes.Song>> kuGouMusicSearchCommonRes = OkHttpUtil.get(searchUrl, null, null, new TypeReference<>() {
});
if (Objects.isNull(kuGouMusicSearchCommonRes) || Objects.isNull(kuGouMusicSearchCommonRes.getData()) || kuGouMusicSearchCommonRes.getData().getTotal() <= 0) {
return null;
}
MusicSearchRes musicSearchRes = new MusicSearchRes();
musicSearchRes.setCode(200);
MusicSearchRes.SearchResult searchResult = new MusicSearchRes.SearchResult();
searchResult.setHasMore(pageNo * pageSize < kuGouMusicSearchCommonRes.getData().getTotal());
List<MusicSearchRes.Song> songList = kuGouMusicSearchCommonRes.getData().getLists().stream()
.map(s -> {
MusicSearchRes.Song song = new MusicSearchRes.Song();
song.setId(s.getFileHash());
song.setName(s.getSongName());
List<MusicSearchRes.Artist> artistList = s.getSingers().stream()
.map(singer -> {
MusicSearchRes.Artist artist = new MusicSearchRes.Artist();
artist.setId(singer.getId());
artist.setName(singer.getName());
return artist;
})
.collect(Collectors.toList());
song.setArtists(artistList);
MusicSearchRes.Album album = new MusicSearchRes.Album();
album.setId(s.getAlbumId());
album.setName(s.getAlbumName());
song.setAlbum(album);
return song;
})
.collect(Collectors.toList());
searchResult.setSongs(songList);
musicSearchRes.setResult(searchResult);
return musicSearchRes;
}
@Override
public MusicPlaylistRes playlist(String id) {
return null;
}
@Override
public MusicDetailRes detail(String id) {
return null;
}
@Override
public MusicAlbumRes album(String id) {
return null;
}
@Override
public MusicArtistRes artist(String id) {
return null;
}
@Override
public MusicDownloadRes download(String id) {
return null;
}
@Override
public void saveMusic(MusicDownloadRes res) {
}
@Override
public void processFile(MusicDownloadRes res) throws IOException {
}
@Override
public MusicRecordEntity queryByPlatform(String id) {
return null;
}
@Override
public String getDownloadBasePath() {
return "";
}
@Override
public void saveDownloadRecord(Long userId, String batchNo, String musicId) {
}
@Override
public List<MusicDownloadRecordEntity> queryDownloadRecord(String batchNo) {
return List.of();
}
@Override
public List<MusicRecordEntity> queryMusicByPlatformIdList(List<String> platformIdList) {
return List.of();
}
}

View File

@ -0,0 +1,122 @@
package top.baogutang.music.domain.res.search;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
*
* @description:
*
* @author: N1KO
* @date: 2024/12/16 : 18:33
*/
@Data
public class KuGouMusicSearchCommonRes<T extends Serializable> implements Serializable {
private static final long serialVersionUID = -3851575429347578104L;
private Integer status;
@JsonProperty("error_code")
private Integer errorCode;
@JsonProperty("error_msg")
private String errorMsg;
private T data;
@Data
public static class PageData<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 1606319973451240398L;
private Integer page;
@JsonProperty("pagesize")
private Integer pageSize;
private Integer total;
private List<T> lists;
}
@Data
public static class Song implements Serializable {
private static final long serialVersionUID = 564075626053778101L;
@JsonProperty("FileHash")
private String fileHash;
@JsonProperty("SongName")
private String songName;
@JsonProperty("AlbumID")
private String albumId;
@JsonProperty("AlbumName")
private String albumName;
@JsonProperty("Singers")
private List<Singer> singers;
}
@Data
public static class Author implements Serializable {
private static final long serialVersionUID = -5222912661645405260L;
@JsonProperty("AuthorId")
private String authorId;
@JsonProperty("AuthorName")
private String authorName;
@JsonProperty("Avatar")
private String avatar;
}
@Data
public static class Playlist implements Serializable {
private static final long serialVersionUID = -1508270737885641882L;
@JsonProperty("gid")
private String gid;
@JsonProperty("specialname")
private String specialname;
@JsonProperty("img")
private String img;
}
@Data
public static class Album implements Serializable {
private static final long serialVersionUID = 8644829843407879987L;
@JsonProperty("albumid")
private String albumId;
@JsonProperty("albumname")
private String albumName;
@JsonProperty("img")
private String img;
}
@Data
public static class Singer implements Serializable {
private static final long serialVersionUID = -5222912661645405260L;
private String id;
private String name;
}
}

View File

@ -18,7 +18,7 @@ public enum ChannelEnum {
KU_GOU_MUSIC(2, "酷狗音乐"),
KU_WO_MUSIC(3, "酷我音乐"),
// KU_WO_MUSIC(3, "酷我音乐"),
// CUS_MUSIC(4, "自定义音乐"),

View File

@ -27,10 +27,10 @@ public enum SearchTypeEnum {
* 1018:综合,
* 2000:声音(搜索声音返回字段格式会不一样)
*/
SONG(1, 0, "单曲"),
ALBUM(10, 8, "专辑"),
SINGER(100, 9, "歌手"),
PLAYLIST(1000, 2, "歌单"),
SONG(1, 0, "song", "单曲"),
ALBUM(10, 8, "album", "专辑"),
SINGER(100, 9, "author", "歌手"),
PLAYLIST(1000, 2, "special", "歌单"),
;
@ -39,11 +39,14 @@ public enum SearchTypeEnum {
private final Integer qqMusicCode;
private final String kuGouMusicCode;
private final String desc;
SearchTypeEnum(Integer code, Integer qqMusicCode, String desc) {
SearchTypeEnum(Integer code, Integer qqMusicCode, String kuGouMusicCode, String desc) {
this.code = code;
this.qqMusicCode = qqMusicCode;
this.kuGouMusicCode = kuGouMusicCode;
this.desc = desc;
}
@ -53,4 +56,11 @@ public enum SearchTypeEnum {
.findFirst()
.orElse(null);
}
public static SearchTypeEnum parseKuGouMusicCode(Integer type) {
return Arrays.stream(SearchTypeEnum.values())
.filter(searchType -> Objects.equals(searchType.getCode(), type))
.findFirst()
.orElse(null);
}
}

View File

@ -0,0 +1,30 @@
package top.baogutang.music.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
*
* @description:
*
* @author: N1KO
* @date: 2024/12/16 : 18:22
*/
@Data
@Component
@ConfigurationProperties(prefix = "baogutang.kugou-music")
public class KuGouMusicProperties {
private String queryBaseUrl;
private String playlistBaseUrl;
private String albumBaseUrl;
private String artistBaseUrl;
private String downloadBaseUrl;
private String downloadPath;
}

View File

@ -0,0 +1,20 @@
package top.baogutang.music.service;
import org.springframework.stereotype.Service;
import top.baogutang.music.enums.ChannelEnum;
/**
*
* @description:
*
* @author: N1KO
* @date: 2024/12/16 : 18:25
*/
@Service
public class IKuGouMusicService extends AbstractMusicService {
@Override
public ChannelEnum getChannelEnum() {
return ChannelEnum.KU_GOU_MUSIC;
}
}

View File

@ -59,5 +59,13 @@ baogutang:
download-path: /downloads/music
# download-path: /Users/nikooh/Desktop/downloads/music
kugou-music:
query-base-url: http://117.72.78.133:5177/search?keywords=%s&page=%d&pagesize=%d&type=%s
playlist-base-url: http://117.72.78.133:5175/songlist?id=%s
album-base-url: http://117.72.78.133:5175/album/songs?albummid=%s
download-base-url: http://117.72.78.133:5176/song?url=https://y.qq.com/n/ryqq/songDetail/%s
download-path: /downloads/music
# download-path: /Users/nikooh/Desktop/downloads/music