音乐·Mirai QQ机器人

  • 前言

鉴于市面上绝大部分的点歌api都寄了,博主便自己摸索出了自己的点歌api,仅支持免费歌曲和会员试听,仅供学习参考,勿用于非法途径。

感兴趣的可以看博主前面的教程来搭建,有问题可以评论区问问,没有及时答复的话可以加QQ群

  • 成果展示

  • 流程展示

  • 具体实现

  • 接收用户输入

        用户发送点歌关键词后直接获取后面的部分作为歌名

if (content.startsWith("点歌")) {
							String songName = content.substring(2);
							CompletableFuture<String> songFuture = CompletableFuture.supplyAsync(() -> {
								try {
									return song(songName);
								} catch (UnsupportedEncodingException e) {
									throw new RuntimeException(e);
								}
							});
							songFuture.thenAcceptAsync(result -> {
								if (!result.equals("false")) {
									try {
										String[] list = result.split(";");
										Image image = event.getSubject().uploadImage(ExternalResource.create(urlTopng(list[2])));
										ExternalResource audioResource = ExternalResource.create(new File("C:\\Users\\z\\Desktop\\BOT素材\\song.amr"));
										Audio audio = event.getSubject().uploadAudio(audioResource);
										MessageChainBuilder messages = new MessageChainBuilder()
												.append("[歌集]:" + list[0])
												.append("\n[歌手]:" + list[3])
												.append("\n[歌名]:" + list[1])
												.append(image);
										event.getSubject().sendMessage(messages.build());
										event.getSubject().sendMessage(audio);
									} catch (IOException e) {
										throw new RuntimeException(e);
									}
								} else {
									event.getSubject().sendMessage("点歌失败,请检查api");
								}
							});
						}
  • 模拟搜索请求

        里面的{歌名}为歌名请求的替换部分

<p>
http://msearchcdn.kugou.com/api/v3/search/song?showtype=14&highlight=em&pagesize=1&tag_aggr=1&tagtype=全部&plat=0&sver=5&correct=1&api_ver=1&version=9108&page=1&area_code=1&tag=1&with_res_tag=1&keyword={歌名}
</p>
  • 截取返回的Hash和ablum_id

        返回的界面数据较多,仔细甄别

        里面的hashalbum_id是我们需要的内容

