当前位置: 首页 > news >正文

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";//固定 密匙idprivate String srcappid = "2919";//固定 appidprivate 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;// tokenprivate String token = "";// 用户userIdprivate String userid = "";// midprivate String mid = "";// uuidprivate String uuid = "";// dfifprivate 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;//播放hashprivate 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();}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于鸿蒙API10的RTSP播放器(四:沉浸式播放窗口)
  • 微软 Azure AI 服务免费试用及申请:语音识别、文本转语音、基于视觉、语言处理、文档分析等10大场景
  • EP12 分类列表元素点击跳转
  • 医学数据分析实训 项目一 医学数据采集
  • 深入解读Docker核心原理:Namespace资源隔离机制详解
  • SPDK 部署NVMe over TCP
  • golang学习笔记19——golang做服务发现与注册的深度剖析
  • PHP在现代Web开发中的高效应用与最佳实践
  • 【C++】模拟实现string类
  • LabVIEW重构其他语言开发的旧系统
  • 个人hic分析流程搭建4—compartment模块分析
  • 切线空间:unity中shader切线空间,切线矩阵,TBN矩阵 ,法线贴图深度剖析
  • 基于人工智能的自动驾驶系统项目教学指南
  • 三星ZFlip5/ZFlip4/W7024刷安卓14国行OneUI6.1系统-高级设置-韩/欧/港版
  • StreamReader 和 StreamWriter提供自动处理字符编码的功能
  • php的引用
  • Android框架之Volley
  • Android系统模拟器绘制实现概述
  • Apache Spark Streaming 使用实例
  • Docker下部署自己的LNMP工作环境
  • echarts花样作死的坑
  • extract-text-webpack-plugin用法
  • gf框架之分页模块(五) - 自定义分页
  • JavaScript异步流程控制的前世今生
  • Java编程基础24——递归练习
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Object.assign方法不能实现深复制
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • unity如何实现一个固定宽度的orthagraphic相机
  • Web标准制定过程
  • 关于extract.autodesk.io的一些说明
  • 面试总结JavaScript篇
  • 如何在 Tornado 中实现 Middleware
  • 提醒我喝水chrome插件开发指南
  • 怎么将电脑中的声音录制成WAV格式
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • (10)STL算法之搜索(二) 二分查找
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (办公)springboot配置aop处理请求.
  • (二)延时任务篇——通过redis的key监听,实现延迟任务实战
  • (五)c52学习之旅-静态数码管
  • (转) RFS+AutoItLibrary测试web对话框
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .describe() python_Python-Win32com-Excel
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .Net IOC框架入门之一 Unity
  • .NET 反射的使用
  • /dev/sda2 is mounted; will not make a filesystem here!