下载百度音乐无损品质音乐


使用百度音乐时,可以添加收藏,收藏后的音乐列表会保存在http://yinyueyun.baidu.com中,并且提供下载链接。用java简单写了个下载自己收藏音乐的程序,过程中发现对于VIP的无损音乐,下载链接已经给出来了,只是在前台做了限制,这个,这个。。。。(Bug已经报给百度音乐,这里的代码只为方便自己和代码分享)。

本来想用用户名和密码登陆百度账号,可是在登陆时需要传递一个参数callback,这个参数不是服务器发送过来的,怀疑是根据什么参数在本地计算出来的,看不太懂js,这个功能就没实现。

使用步骤如下:

  • 代码jar包使用maven管理,需要去apache网站下载maven,然后在项目根路径mvn install
  • 浏览器登陆百度账号,查看浏览器中的cookie,取出名称为BDUSS的cookie的值,把它复制到com.yeetrack.yinyueyun包下的HttpTool.java中的cookieValue中。
  • 执行MusicDownload.java中的main方法,即可。

下载下来的音乐,保存在项目根路径下的music文件夹,默认下载音质最好的。
全部代码地址:http://www.oschina.net/code/snippet_147181_25883
下面是主函数的代码:

    List<String> idList = new ArrayList<String>();

    CloseableHttpClient httpClient = HttpTool.getHttpClient();

    HttpGet get = new HttpGet("http://yinyueyun.baidu.com/data/cloud/collection?type=song&start=0&size=2000&_="+System.currentTimeMillis());

    CloseableHttpResponse response = httpClient.execute(get);

    String result = EntityUtils.toString(response.getEntity(), "utf-8");
    get.releaseConnection();

    StringBuffer songIds = new StringBuffer();
    int start = result.indexOf("\"id\":");
    int end = -1;
    if(start != -1)
        end = result.indexOf(",", start);
    while(start != -1 && end != -1)
    {
        songIds.append(result.substring(start+5, end)+",");
        idList.add(result.substring(start+5, end));
        start = result.indexOf("\"id\":", end);
        if(start != -1)
            end = result.indexOf(",", start);
    }
    String songidString = songIds.substring(0, songIds.length()-1);

    //获取音乐的详细信息
    HttpPost songInfoPost = new HttpPost("http://yinyueyun.baidu.com/data/cloud/songinfo");
    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
    params.add(new BasicNameValuePair("songIds", songidString));
    params.add(new BasicNameValuePair("type", ""));
    params.add(new BasicNameValuePair("rate", ""));
    params.add(new BasicNameValuePair("pt", "0"));
    params.add(new BasicNameValuePair("flag", ""));
    params.add(new BasicNameValuePair("s2p", ""));
    params.add(new BasicNameValuePair("prerate", ""));
    params.add(new BasicNameValuePair("bwt", ""));
    params.add(new BasicNameValuePair("dur", ""));
    params.add(new BasicNameValuePair("bat", ""));
    params.add(new BasicNameValuePair("bp", ""));
    params.add(new BasicNameValuePair("pos", ""));
    params.add(new BasicNameValuePair("auto", ""));
    UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "utf-8");
    songInfoPost.setEntity(formEntity);
    CloseableHttpResponse songInfoResponse = httpClient.execute(songInfoPost);
    String jsonResult = EntityUtils.toString(songInfoResponse.getEntity());
    songInfoPost.releaseConnection();

    SongInfoEntity songInfoEntity = JSON.parseObject(jsonResult, SongInfoEntity.class);

    //下载音乐
    HttpGet songGet = null;
    for(SongEntity song : songInfoEntity.getData().getSongList())
    {

        //需要根据song id来获取每首歌曲存在的码率
        HttpGet songRateGet = new HttpGet("http://yinyueyun.baidu.com/data/cloud/download?songIds="+song.getSongId());
        CloseableHttpResponse songRateResponse = httpClient.execute(songRateGet);
        Map<Integer, String> rateMap = SongDataUtil.getRateAndFormat(EntityUtils.toString(songRateResponse.getEntity()));
        if(rateMap == null || rateMap.size()==0)
            continue;
        //可以遍历treemap,来下载多种格式的音乐,这里只下载最优质的
        Integer rateMax = null;
        String format = null;
        Iterator<Integer> it = rateMap.keySet().iterator();
        while (it.hasNext())
        {
            //it.next()得到的是key,tm.get(key)得到obj
            rateMax = it.next();
        }
        format = rateMap.get(rateMax);

        //开始下载音乐
        songGet = new HttpGet("http://yinyueyun.baidu.com/data/cloud/downloadsongfile?songIds="+song.getSongId()+"&rate="+rateMax.toString()+"&format="+format);
        //songGet = new HttpGet("http://yinyueyun.baidu.com/data/cloud/downloadsongfile?songIds=83590931&rate=941&format=flac");
        songGet.addHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36");

        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;

        CloseableHttpResponse songResponse = httpClient.execute(songGet);

        if(!songResponse.getStatusLine().toString().contains("302"))
            continue;

        //获取重定向url,该url是最终的音乐资源地址
        String redictUrl = null;
        for(Header header : songResponse.getAllHeaders())
        {
            if("Location".equals(header.getName()))
                redictUrl = header.getValue();
        }
        songGet.releaseConnection();

        HttpGet mp3Get = new HttpGet(redictUrl);
        System.out.println(redictUrl+"---"+song.getSongName()+"--->正在下载...");
        CloseableHttpResponse mp3Response = httpClient.execute(mp3Get);

            inputStream = mp3Response.getEntity().getContent();
            fileOutputStream = new FileOutputStream(new File("music/"+song.getSongName()+"-"+song.getArtistName()+"."+format));

                    byte[] bytes = new byte[102400];
                    int len = 0;
                    while((len=inputStream.read(bytes))!= -1)
                    {
                        fileOutputStream.write(bytes, 0 ,len);
                        fileOutputStream.flush();
                    }

        System.out.println(song.getSongName()+"---下载完毕");
        fileOutputStream.close();
        //songGet.reset();

    }
    httpClient.close();

 

One thought on “下载百度音乐无损品质音乐

发表评论

电子邮件地址不会被公开。 必填项已用*标注

(Spamcheck Enabled)