之前下载了一些mp3歌曲,但是有一些歌曲的音质比较差,想重新下载一些音质好一点的音乐。
通过搜索,发现百度有一些音质比较好的音乐提供下载。打算从百度音乐那里下载下来。
但是发现,要下载的歌曲数量太多了,要一首一首地点击下载太麻烦了。
于是用java写了个批量升级音乐的程序,一键下载。
现在要下载百度音乐320k以上音质的歌曲要会员才可以,不过也有相关的方法可以下载。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.tag.id3.AbstractID3v2Tag;
import org.jaudiotagger.tag.id3.ID3v24Frames;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class Test {
/**
* 获取mp3文件的相关信息 包括ID3V2Tag标签等信息
* @param filePath
* @return
*/
public Map getMusic(String filePath){
Map map=null;
try {
String musicArtist=null;
Integer bitrate=null;
File file=new File(filePath);
MP3File file1=(MP3File) AudioFileIO.read(file);
if(file1.getID3v2Tag()!=null){
AbstractID3v2Tag v2Tag=file1.getID3v2Tag();
musicArtist=v2Tag.getFirst(ID3v24Frames.FRAME_ID_ARTIST);
System.out.println(v2Tag.getFirst(ID3v24Frames.FRAME_ID_ARTIST));
}else if(file1.getID3v1Tag()!=null){
}
bitrate=(int) file1.getAudioHeader().getBitRateAsNumber();
System.out.println(bitrate);
String songName=file.getName().replace(".mp3", "");
String searchName=songName.replace("-", "");
if(musicArtist!=null){
musicArtist=new String(musicArtist.getBytes("8859_1"),"GB2312");
searchName=searchName+musicArtist;
}
map=new HashMap();
map.put("bitrate", bitrate);
map.put("songName", songName);
map.put("searchName", searchName);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return map;
}
/**
* 获取要更新的mp3文件地址
* @param filePath
* @return
*/
public List<String> getAllMusic(String filePath){
List<String> list=null;
try {
File file=new File(filePath);
list=new ArrayList<String>();
if(!file.isDirectory()){
list.add(file.getAbsolutePath());
}else if(file.isDirectory()){
String[] fileList=file.list();
for(int i=0;i<fileList.length;i++){
File file1=new File(filePath+"/"+fileList[i]);
if(!file1.isDirectory()){
list.add(file1.getAbsolutePath());
}else if(file1.isDirectory()){
getAllMusic(filePath+"/"+fileList[i]);
}
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return list;
}
/**
* 根据mp3名字查找mp3歌曲
* @param songName
* @return
*/
public String getMusicId(String songName){
String songId=null;
try {
songName=URLEncoder.encode(songName, "utf-8");
System.out.println(songName);
String strUrl="http://music.baidu.com/search?key="+songName;
Document doc=Jsoup.connect(strUrl).get();
Elements elements=doc.select("span");
for(int i=0;i<elements.size();i++){
if(elements.get(i).attr("title").equals("无损资源")){
System.out.println(elements.get(i+1).attr("data-musicicon"));
JSONObject json=new JSONObject().fromObject(elements.get(i+1).attr("data-musicicon"));
songId=json.get("id").toString();
System.out.println(songId);
break;
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return songId;
}
/**
* 获取mp3的下载链接
* @param musicId
* @return
*/
public String getMusicLink(String musicId){
String songLink=null;
try {
StringBuilder strbuilder=new StringBuilder();
int b;
String url="http://ting.baidu.com/data/music/links?songIds="+musicId+"&rate=320";
InputStream a=new URL(url).openStream();
BufferedReader br=new BufferedReader(new InputStreamReader(a,Charset.forName("UTF-8")));
while((b=br.read())!=-1){
strbuilder.append((char)b);
}
String jsonText=strbuilder.toString();
JSONObject json=new JSONObject().fromObject(jsonText);
String str=json.get("data").toString();
JSONObject json1=new JSONObject().fromObject(str);
String str1=json1.get("songList").toString().replace("[", "").replace("]", "");
songLink=(String) new JSONObject().fromObject(str1).get("songLink");
br.close();
a.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return songLink;
}
/**
* 下载mp3
* @param musicLink
* @param path
* @param fileName
*/
public void downloadMusic(String musicLink,String path,String fileName){
try {
String downUrl=musicLink;
HttpClient httpClient = null;
/**
* 用java自带的http方法下载
*/
// URL url=new URL(downUrl);
// HttpURLConnection conn=(HttpURLConnection) url.openConnection();
// conn.setConnectTimeout(5000);
// InputStream in=conn.getInputStream();
// OutputStream out=new FileOutputStream("D:/eclipse-SDK-4.2.1-win32/workspace/Test/downloadLib/"+"a"+".mp3");
// byte[] b=new byte[1024];
// int len=0;
// while((len=in.read(b))!=-1){
// out.write(b,0,len);
// }
// out.flush();
// in.close();
// out.close();
/**
* 使用httpClient下载
*/
httpClient=new DefaultHttpClient();
HttpGet httpGet=new HttpGet(downUrl);
HttpResponse httpResponse=httpClient.execute(httpGet);
StatusLine statusLine=httpResponse.getStatusLine();
if(statusLine.getStatusCode()==200){
File file=new File(path+"/"+fileName+"1"+".mp3");
FileOutputStream out=new FileOutputStream(file);
InputStream in=(InputStream) httpResponse.getEntity().getContent();
byte[] b=new byte[1024];
int len=0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
in.close();
out.flush();
out.close();
}
}catch (IllegalArgumentException e1) {
// TODO: handle exception
e1.printStackTrace();
System.out.println("找不到该歌曲的资源");
System.out.println("歌曲文件名为"+fileName);
try {
FileWriter fileWriter=new FileWriter(path+"/"+"找不到资源的歌曲.txt",true);
fileWriter.write("找不到资源的歌曲: \r\n");
fileWriter.write(fileName+".mp3"+" \r\n");
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void main(String[] args) {
Integer bitrate=null;
String searchName=null;
String songName=null;
try {
System.out.println("请输入要更新的音乐文件地址:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String filePath=br.readLine();
System.out.println("请输入音乐文件保存的地址:");
br=new BufferedReader(new InputStreamReader(System.in));
String downloadPath=br.readLine();
Test t=new Test();
Map map;
List<String> list=t.getAllMusic(filePath);
for(int i=0;i<list.size();i++){
map=t.getMusic(list.get(i));
bitrate=(Integer) map.get("bitrate");
searchName=(String) map.get("searchName");
songName=(String) map.get("songName");
System.out.println(map.get("songName"));
if(bitrate<320){
String musicId=t.getMusicId(searchName);
String musicLink=t.getMusicLink(musicId);
t.downloadMusic(musicLink, downloadPath, songName);
}
}
System.out.println(t.getAllMusic(filePath));
br.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
本人是新手,写的程序肯定不是很完善。例如在获取mp3的标签,获取出来的string字符,经过编码转换,有些字符还会出现乱码。
顺便提醒一下大家,这个程序是抓取百度的页面去获得mp3的下载链接等信息的,假如百度的页面 有相关的修改,有可能会影响到使用的效果。
假如大家发现程序有什么需要改进的地方,请各位高手多多指教一下。
觉得java版本用起来没有那么方便,要配置环境什么的。所以打算再写个python版本出来。
转载的时候,请大家注明出处。
开发过程中参考过的教程:
http://www.jthink.net/jaudiotagger/examples_id3.jsp
http://my.oschina.net/gtd/blog/58172
http://blog.csdn.net/toni001/article/details/6724785
http://blog.csdn.net/longlonglong25/article/details/11179903
http://www.fightingquaker.com/myid3/
http://www.360doc.com/content/07/0828/08/11020_699438.shtml
http://www.sauronsoftware.it/projects/jave/manual.php
http://yhz61010.iteye.com/blog/1885400
http://blog.csdn.net/iloster/article/details/8694014
http://blog.csdn.net/zz198808/article/details/9264255 python
http://www.blogjava.net/xcp/archive/2008/10/31/json2.html
http://blog.csdn.net/zhuyangxing/article/details/9344459
http://bbs.csdn.net/topics/390639493?page=1
http://www.myexception.cn/internet/1276415.html
http://blog.csdn.net/mhmyqn/article/details/8205874
http://www.cnblogs.com/ValiancyHe/p/3450432.html
http://blog.csdn.net/smile725775/article/details/8248202
http://blog.goyiyo.com/archives/911?utm_source=rss
http://blog.csdn.net/zhang_red/article/details/8434260
http://qiaolevip.iteye.com/blog/1685893
http://www.oschina.net/code/snippet_1021353_26864
http://www.ibm.com/developerworks/cn/java/j-lo-jsouphtml/index.html?ca
http://hi.baidu.com/vhook/item/e1bb539abbfe85df7b7f01da
http://blog.csdn.net/zyz19900613/article/details/8569644
http://zhidao.baidu.com/link?url=5-xyKjac_oeYPJt2Ysf6wdylz1MmwcfZ0kiKrkskAbN40LdpexwKlqWShJEV0q0OnyFo1VPl6uhEjCCzYpOT0q
http://bbs.csdn.net/topics/350246971
http://www.cnblogs.com/yezhenhan/archive/2012/09/10/2678690.html
http://blog.csdn.net/smartcat86/article/details/4085739/
http://blog.csdn.net/liangoo7/article/details/7882773
http://blog.csdn.net/liuhenghui5201/article/details/8276278
http://blog.csdn.net/frank520/article/details/6865001