MusicUtils.java

/**
 * 
 */
package com.renwen;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 	音乐破解工具类
 */
public class MusicUtils {

	//下载根目录
	public static String rootSavePath = "";

	//下载的歌曲存储
	private Map<Integer, List<Music>> musicLists = new HashMap<Integer, List<Music>>();
	public Map<Integer, List<Music>> getMusicLists() {
		return musicLists;
	}

	JProgressBar progressBar;
	
	static {
		File[] files = File.listRoots();
		int disk;
		for (disk = files.length - 1; disk >= 0; disk--) {
			//最后一个盘没有空间
			if (files[disk].getTotalSpace() > 0) {
				break;
			}
		}
		rootSavePath = files[disk].getPath() + "\\MineMusic";
		File file = new File(rootSavePath);
		if (!file.exists()) {
			//文件路径不存在,创建
			file.mkdirs();
		}
	}

	private int rn = 10;
	public int getRn() {
		return rn;
	}
	public void setRn(int rn) {
		this.rn = rn;
	}

	private int total = 0;
	public int getTotal() {
		return total;
	}

	private int pages = 0;
	public int getPages() {
		return pages;
	}

//	private MusicMainFrame musicMainFrame;
//	public void setMusicMainFrame(MusicMainFrame musicMainFrame) {
//		this.musicMainFrame = musicMainFrame;
//	}
	/**
	 * 	通过对应的网址,获取所有的请求头信息
	 * @param url 解析的网址
	 * @return 所有的cookies信息
	 */
	public Map<String, Object> getCookies(String url) {
		Map<String, Object> cookies=new HashMap<>();
		try {
			//打开链接
			HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
			//获取所有的请求头信息
			Map<String, List<String>> map = con.getHeaderFields();
			//迭代器遍历
			Set<String> set = map.keySet();
			Iterator<String> it = set.iterator();
			String token = "";
			while (it.hasNext()) {
				Object obj = it.next();
				if (obj != null) {
					String key = obj.toString();
					if (key != null) {
						if (key.equals("Set-Cookie")) {
							token=map.get(key).toString();
							break;
						}
					}
				}
			}
			//分离出token
			String  cookie_token=token.split(";")[0].substring(1);
			String value=token.substring(token.indexOf("=")+1,token.indexOf(";"));
			//保存请求信息
			cookies.put("csrf", value);
			cookies.put("Cookie",cookie_token);
			cookies.put("Referer",url);
		} catch (Exception e) {
			System.out.println("cookies获取失败:"+e.getMessage());
			return null;
		}
		return cookies;
	}

	/**
	 * 	根据搜索的网址,获取搜索的所有数据
	 * @param url 搜索歌曲的地址
	 * @param cookies 对应的token请求头
	 * @return 所有的歌曲的json字符串
	 */
	public String getMusicData(String url, Map<String, Object> cookies) {
		StringBuffer sb = new StringBuffer();
		try {
			URL urls = new URL(url);
			HttpURLConnection con = (HttpURLConnection) urls.openConnection();
			Set<String> set = cookies.keySet();
			Iterator<String> it = set.iterator();
			while (it.hasNext()) {
				String key = it.next();
				//将所有的请求头信息设置到request请求中
				con.setRequestProperty(key, cookies.get(key).toString());
			}
			BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
			String str = "";
			while ((str = br.readLine()) != null) {
				sb.append(str);
			}
		} catch (Exception e) {
			System.out.println("网址解析失败:"+e.getMessage());
			return null;
		}
		return sb.toString();
	}

	/**
	 * 	解析得到的音乐json数据
	 * @param musicData 音乐json数据
	 * @return
	 */
	public List<Music> getMusicInfos(String musicData) {
		try {
			return JSONArray.parseArray(
					JSONObject.parseObject(musicData).getJSONObject("data")
					.getString("list"), Music.class);
		} catch (Exception e) {
			System.out.println("歌曲信息获取失败:"+e.getMessage());
			return null;
		}
	}