{"relative":{"priortype":1,"singer":null},"black":{"type":0,"isblock":1},"correct":null,"status":1,"errcode":0,"data":{"timestamp":1698558996,"tab":"","forcecorrection":0,"correctiontype":0,"total":480,"istag":0,"allowerr":0,"info":[{"hash":"37a8f50a9ec3b267c3cc6bec633d9c4a","sqfilesize":26170434,"sourceid":0,"pay_type_sq":3,"bitrate":128,"ownercount":7123111,"pkg_price_sq":1,"songname":"青花瓷<\/em>","album_name":"我很忙","songname_original":"青花瓷<\/em>","Accompany":1,"sqhash":"57395d60345f46e2effe581176af9a0c","fail_process":4,"pay_type":3,"rp_type":"audio","album_id":"979856","othername_original":"","mvhash":"dc602a8579c0ac1e2895543ffc2c7daf","extname":"mp3","group":[{"hash":"e62d487fac0c438a66fd7a52f8451f9d","sqfilesize":26171657,"sourceid":0,"pay_type_sq":3,"bitrate":128,"ownercount":3033,"pkg_price_sq":1,"songname":"青花瓷<\/em>","album_name":"爱在飞翔","songname_original":"青花瓷<\/em>","Accompany":1,"sqhash":"a8adf335fd6186ce0f15e2933ed329e6","fail_process":4,"pay_type":3,"rp_type":"audio","album_id":"1740508","othername_original":"","mvhash":"dc602a8579c0ac1e2895543ffc2c7daf","extname":"mp3","price_320":200,"320hash":"3f5e758e20ee654cf6256d5cc021cdc3","topic":"","othername":"","isnew":0,"fold_type":0,"old_cpy":0,"srctype":1,"singername":"周杰伦","album_audio_id":39609139,"duration":239,"320filesize":9582955,"pkg_price_320":1,"audio_id":339796,"feetype":0,"price":200,"filename":"周杰伦 - 青花瓷<\/em>","source":"","price_sq":200,"fail_process_320":4,"trans_param":{"cpy_level":1,"classmap":{"attr0":234885128},"cpy_grade":5,"qualitymap":{"attr0":4177972},"pay_block_tpl":1,"cid":7220571,"language":"国语","hash_multitrack":"832EE9460484B6C3F2700B9DBF0B8092","cpy_attr0":15488,"ipmap":{"attr0":4096},"hash_offset":{"clip_hash":"B716D939AFBBDB9886B6AC8EBE36DE72","start_byte":0,"end_ms":60000,"end_byte":960119,"file_type":0,"start_ms":0,"offset_hash":"D54255838FBB3D3F4133F0197C3FCB92"},"musicpack_advance":1,"display":32,"display_rate":1},"pkg_price":1,"pay_type_320":3,"topic_url":"","m4afilesize":0,"rp_publish":1,"privilege":10,"filesize":3833299,"isoriginal":1,"320privilege":10,"sqprivilege":10,"fail_process_sq":4},{"hash":"852e517e7235746805ae9734c5089617","sqfilesize":26171657,"sourceid":0,"pay_type_sq":3,"bitrate":128,"ownercount":1547,"pkg_price_sq":1,"songname":"青花瓷<\/em>","album_name":"K情歌10","songname_original":"青花瓷<\/em>","Accompany":1,"sqhash":"8bb9b6f1f89d5eb1421c06e10ad841b5","fail_process":4,"pay_type":3,"rp_type":"audio","album_id":"8438612","othername_original":"","mvhash":"dc602a8579c0ac1e2895543ffc2c7daf","extname":"mp3","price_320":200,"320hash":"005342d7a33d759a1ba33c155e75302b","topic":"","othername":"","isnew":0,"fold_type":0,"old_cpy":0,"srctype":1,"singername":"周杰伦","album_audio_id":106788312,"duration":239,"320filesize":9582957,"pkg_price_320":1,"audio_id":339796,"feetype":0,"price":200,"filename":"周杰伦 - 青花瓷<\/em>","source":"","price_sq":200,"fail_process_320":4,"trans_param":{"cpy_level":1,"classmap":{"attr0":234885128},"cpy_grade":5,"qualitymap":{"attr0":4177972},"pay_block_tpl":1,"cid":4982133,"language":"国语","hash_multitrack":"57E8F2D45F8E9C41F36B856227E4C6E1","cpy_attr0":15488,"ipmap":{"attr0":4096},"hash_offset":{"clip_hash":"E03B818C74EF8673EFD050E33D6FF04D","start_byte":0,"end_ms":117259,"end_byte":1876287,"file_type":0,"start_ms":57259,"offset_hash":"E43479DE1B1C73835A3268D5A48A3CD7"},"musicpack_advance":1,"display":32,"display_rate":1},"pkg_price":1,"pay_type_320":3,"topic_url":"","m4afilesize":0,"rp_publish":1,"privilege":10,"filesize":3833301,"isoriginal":1,"320privilege":10,"sqprivilege":10,"fail_process_sq":4},{"hash":"d89efc4f198c5e5bac6ed455ee4abd0c","sqfilesize":25836663,"sourceid":0,"pay_type_sq":0,"bitrate":128,"ownercount":252268,"pkg_price_sq":0,"songname":"青花瓷<\/em>","album_name":"中国好声音第四季荣耀之战原唱曲目","songname_original":"青花瓷<\/em>","Accompany":1,"sqhash":"61814a0d374dcbc533ac7c5898b89892","fail_process":0,"pay_type":0,"rp_type":"audio","album_id":"555030","othername_original":"","mvhash":"dc602a8579c0ac1e2895543ffc2c7daf","extname":"mp3","price_320":0,"320hash":"178848a26c4ae443a5c993cf949c4327","topic":"","othername":"","isnew":0,"fold_type":0,"old_cpy":1,"srctype":1,"singername":"周杰伦","album_audio_id":28107217,"duration":239,"320filesize":9648878,"pkg_price_320":0,"audio_id":339796,"feetype":0,"price":0,"filename":"周杰伦 - 青花瓷<\/em>","source":"","price_sq":0,"fail_process_320":0,"trans_param":{"pay_block_tpl":1,"qualitymap":{"attr0":20955189},"classmap":{"attr0":234885128},"cid":-1,"hash_multitrack":"99DBFA3F9F1A41683B2FF2282F0D319B","cpy_attr0":0,"ipmap":{"attr0":4096},"language":"国语","musicpack_advance":0,"display":32,"display_rate":1},"pkg_price":0,"pay_type_320":0,"topic_url":"","m4afilesize":0,"rp_publish":1,"privilege":0,"filesize":3825382,"isoriginal":1,"320privilege":0,"sqprivilege":0,"fail_process_sq":0}],"price_320":200,"320hash":"d38bff1043fec27b8d40f40da953cb0e","topic":"","othername":"","isnew":0,"fold_type":0,"old_cpy":0,"srctype":1,"singername":"周杰伦","album_audio_id":32218352,"duration":239,"320filesize":9576683,"pkg_price_320":1,"audio_id":339796,"feetype":0,"price":200,"filename":"周杰伦 - 青花瓷<\/em>","source":"","price_sq":200,"fail_process_320":4,"trans_param":{"cpy_level":1,"classmap":{"attr0":234885128},"cpy_grade":5,"qualitymap":{"attr0":1329578037},"pay_block_tpl":1,"cid":2556436,"language":"国语","hash_multitrack":"85568A05EE0200F50547925517FAA5B7","cpy_attr0":15488,"ipmap":{"attr0":4096},"hash_offset":{"clip_hash":"9877793C360F13ED36011712BB613131","start_byte":0,"end_ms":60000,"end_byte":960117,"file_type":0,"start_ms":0,"offset_hash":"1D7E04573B8A2FDF51122C3DC0B4A8FB"},"musicpack_advance":1,"display":32,"display_rate":1},"pkg_price":1,"pay_type_320":3,"topic_url":"","m4afilesize":0,"rp_publish":1,"privilege":10,"filesize":3830789,"isoriginal":1,"320privilege":10,"sqprivilege":10,"fail_process_sq":4}],"aggregation":[],"correctiontip":"","istagresult":0},"error":""}
  • 爬取结果返回界面的数据

