/**
*
*/
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();
}
}
MusicUtils.java
最新推荐文章于 2024-05-15 00:54:44 发布