	/**
	 * 	解析搜索的歌手总共歌曲数量
	 * @param musicData 音乐json数据
	 * @return
	 */
	public int getMusicTotal(String musicData) {
		try {
			return JSONObject.parseObject(musicData).getJSONObject("data")
					.getIntValue("total");
		} catch (Exception e) {
			System.out.println("歌曲数量获取失败:"+e.getMessage());
			return 0;
		}
	}

	/**
	 * 	根据数据条数获取对应的页数
	 * @param total 总数据条数
	 * @param rn 每页显示多少条数据
	 */
	public int getPages(int total, int rn) {
		int pages = total / rn;
		return pages % rn == 0?pages:++pages;
	}


	/**
	 * 	根据歌曲id获取下载链接
	 * @param rid 歌曲id
	 * @return 下载链接
	 */
	public String getDownloadUrl(String rid) {
		String musicUrl = "http://www.kuwo.cn/url?format=mp3&rid="+rid+"&response=url"
				+ "&type=convert_url3&br=320kmp3&from=web&t=1591344082519&httpsStatus=1"
				+ "&reqId=bf0b6671-a702-11ea-bc80-694d299522e5";
		StringBuffer sb = new StringBuffer();
		String downloadUrl = "";
		try {
			URL urls = new URL(musicUrl);
			HttpURLConnection con = (HttpURLConnection) urls.openConnection();
			BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
			String str = "";
			while ((str = br.readLine()) != null) {
				sb.append(str);
			}
			//获取下载地址
			downloadUrl = JSONObject.parseObject(sb.toString()).getString("url");
		} catch (IOException e) {
			System.out.println("url获取失败:"+e.getMessage());
			return null;
		}
		return downloadUrl;
	}

