SpringBoot 整合酷狗获取下载音乐(需要自己账户)

程序员必备宝典icon-default.png?t=O83Ahttps://tmxkj.top/#/

  1. 在此声明,本内容仅供个人学习、研究或娱乐之用,严禁任何形式的商业用途。若您发现本内容被用于商业目的,请立即删除,及时与小编联系,我们将删除原代码。

  2. 我们尊重并保护所有原创作品的知识产权。

  3. 为了营造一个健康、积极的网络环境,我们鼓励用户遵守相关法律法规,尊重他人劳动成果,不进行任何形式的侵权行为。同时,我们也将持续优化内容审核机制,加强对侵权行为的打击力度,保障广大用户的合法权益。

  4. 如有任何疑问或建议,欢迎随时联系小编。我们将竭诚为您提供帮助,共同维护一个和谐、有序的网络空间。

        <!-- fastjson格式 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>

     <!--实体类参数校验-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

   <!-- gson转实体类配置-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.11.0</version>
        </dependency>

(1)歌曲查找请求返回示例:

{
	"code": 200,
	"msg": "成功!",
	"data": [
		{
			"id": "64563865",
			"fileName": "小贱、星弟 - 不想做朋友",
			"albumName": "不想做朋友",
			"singerName": "小贱、星弟",
			"albumId": "975285",
			"duration": 236,
			"singers": [
				{
					"name": "小贱",
					"ip_id": 0,
					"id": 3227
				},
				{
					"name": "星弟",
					"ip_id": 0,
					"id": 3161
				}
			],
			"mvHash": "D42F35525BDA84550E01177191D17B0D",
			"type": "audio",
			"image": "http://imge.kugou.com/stdmusic/{size}/20210112/20210112235153293725.jpg",
			"suffix": "",
			"transParam": {
				"unionCover": "http://imge.kugou.com/stdmusic/{size}/20210112/20210112235153293725.jpg",
				"language": "国语"
			},
			"timestamp": 1726210030,
			"isHaveMv": true,
			"playDuration": "3:56",
			"playUrl": null,
			"hash": null,
			"lyrics": null,
			"emixSongId": "12ftsp9e"
		},
		{
			"id": "313917307",
			"fileName": "钟小明 - 不想做朋友",
			"albumName": "翻唱",
			"singerName": "钟小明",
			"albumId": "44694996",
			"duration": 236,
			"singers": [
				{
					"name": "钟小明",
					"ip_id": 0,
					"id": 5281518
				}
			],
			"mvHash": "CFEF1B0B2A1E2C2309442113CF506994",
			"type": "audio",
			"image": "http://imge.kugou.com/stdmusic/{size}/20210516/20210516100230949417.jpg",
			"suffix": "",
			"transParam": {
				"unionCover": "http://imge.kugou.com/stdmusic/{size}/20210516/20210516100230949417.jpg",
				"language": "国语"
			},
			"timestamp": 1726210030,
			"isHaveMv": true,
			"playDuration": "3:56",
			"playUrl": null,
			"hash": null,
			"lyrics": null,
			"emixSongId": "56wc574a"
		}]

 (2)歌曲下载请求返回示例:

{
	"code": 200,
	"msg": "获取成功",
	"data": {
		"id": "64563865",
		"fileName": "小贱、星弟 - 不想做朋友",
		"albumName": "不想做朋友",
		"singerName": "小贱、星弟",
		"albumId": "975285",
		"duration": 236,
		"singers": [
			{
				"name": "小贱",
				"ip_id": 0,
				"id": 3227
			},
			{
				"name": "星弟",
				"ip_id": 0,
				"id": 3161
			}
		],
		"mvHash": "D42F35525BDA84550E01177191D17B0D",
		"type": "audio",
		"image": "http://imge.kugou.com/stdmusic/20210112/20210112235153293725.jpg",
		"suffix": "",
		"transParam": {
			"unionCover": "http://imge.kugou.com/stdmusic/{size}/20210112/20210112235153293725.jpg",
			"language": "国语"
		},
		"timestamp": 1726210030,
		"isHaveMv": true,
		"playDuration": "3:56",
		"playUrl": "https://webfs.kugou.com/202409131515/81c41fb53bb0654a303111f155be5fdb/v3/2168b82c91dbe9b89e19a6a0c6f97bd0/yp/full/ap1014_us635334580_mii0w1iw8z2ai2iphcu80ooo2ki81120_pi406_mx64563865_s2318522131.mp3",
		"hash": "2168B82C91DBE9B89E19A6A0C6F97BD0",
		"lyrics": "\ufeff[id:$00000000]\r\n[ar:星弟/小贱]\r\n[ti:不想做朋友]\r\n[by:]\r\n[hash:2168b82c91dbe9b89e19a6a0c6f97bd0]\r\n[al:不想做朋友]\r\n[sign:]\r\n[qq:]\r\n[total:0]\r\n[offset:0]\r\n[00:00.00]小贱、星弟 - 不想做朋友\r\n[00:00.26]作词:小贱\r\n[00:01.19]作曲:星弟\r\n[00:14.14]编曲:星弟\r\n[00:17.27]星:\r\n[00:18.31]那句我还爱你差点说出口\r\n[00:24.96]却被你一声问候堵在了心头\r\n[00:32.25]小:\r\n[00:32.59]真的沦落成朋友也能笑着接受\r\n[00:41.09]只是见面时心会比较痛\r\n[00:50.05]其实我不洒脱只是装英雄\r\n[00:56.46]那么爱你怎可能一滴泪没有\r\n[01:04.11]星:\r\n[01:04.37]我说我会再牵手有很多人等候\r\n[01:12.66]合:\r\n[01:13.06]可谁能给我 那样的感动\r\n[01:19.86]星:\r\n[01:20.26]不想和你做朋友\r\n[01:24.04]小:\r\n[01:25.10]夜深的时候\r\n[01:28.22]合:\r\n[01:28.92]还希望有你温暖我胸口\r\n[01:35.42]小:\r\n[01:36.09]不想和你做朋友\r\n[01:39.97]星:\r\n[01:41.06]我会再等候\r\n[01:44.39]合:\r\n[01:44.89]也许等到你 忘了我以后\r\n[02:08.47]星:\r\n[02:09.52]其实我不洒脱只是装英雄\r\n[02:16.12]那么爱你怎可能一滴泪没有\r\n[02:23.08]小:\r\n[02:23.69]我说我会再牵手有很多人等候\r\n[02:31.95]合:\r\n[02:32.36]可谁能给我那样的感动\r\n[02:39.57]小:\r\n[02:39.77]不想和你做朋友\r\n[02:43.27]星:\r\n[02:44.46]夜深的时候\r\n[02:47.67]合:\r\n[02:48.30]还希望有你温暖我胸口\r\n[02:54.86]星:\r\n[02:55.43]不想和你做朋友\r\n[02:59.69]小:\r\n[03:00.28]我会再等候\r\n[03:03.86]合:\r\n[03:04.30]也许等到你 忘了我以后\r\n[03:10.82]小:\r\n[03:11.64]不想和你做朋友夜深的时候\r\n[03:19.77]还希望有你温暖我胸口\r\n[03:26.32]星:\r\n[03:27.03]不想和你做朋友\r\n[03:30.22]小:\r\n[03:30.55]不做朋友\r\n[03:32.12]星:\r\n[03:32.26]我会再等候\r\n[03:34.21]小:\r\n[03:34.37]我会再等候\r\n[03:35.98]星:\r\n[03:36.13]也许等到你 忘了我以后\r\n",
		"emixSongId": "12ftsp9e"
	}
}

(3) 上请求示例代码

  public static void main(String[] args) throws IOException {
        long timestamp = System.currentTimeMillis() / 1000;
        KuGouHand hand = new KuGouHand();
        List<KuGou> list =audioIdList("凯小晴",timestamp,hand);
        for (KuGou kuGous : list) {
            fetchUrl(kuGous.getEMixSongId(),timestamp,kuGous,hand);
        }
    }


    /**
     * 获取MD5验签
     */
    public static String setMd5Sign(long timestamp, String audioId,KuGouHand hand) {
        List<String> signatureList = new ArrayList<>();
        signatureList.add("NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt");
        signatureList.add("appid="+hand.getAppid());
        signatureList.add("clienttime=" + timestamp);
        signatureList.add("clientver=20000");
        signatureList.add("dfid="+hand.getDfid());
        signatureList.add("encode_album_audio_id=" + audioId);
        signatureList.add("mid="+hand.getMid());
        signatureList.add("platid="+hand.getPlatid());
        signatureList.add("srcappid="+hand.getSrcappid());
        signatureList.add("token="+hand.getToken());
        signatureList.add("userid="+hand.getUserid());
        signatureList.add("uuid="+hand.getUuid());
        signatureList.add("NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt");

        StringBuilder stringBuilder = new StringBuilder();
        for (String s : signatureList) {
            stringBuilder.append(s);
        }

        String sign = getMD5(stringBuilder.toString());
        return sign;
    }

    /**
     * MD5算法转换
     */
    private static String getMD5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                hexString.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3));
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *  获取搜索验签
     */
    public static String md5SignSearch(String timestamp, String musicName,KuGouHand hand) {
        String[] signatureList = {
                "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt",
                "appid="+hand.getAppid(),
                "bitrate="+hand.getBitrate(),
                "callback="+hand.getCallback(),
                "clienttime=" + timestamp,
                "clientver=1000",
                "dfid="+hand.getDfid(),
                "filter="+hand.getFilter(),
                "inputtype="+hand.getInputtype(),
                "iscorrection="+hand.getIscorrection(),
                "isfuzzy="+hand.getIsfuzzy(),
                "keyword=" + musicName,
                "mid="+hand.getMid(),
                "page="+hand.getPage(),
                "pagesize="+hand.getPagesize(),
                "platform="+hand.getPlatform(),
                "privilege_filter="+hand.getPrivilegefilter(),
                "srcappid="+hand.getSrcappid(),
                "token="+hand.getToken(),
                "userid="+hand.getUserid(),
                "uuid="+hand.getUuid(),
                "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt"
        };

        StringBuilder stringBuilder = new StringBuilder();
        for (String s : signatureList) {
            stringBuilder.append(s);
        }

        String string = stringBuilder.toString();
        return getMD5(string);
    }

    /**
     * 获取下载地址
     */
    public static void fetchUrl(String audioId, long timestamp, KuGou kuGou, KuGouHand hand) throws IOException {
        OkHttpClient client = new OkHttpClient();
        LinkedHashMap<String, String> param = new LinkedHashMap<>();
        param.put("srcappid",hand.getSrcappid() );
        param.put("clientver", "20000");
        param.put("clienttime", String.valueOf(timestamp));
        param.put("mid", hand.getMid());
        param.put("uuid", hand.getUuid());
        param.put("dfid", hand.getDfid());
        param.put("appid", hand.getAppid());
        param.put("platid", hand.getPlatid());
        param.put("encode_album_audio_id", audioId);
        param.put("token", hand.getToken());
        param.put("userid", hand.getUserid());
        param.put("signature", setMd5Sign(timestamp, audioId,hand));
        String url = "https://wwwapi.kugou.com/play/songinfo" + GetParams(param);

        Request request = new Request.Builder()
                .url(url)
                // .headers(headers)
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            String responseBody = response.body().string();
            Gson gson = new Gson();
            Type type = new TypeToken<Map<String, Object>>() {}.getType();
            Type type2 = new TypeToken<Map<String, Object>>() {}.getType();
            Map<String, Object> map = gson.fromJson(responseBody, type);
            Map<String, Object> map2 = gson.fromJson(JSON.toJSONString(map.get("data")), type2);
            System.out.println(map2.get("play_url"));
            kuGou.setPlayUrl(String.valueOf(map2.get("play_url")));
            kuGou.setHash(String.valueOf(map2.get("hash")));
            kuGou.setLyrics(String.valueOf(map2.get("lyrics")));
            String img = String.valueOf(map2.get("img"));
            if (img!=null){
                kuGou.setImage(img);
            }
        }
    }

    /**
     * 获取音乐列表
     */
    public static List<KuGou> audioIdList(String musicName, long timestamp, KuGouHand hand) throws IOException {
        List<KuGou> list=new ArrayList<>();
        String sign = md5SignSearch(String.valueOf(timestamp), musicName,hand);
        LinkedHashMap<String, String> param = new LinkedHashMap<>();
        param.put("callback", hand.getCallback());
        param.put("srcappid", hand.getSrcappid());
        param.put("clientver", "1000");
        param.put("clienttime", String.valueOf(timestamp));
        param.put("mid", hand.getMid());
        param.put("uuid", hand.getUuid());
        param.put("dfid",hand.getDfid());
        param.put("keyword", musicName);
        param.put("page", hand.getPage());
        param.put("pagesize", hand.getPagesize());
        param.put("bitrate", hand.getBitrate());
        param.put("isfuzzy", hand.getIsfuzzy());
        param.put("inputtype", hand.getInputtype());
        param.put("platform", hand.getPlatform());
        param.put("userid", hand.getUserid());
        param.put("iscorrection", hand.getIscorrection());
        param.put("privilege_filter", hand.getPrivilegefilter());
        param.put("filter", hand.getFilter());
        param.put("token", hand.getToken());
        param.put("appid", hand.getAppid());
        param.put("signature", sign);


        OkHttpClient client = new OkHttpClient();
        String url = "https://complexsearch.kugou.com/v2/search/song" + GetParams(param);

        Request request = new Request.Builder()
                .url(url)
               // .headers(headers)
                .build();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        if (response.isSuccessful()) {
            int startIndex = responseBody.indexOf("callback123(");
            if (startIndex != -1) {
                startIndex += "callback123(".length();
                int endIndex = responseBody.lastIndexOf(")");
                if (endIndex != -1) {
                    String result = responseBody.substring(startIndex, endIndex);
                    Gson gson = new Gson();
                    Type type = new TypeToken<Map<String, Object>>() {}.getType();
                    Type type2 = new TypeToken<Map<String, Object>>() {}.getType();
                    Map<String, Object> map = gson.fromJson(result, type);
                    Map<String, Object> map2 = gson.fromJson(JSON.toJSONString(map.get("data")), type2);
                    List<KuGou> list2 =  JSON.parseArray(JSON.toJSONString(map2.get("lists")), KuGou.class);
                    return  list2;
                }
            }
            return list;
        } else {
            throw new IOException("No matching results found");
        }
    }