里面的hsah和ablum_id再替换下面的{Hash}和{Song_id}

爬取请求结果里面的play_url(为mp3资源文件)

<p>
https://wwwapi.kugou.com/yy/index.php?r=play/getdata&hash={Hash}&dfid=3ex60E2pQb582fRAwB1wYhA1&appid=1014&mid=94c23e6bf948c957d06d24c4dec18b1e&platid=4&album_id={Song_id}&_=1695860308340
</p>

<p>
{"status":1,"err_code":0,"data":{"hash":"37a8f50a9ec3b267c3cc6bec633d9c4a","timelength":239386,"filesize":3830789,"audio_name":"\u5468\u6770\u4f26 - \u9752\u82b1\u74f7","have_album":1,"album_name":"\u6211\u5f88\u5fd9","album_id":"979856","img":"http:\/\/imge.kugou.com\/stdmusic\/20220705\/20220705143006989099.jpg","have_mv":1,"video_id":"592096","author_name":"\u5468\u6770\u4f26","song_name":"\u9752\u82b1\u74f7","lyrics":"\ufeff[id:$00000000]\r\n[ar:\u5468\u6770\u4f26]\r\n[ti:\u9752\u82b1\u74f7]\r\n[by:]\r\n[hash:3d6395061264198afc68c0d70c48074e]\r\n[al:]\r\n[sign:]\r\n[qq:]\r\n[total:239000]\r\n[offset:0]\r\n[00:00.31]\u5468\u6770\u4f26 - \u9752\u82b1\u74f7\r\n[00:00.51]\u4f5c\u8bcd\uff1a\u65b9\u6587\u5c71\r\n[00:00.72]\u4f5c\u66f2\uff1a\u5468\u6770\u4f26\r\n[00:00.87]\u7f16\u66f2\uff1a\u949f\u5174\u6c11\r\n[00:21.80]\u7d20\u80da\u52fe\u52d2\u51fa\u9752\u82b1\u7b14\u950b\u6d53\u8f6c\u6de1\r\n[00:26.13]\u74f6\u8eab\u63cf\u7ed8\u7684\u7261\u4e39\u4e00\u5982\u4f60\u521d\u5986\r\n[00:30.56]\u5189\u5189\u6a80\u9999\u900f\u8fc7\u7a97\u5fc3\u4e8b\u6211\u4e86\u7136\r\n[00:34.99]\u5ba3\u7eb8\u4e0a\u8d70\u7b14\u81f3\u6b64\u6401\u4e00\u534a\r\n[00:39.47]\u91c9\u8272\u6e32\u67d3\u4ed5\u5973\u56fe\u97f5\u5473\u88ab\u79c1\u85cf\r\n[00:43.89]\u800c\u4f60\u5ae3\u7136\u7684\u4e00\u7b11\u5982\u542b\u82de\u5f85\u653e\r\n[00:48.32]\u4f60\u7684\u7f8e\u4e00\u7f15\u98d8\u6563\r\n[00:50.77]\u53bb\u5230\u6211\u53bb\u4e0d\u4e86\u7684\u5730\u65b9\r\n[00:57.23]\u5929\u9752\u8272\u7b49\u70df\u96e8 \u800c\u6211\u5728\u7b49\u4f60\r\n[01:01.66]\u708a\u70df\u8885\u8885\u5347\u8d77 \u9694\u6c5f\u5343\u4e07\u91cc\r\n[01:06.09]\u5728\u74f6\u5e95\u4e66\u6c49\u96b6\u4eff\u524d\u671d\u7684\u98d8\u9038\r\n[01:10.58]\u5c31\u5f53\u6211\u4e3a\u9047\u89c1\u4f60\u4f0f\u7b14\r\n[01:15.02]\u5929\u9752\u8272\u7b49\u70df\u96e8 \u800c\u6211\u5728\u7b49\u4f60\r\n[01:19.44]\u6708\u8272\u88ab\u6253\u635e\u8d77 \u6655\u5f00\u4e86\u7ed3\u5c40\r\n[01:23.86]\u5982\u4f20\u4e16\u7684\u9752\u82b1\u74f7\u81ea\u987e\u81ea\u7f8e\u4e3d\r\n[01:27.78]\u4f60\u773c\u5e26\u7b11\u610f\r\n[01:50.70]\u8272\u767d\u82b1\u9752\u7684\u9526\u9ca4\u8dc3\u7136\u4e8e\u7897\u5e95\r\n[01:55.04]\u4e34\u6479\u5b8b\u4f53\u843d\u6b3e\u65f6\u5374\u60e6\u8bb0\u7740\u4f60\r\n[01:59.47]\u4f60\u9690\u85cf\u5728\u7a91\u70e7\u91cc\u5343\u5e74\u7684\u79d8\u5bc6\r\n[02:03.84]\u6781\u7ec6\u817b\u72b9\u5982\u7ee3\u82b1\u9488\u843d\u5730\r\n[02:08.38]\u5e18\u5916\u82ad\u8549\u60f9\u9aa4\u96e8\u95e8\u73af\u60f9\u94dc\u7eff\r\n[02:12.81]\u800c\u6211\u8def\u8fc7\u90a3\u6c5f\u5357\u5c0f\u9547\u60f9\u4e86\u4f60\r\n[02:17.19]\u5728\u6cfc\u58a8\u5c71\u6c34\u753b\u91cc\r\n[02:19.69]\u4f60\u4ece\u58a8\u8272\u6df1\u5904\u88ab\u9690\u53bb\r\n[02:26.16]\u5929\u9752\u8272\u7b49\u70df\u96e8 \u800c\u6211\u5728\u7b49\u4f60\r\n[02:30.53]\u708a\u70df\u8885\u8885\u5347\u8d77 \u9694\u6c5f\u5343\u4e07\u91cc\r\n[02:34.97]\u5728\u74f6\u5e95\u4e66\u6c49\u96b6\u4eff\u524d\u671d\u7684\u98d8\u9038\r\n[02:39.44]\u5c31\u5f53\u6211\u4e3a\u9047\u89c1\u4f60\u4f0f\u7b14\r\n[02:43.93]\u5929\u9752\u8272\u7b49\u70df\u96e8 \u800c\u6211\u5728\u7b49\u4f60\r\n[02:48.35]\u6708\u8272\u88ab\u6253\u635e\u8d77 \u6655\u5f00\u4e86\u7ed3\u5c40\r\n[02:52.78]\u5982\u4f20\u4e16\u7684\u9752\u82b1\u74f7\u81ea\u987e\u81ea\u7f8e\u4e3d\r\n[02:56.65]\u4f60\u773c\u5e26\u7b11\u610f\r\n[03:01.74]\u5929\u9752\u8272\u7b49\u70df\u96e8 \u800c\u6211\u5728\u7b49\u4f60\r\n[03:06.12]\u708a\u70df\u8885\u8885\u5347\u8d77 \u9694\u6c5f\u5343\u4e07\u91cc\r\n[03:10.60]\u5728\u74f6\u5e95\u4e66\u6c49\u96b6\u4eff\u524d\u671d\u7684\u98d8\u9038\r\n[03:14.98]\u5c31\u5f53\u6211\u4e3a\u9047\u89c1\u4f60\u4f0f\u7b14\r\n[03:19.47]\u5929\u9752\u8272\u7b49\u70df\u96e8 \u800c\u6211\u5728\u7b49\u4f60\r\n[03:23.90]\u6708\u8272\u88ab\u6253\u635e\u8d77 \u6655\u5f00\u4e86\u7ed3\u5c40\r\n[03:28.33]\u5982\u4f20\u4e16\u7684\u9752\u82b1\u74f7\u81ea\u987e\u81ea\u7f8e\u4e3d\r\n[03:32.20]\u4f60\u773c\u5e26\u7b11\u610f\r\n","author_id":"3520","privilege":10,"privilege2":"1010","play_url":"https:\/\/webfs.hw.kugou.com\/202310291411\/06a29756bd59e98d10a19bd2512bd1d1\/v2\/37a8f50a9ec3b267c3cc6bec633d9c4a\/part\/0\/960117\/G286\/M0B\/6E\/45\/clip_vocBAGS4ICKAe_wZADp0BfGWDHU329.mp3","authors":[{"author_id":"3520","author_name":"\u5468\u6770\u4f26","is_publish":"1","sizable_avatar":"http:\/\/singerimg.kugou.com\/uploadpic\/softhead\/{size}\/20230510\/20230510173043311.jpg","e_author_id":"3E0KCC3671E7","avatar":"http:\/\/singerimg.kugou.com\/uploadpic\/softhead\/400\/20230510\/20230510173043311.jpg"}],"is_free_part":1,"bitrate":128,"recommend_album_id":"979856","store_type":"audio","album_audio_id":32218352,"is_publish":1,"e_author_id":"3E0KCC3671E7","audio_id":"339796","has_privilege":true,"play_backup_url":"https:\/\/webfs.tx.kugou.com\/202310291411\/8c63ca81bcb969de535a298d8bf21fce\/v2\/37a8f50a9ec3b267c3cc6bec633d9c4a\/part\/0\/960117\/G286\/M0B\/6E\/45\/clip_vocBAGS4ICKAe_wZADp0BfGWDHU329.mp3","trans_param":{"hash_offset":{"start_byte":0,"end_byte":960117,"start_ms":0,"end_ms":60000,"offset_hash":"1D7E04573B8A2FDF51122C3DC0B4A8FB","file_type":0,"clip_hash":"9877793C360F13ED36011712BB613131"},"musicpack_advance":1,"pay_block_tpl":1,"display":32,"display_rate":1,"cpy_grade":5,"cpy_level":1,"cid":2556436,"cpy_attr0":15488,"classmap":{"attr0":234885128},"hash_multitrack":"85568A05EE0200F50547925517FAA5B7","qualitymap":{"attr0":1329578037},"language":"\u56fd\u8bed","ipmap":{"attr0":4096}},"small_library_song":1,"encode_album_id":"l0286f","encode_album_audio_id":"j6ju8e3","e_video_id":"cov476"}}
</p>
  • 发送,点歌完成