	/**
	 * 	根据传入的路径、音乐信息和下载地址,下载音乐到本地
	 * @param savePath 保存路径,如果不输入,则默认存储到最后一个磁盘的KwMusic文件夹中。
	 * @param music 音乐信息
	 * @param downloadUrl 下载地址
	 */
	public void downloadMusic(String savePath, Music music, String downloadUrl) {
		//		File file = new File(rootSavePath);
		//		if (!file.exists()) {
		//			//文件路径不存在,sss创建
		//			file.mkdirs();
		//		}
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;
		try {
			String downUrl = rootSavePath + "\\" + music.getArtist() + "-" + music.getName() + ".mp3";
			if (!(new File(downUrl)).exists()) {
				//获取下载地址的输入流
				URL urls = new URL(downloadUrl);
				HttpURLConnection con = (HttpURLConnection) urls.openConnection();
				con.setRequestProperty("Accept-Encoding", "identity");
				//System.out.println("文件总大小:"+con.getContentLengthLong());
				bis = new BufferedInputStream(con.getInputStream());
				//创建输出流下载文件
				bos = new BufferedOutputStream(new FileOutputStream(downUrl));
				byte[] b = new byte[1024*2];
				int len = 0;
				//long downLen = 0;
				//long totalLen = con.getContentLengthLong();//文件总大小
				//获取到点我下载的组件内容
				//JLabel label_down = musicMainFrame.getLabel_down();
				//label_down.setText("下载中0%");
				while ((len = bis.read(b)) != -1) {
					//downLen += len;
					//currentProgress = (int) (downLen / (double)totalLen * 100);
					//label_down.setText("下载中"+currentProgress+"%");
					bos.write(b, 0, len);
				}
				//currentProgress = 100;
				//label_down.setText("已下载");
				bos.flush();
				//System.out.println("下载成功,存储地址是====>" + downUrl);
			} else {
				//System.out.println("【歌曲已存在】,存储地址是====>" + downUrl);
			}

		} catch (Exception e) {
			System.out.println("下载失败:" + e.getMessage());
		} finally {
			try {
				if (bos != null) {
					bos.close();
				}
				if (bis != null) {
					bis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	DecimalFormat df = new DecimalFormat("##.##");
	
	/**
	 * 	根据传入的路径、音乐信息和下载地址,下载音乐到本地
	 * @param savePath 保存路径,如果不输入,则默认存储到最后一个磁盘的KwMusic文件夹中。
	 * @param music 音乐信息
	 * @param downloadUrl 下载地址
	 */
	public boolean downloadMusic(Music music, String downloadUrl, JLabel label) {
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;
		String downUrl = "";
		File file = null;
		try {
			downUrl = rootSavePath + "\\" + music.getArtist() + "-" + music.getName() + ".mp3";
			file = new File(downUrl);
			//文件不存在或者重新下载都可以进入下载过程
			if (!file.exists() || label.getText().equals("正在链接资源...")) {
				//获取下载地址的输入流
				URL urls = new URL(downloadUrl);
				HttpURLConnection con = (HttpURLConnection) urls.openConnection();
				con.setRequestProperty("Accept-Encoding", "identity");
				bis = new BufferedInputStream(con.getInputStream());
				//创建输出流下载文件
				bos = new BufferedOutputStream(new FileOutputStream(downUrl));
				byte[] b = new byte[1024*2];
				int len = 0;
				long downLen = 0;
				long totalLen = con.getContentLengthLong();//文件总大小
				//计算总大小
				String fileLen = df.format(((double)totalLen / 1024 / 1024)) + "M";
				int percent = 0;
				while ((len = bis.read(b)) != -1) {
					downLen += len;
					percent = (int) (downLen / (double)totalLen * 100);
					label.setText(percent+"%"+ " / " + df.format(((double)downLen / 1024 / 1024))+"M / "+fileLen);
					bos.write(b, 0, len);
				}
				bos.flush();
			}
			return true;
		} catch (Exception e) {
			System.out.println("下载失败:" + e.getMessage());
			if (file.exists()) {
				file.delete();//下载失败,删除源文件
			}
			return false;
		} finally {
			try {
				if (bos != null) {
					bos.close();
				}
				if (bis != null) {
					bis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				if (file.exists()) {
					file.delete();//下载失败,删除源文件
				}
				return false;
			}
		}
	}

	/**
	 * 	获取控制台输入的信息
	 */
	@SuppressWarnings("resource")
	public String getInputStr(String tipInfo) {
		Scanner s = new Scanner(System.in);
		String str = "";
		try {
			System.out.print(tipInfo);
			str = URLEncoder.encode(s.next(), "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 	显示搜索的结果
	 * @param name 搜索的关键字
	 */
	public String showInfos(String name, int pn) {
		//处理分页
		if (pn < 1) {
			pn = 1;
		} else if (pages > 0 && pn > pages) {
			pn = pages;
		}
		//拼接网址
		String url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key="+name+"&pn="+pn+"&rn="+rn+"&httpsStatus=1&reqId=5756cf81-a70a-11ea-8d43-770cffbd05bf";
		String urlSrc = "http://www.kuwo.cn/search/list?key="+name;

		//从集合中寻找这一页的数据
		List<Music> musics = musicLists.get(pn);
		if (musics == null) {
			//这一页的数据没有,获取最新歌曲数据
			String musicData = getMusicData(url, getCookies(urlSrc));
			//如果是第一次搜索,获取总页数的一些信息
			if (musicLists.size() == 0) {
				total = getMusicTotal(musicData);//总数据数
				pages = getPages(total, rn);//总页数
				//				try {
				//					//拼接文件存储路径
				//					rootSavePath += "\\" + URLDecoder.decode(name, "UTF-8");
				//				} catch (UnsupportedEncodingException e) {
				//					e.printStackTrace();
				//				}
			}
			//解析得到这一页的音乐
			musics = getMusicInfos(musicData);
			//将这一页的记录存储到集合中
			musicLists.put(pn, musics);
		}
		System.out.println("搜索结果(显示第一页的数据):");
		System.out.println("========================");
		System.out.println("总共搜索到:"+total+"条 / 共 " + pages + "页 / 当前页【"+pn+"】页 / 每页显示【"+rn+"】条");
		for (int i = 0; i < musics.size(); i++) {
			System.out.println((i+1)+"."+musics.get(i));
		}
		System.out.println("========================");
		String s = "请输入下载模式(p上一页 n下一页 esc 退出):";
		s += "\n输入对应编号下载对应歌曲;";
		s += "\n输入0直接下载本页全部歌曲;";
		s += "\n输入1,2,3...直接下载对应的歌曲编号;";
		s += "\n输入p,1,2,3...直接下载对应的页面歌曲;";
		s += "\n输入m-n直接下载m-n页的所有歌曲。";
		s += "\n请输入您的下载模式:";
		String select = getInputStr(s);
		try {
			return URLDecoder.decode(select, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			System.out.println("解码错误:"+e.getMessage());
			return null;
		}
	}	


	/**
	 * 	显示搜索的结果
	 * @param name 搜索的关键字
	 */
	public List<Music> getMusicData(String name, int pn) {
		//处理分页
		if (pn < 1) {
			pn = 1;
		} else if (pages > 0 && pn > pages) {
			pn = pages;
		}
		//拼接网址
		String url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key="+name+"&pn="+pn+"&rn="+rn+"&httpsStatus=1&reqId=5756cf81-a70a-11ea-8d43-770cffbd05bf";
		String urlSrc = "http://www.kuwo.cn/search/list?key="+name;

		//从集合中寻找这一页的数据
		List<Music> musics = musicLists.get(pn);
		if (musics == null) {
			//这一页的数据没有,获取最新歌曲数据
			String musicData = getMusicData(url, getCookies(urlSrc));
			//如果是第一次搜索,获取总页数的一些信息
			if (musicLists.size() == 0) {
				total = getMusicTotal(musicData);//总数据数
				pages = getPages(total, rn);//总页数
			}
			//解析得到这一页的音乐
			musics = getMusicInfos(musicData);
			//将这一页的记录存储到集合中
			musicLists.put(pn, musics);
		}
		return musics;
	}	

	/**
	 * 	下载某一页的所有歌曲
	 */
	public void download(List<Music> musics) {
		for (Music music : musics) {
			downloadMusic(null, music, getDownloadUrl(music.getRid()));
		}
	}

	/**
	 * 	下载第一页
	 */
	public void downloadIndex(int pn) {
		download(musicLists.get(pn));
	}

	/**
	 * 	下载哪几页
	 * @param start
	 * @param end
	 */
	public void downloadRange(String name, int start, int end) {
		for (int i = start; i <= end; i++) {
			//获取这一页时候已经查询过
			List<Music> musics = musicLists.get(i);
			if (musics == null) {
				//没有查询过,重新查询
				String url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key="+name+"&pn="+i+"&rn="+rn+"&httpsStatus=1&reqId=5756cf81-a70a-11ea-8d43-770cffbd05bf";
				String urlSrc = "http://www.kuwo.cn/search/list?key="+name;
				//获取歌曲数据
				String musicData = getMusicData(url, getCookies(urlSrc));
				//解析
				musics = getMusicInfos(musicData);
			}
			download(musics);
		}
	}

	/**
	 * 	下载范围页歌曲
	 */
	public void downloadRange(String name, String s) {
		try {
			String[] ss = s.split("\\-");
			int start = Integer.parseInt(ss[0]);
			int end = Integer.parseInt(ss[1]);
			for (int i = start; i <= end; i++) {
				//获取这一页是否已经查询,没有查询先查询
				List<Music> musics = musicLists.get(i);
				if (musics == null) {
					String url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key="+name+"&pn="+i+"&rn="+rn+"&httpsStatus=1&reqId=5756cf81-a70a-11ea-8d43-770cffbd05bf";
					String urlSrc = "http://www.kuwo.cn/search/list?key="+name;
					//获取歌曲数据
					String musicData = getMusicData(url, getCookies(urlSrc));
					//解析
					musics = getMusicInfos(musicData);
				}
				download(musics);
			}
		} catch (Exception e) {
			System.out.println("页码输入错误,无法下载!"+e.getMessage());
		}
	}

	/**
	 * 	下载指定哪几页
	 */
	public void downloadWhichPages(String name, String s) {
		try {
			String[] ss = s.split("\\,");
			//第一个p要去掉
			for (int i = 1; i < ss.length; i++) {
				int pn = Integer.parseInt(ss[i]);
				List<Music> musics = musicLists.get(pn);
				if (musics == null) {
					String url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key="+name+"&pn="+pn+"&rn="+rn+"&httpsStatus=1&reqId=5756cf81-a70a-11ea-8d43-770cffbd05bf";
					String urlSrc = "http://www.kuwo.cn/search/list?key="+name;
					//获取歌曲数据
					String musicData = getMusicData(url, getCookies(urlSrc));
					//解析
					musics = getMusicInfos(musicData);
				}
				download(musics);
			}
		} catch (Exception e) {
			System.out.println("页码输入错误,无法下载!"+e.getMessage());
		}
	}

	/**
	 * 	根据传入的编号,下载单曲
	 * @param pn 当前页
	 * @param numStr 歌曲编号
	 */
	public void downloadSingle(int pn, int num) {
		//下载单曲
		Music music = musicLists.get(pn).get(num-1);
		downloadMusic(null, music, getDownloadUrl(music.getRid()));
	}
	
	/**
	 * 	根据传入的编号,下载单曲
	 * @param pn 当前页
	 * @param numStr 歌曲编号
	 */
	public boolean downloadSingle(int pn, int num, JLabel label) {
		//下载单曲
		Music music = musicLists.get(pn).get(num-1);
		return downloadMusic(music, getDownloadUrl(music.getRid()), label);
	}

	/**
	 * 下载哪几个编号的歌曲
	 * @param pn 当前页
	 * @param s 编号 使用英文,隔开。比如 1,2,3
	 */
	public void dowloadWhichMusic(int pn, String s) {
		String[] ss = s.split("\\,");
		for (int i = 0; i < ss.length; i++) {
			downloadSingle(pn, Integer.parseInt(ss[i]));
		}
	}

	public void start() {
		//创建工具
		MusicUtils musicUtils = new MusicUtils();
		//每页显示20条
		musicUtils.setRn(20);

		//歌手名称
		String name = musicUtils.getInputStr("请输入要搜索的歌手或者歌曲名称:");
		int pn = 1;
		//无限循环
		while (true) {
			//显示歌曲信息。弹出那个选择菜单。
			String s = musicUtils.showInfos(name, pn);
			//获取要下载的歌曲信息
			if (s.equals("0")) {
				//下载第一页的所有歌曲
				musicUtils.downloadIndex(pn);
			} else if (s.equals("esc")) {
				//结束程序
				System.out.println("程序结束!");
				System.exit(0);
			} else if (s.equals("p")) {
				//上一页
				pn--;
			} else if (s.equals("n")) {
				//下一页
				pn++;
			} else {
				if (s.indexOf("p") != -1) {
					//有p证明按照页下载
					musicUtils.downloadWhichPages(name, s);
				} else if (s.indexOf("-") != -1) {
					//有-证明按照页面范围下载
					musicUtils.downloadRange(name, s);
				} else if (s.indexOf(",") != -1) {
					//有,证明下载第一页的固定歌曲
					musicUtils.dowloadWhichMusic(pn, s);
				} else {
					//只有一种,直接按照歌曲编号下载
					//下载对应编号的所有歌曲
					musicUtils.downloadSingle(pn, Integer.parseInt(s));
				}
			}
		}
	}

	private volatile int currentProgress = 0;

	class DownFrame extends JFrame{
		private static final long serialVersionUID = -5884697174019216575L;

		public DownFrame() {
			setSize(200, 100);
			setLocationRelativeTo(null);
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			// 创建一个进度条
			progressBar = new JProgressBar();

			// 设置进度的 最小值 和 最大值
			progressBar.setMinimum(0);
			progressBar.setMaximum(100);

			// 设置当前进度值
			progressBar.setValue(currentProgress);

			// 绘制百分比文本(进度条中间显示的百分数)
			progressBar.setStringPainted(true);

			// 添加进度改变通知
			progressBar.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent e) {
					System.out.println("当前进度值: " + progressBar.getValue() + "; " +
							"进度百分比: " + progressBar.getPercentComplete());
				}
			});
			add(progressBar);
			setVisible(true);
		}
	}

	class DownProgressBar extends Thread {

		@Override
		public void run() {
			while (currentProgress < 100) {
				try {
					System.out.println(currentProgress);
					progressBar.setValue(currentProgress);
					Thread.sleep(1000);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	public static void main(String[] args) {
		MusicUtils mu = new MusicUtils();
		mu.new DownFrame();
		mu.new DownProgressBar().start();
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值