(4)Dto 实体类KuGouHand 

import lombok.Data;

@Data
public class KuGouHand {
    //固定 返回名称
    private String callback="callback123";
    //固定 密匙id
    private String srcappid = "2919";
    //固定 appid
    private String appid = "1014";
    //固定
    private String platid = "4";
    //分页
    private String page = "1";
    //分页返回数量
    private String pagesize="30";
    //固定
    private String bitrate ="0";
    //固定
    private String isfuzzy="0";
    //固定
    private String inputtype="0";
    //固定
    private String platform="WebFilter";
    //固定
    private String iscorrection="1";
    //固定
    private String privilegefilter= "0";
    //固定
    private String filter= "10";
    // 验签方法
    private String signature;
    // token
    private String token = "";
    // 用户userId
    private String userid = "";
    // mid
    private String mid = "";
    // uuid
    private String uuid = "";
    // dfif
    private String dfid = "";

}

import com.google.gson.annotations.SerializedName;
import lombok.Data;

import javax.validation.constraints.NotNull;
import java.util.HashMap;

@Data
public class KuGou {
    @SerializedName("ID")
    @NotNull(message = "ID不能为空!")
    private String id;
    @SerializedName("FileName")
    private String fileName;
    @SerializedName("EMixSongID")
    @NotNull(message = "歌曲ID不能为空!")
    private String eMixSongId;
    @SerializedName("AlbumName")
    private String albumName;
    @SerializedName("SingerName")
    private String singerName;
    @SerializedName("AlbumID")
    private String albumId;
    @SerializedName("Duration")
    private Integer duration;
    @SerializedName("Singers")
    private Object singers;
    @SerializedName("MvHash")
    private String mvHash;
    @SerializedName("Type")
    private String type;
    @SerializedName("Image")
    private String image;
    @SerializedName("Suffix")
    private String suffix;
    @SerializedName("trans_param")
    private HashMap<String,Object> transParam;
    //时间戳
    @NotNull(message = "原时间戳不能为空!")
    private long timestamp;
    //是否有Mv视频
    private Boolean isHaveMv = false;
    //播放时长
    private String playDuration;
    //播放地址
    private String playUrl;
    //播放hash
    private String hash;
    //歌词
    private String lyrics;

}

 (5)工具类

 /**
     * 参数装换GET
     */
    public static String GetParams(Map<String, String> params) {
        StringBuilder result = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (result.length() > 0) {
                result.append("&");
            }
            result.append(entry.getKey()).append("=").append(entry.getValue());
        }
        return "?"+result.toString();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值