用了异步的方法加快发送歌曲的速度,效果可以

public static String song(String songName) throws UnsupportedEncodingException {
		String apiURL = "https://api.yujn.cn/api/kugou.php?msg=" + URLEncoder.encode(songName.trim(), "UTF-8");
		try {
			URL url = new URL(apiURL);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.setConnectTimeout(CONNECTION_TIMEOUT);
			connection.setReadTimeout(READ_TIMEOUT);

			int responseCode = connection.getResponseCode();
			if (responseCode == HttpURLConnection.HTTP_OK) {
				try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
					StringBuilder response = new StringBuilder();
					String line;
					while ((line = reader.readLine()) != null) {
						response.append(line);
					}

					Gson gson = new Gson();
					JsonObject jsonObject = gson.fromJson(response.toString(), JsonObject.class);

					if (jsonObject != null) {
						int code = jsonObject.get("code").getAsInt();
						if (code == 200) {
							JsonArray dataArray = jsonObject.get("data").getAsJsonArray();
							if (dataArray != null && dataArray.size() > 0) {
								JsonObject dataNode = dataArray.get(0).getAsJsonObject();
								String audioName = dataNode.get("audio_name").getAsString();
								String albumName = dataNode.get("album_name").getAsString();
								String imgURL = dataNode.get("img").getAsString();
								String authorName = dataNode.get("author_name").getAsString();
								String playURL = dataNode.get("play_url").getAsString();

								CompletableFuture.runAsync(() -> saveMusicFile(playURL), executor);

								return audioName + ";" + albumName + ";" + imgURL + ";" + authorName;
							} else {
								System.out.println("数据节点为空");
							}
						} else {
							System.out.println("请求失败,错误代码:" + code);
						}
					} else {
						System.out.println("解析 JSON 失败");
					}
				}
			} else {
				System.out.println("HTTP请求失败,错误代码:" + responseCode);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "false";
	}

	private static void saveMusicFile(String playURL) {
		try {
			URL fileUrl = new URL(playURL);
			HttpURLConnection fileConnection = (HttpURLConnection) fileUrl.openConnection();
			fileConnection.setRequestMethod("GET");
			fileConnection.setConnectTimeout(CONNECTION_TIMEOUT);
			fileConnection.setReadTimeout(READ_TIMEOUT);

			int fileResponseCode = fileConnection.getResponseCode();
			if (fileResponseCode == HttpURLConnection.HTTP_OK) {
				try (InputStream fileInputStream = fileConnection.getInputStream();
				     FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\z\\Desktop\\BOT素材\\song.amr")) {
					byte[] buffer = new byte[BUFFER_SIZE];
					int bytesRead;
					while ((bytesRead = fileInputStream.read(buffer)) != -1) {
						fileOutputStream.write(buffer, 0, bytesRead);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值