package com.qtfreet.musicuu.musicApi.MusicService;
import android.util.Base64;
import com.alibaba.fastjson.JSON;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteaseDatas;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteaseLostSong;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteaseLostSongAlbumId;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteaseLrc;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteaseMv;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteasePic;
import com.qtfreet.musicuu.musicApi.MusicBean.wy.NeteaseSongUrl;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by qtfreet00 on 2017/2/3.
*/
public class WyMusic implements IMusic {
//网易不支持无损解析,支持下架音乐
private static List<SongResult> search(String key, int page, int size) {
try {
String text = "{\"s\":\"" + key + "\",\"type\":1,\"offset\":" + (page - 1) * size + ",\"limit\":" + size + ",\"total\":true}";
String s = NetUtil.GetEncHtml("http://music.163.com/weapi/cloudsearch/get/web?csrf_token=", text, true);
NeteaseDatas neteaseDatas = JSON.parseObject(s, NeteaseDatas.class);
if (neteaseDatas == null) {
return null;//搜索失败
}
int totalsize = neteaseDatas.getResult().getSongCount(); //歌曲总数量
List<NeteaseDatas.ResultBean.SongsBean> songs = neteaseDatas.getResult().getSongs();
List<SongResult> songResults;
songResults = GetListByJson(songs);
if (songResults == null || songResults.size() <= 0) {
return null;//没有找到符合的歌曲
}
return songResults;
} catch (Exception e) {
return null;//解析歌曲错误
}
}
//获取封面
private static String GetPic(String id) {
String html;
try {
html = NetUtil.GetHtmlContent("http://music.163.com/api/song/detail/?ids=%5B" + id + "%5D", true);
NeteasePic neteasePic = JSON.parseObject(html, NeteasePic.class);
return neteasePic.getSongs().get(0).getAlbum().getBlurPicUrl();
} catch (Exception e) {
return "";
}
}
//解析搜索时获取到的json,然后拼接成固定格式
//具体每个返回标签的规范参考https://github.com/metowolf/NeteaseCloudMusicApi/wiki/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90API%E5%88%86%E6%9E%90---weapi
private static List<SongResult> GetListByJson(List<NeteaseDatas.ResultBean.SongsBean> songs) throws Exception {
List<SongResult> list = new ArrayList<>();
int len = songs.size();
if (len <= 0) {
return null;
}
for (NeteaseDatas.ResultBean.SongsBean song : songs) {
SongResult songResult = new SongResult();
NeteaseDatas.ResultBean.SongsBean songsBean = song;
List<NeteaseDatas.ResultBean.SongsBean.ArBean> ar = songsBean.getAr();
String artistName = "";
for (NeteaseDatas.ResultBean.SongsBean.ArBean anAr : ar) {
artistName = artistName + anAr.getName() + "/";
}
artistName = artistName.substring(0, artistName.length() - 1);
String SongId = String.valueOf(songsBean.getId());
String SongName = songsBean.getName();
String Songlink = "http://music.163.com/#/song?id=" + String.valueOf(songsBean.getId());
String ArtistId = String.valueOf(ar.get(0).getId());
String AlbumId = String.valueOf(songsBean.getAl().getId());
String AlbumName = songsBean.getAl().getName();
songResult.setLength(Util.secTotime(songsBean.getDt() / 1000));
songResult.setArtistName(artistName);
songResult.setArtistId(ArtistId);
songResult.setSongId(SongId);
songResult.setSongName(SongName);
songResult.setSongLink(Songlink);
songResult.setAlbumId(AlbumId);
songResult.setAlbumName(AlbumName);
String MvId = String.valueOf(songsBean.getMv());
songResult.setMvId(MvId);
if (Integer.valueOf(MvId) != 0) {
songResult.setMvHdUrl(GetMvUrl(MvId, "hd"));
songResult.setMvLdUrl(GetMvUrl(MvId, "ld"));
}
songResult.setType("wy");
songResult.setPicUrl(GetPic(SongId));
songResult.setLrcUrl(GetLrcUrl(SongId));
int maxbr = songsBean.getPrivilege().getMaxbr();
if (maxbr == 999000) {
String flac = GetPlayUrl(SongId, "999000");
if (!flac.contains(".mp3")) {
songResult.setBitRate("无损");
songResult.setFlacUrl(flac);
} else {
songResult.setBitRate("320K");
}
songResult.setSqUrl(GetPlayUrl(SongId, "320000"));
songResult.setHqUrl(GetPlayUrl(SongId, "192000"));
songResult.setLqUrl(GetPlayUrl(SongId, "128000"));
} else if (maxbr == 320000) {
songResult.setBitRate("320K");
songResult.setSqUrl(GetPlayUrl(SongId, "320000"));
songResult.setHqUrl(GetPlayUrl(SongId, "192000"));
songResult.setLqUrl(GetPlayUrl(SongId, "128000"));
} else if (maxbr == 192000) {
songResult.setBitRate("192K");
songResult.setHqUrl(GetPlayUrl(SongId, "192000"));
songResult.setLqUrl(GetPlayUrl(SongId, "128000"));
} else {
songResult.setBitRate("128K");
songResult.setLqUrl(GetPlayUrl(SongId, "128000"));
}
if (songsBean.getFee() == 4 || songsBean.getPrivilege().getSt() != 0) {
if (songResult.getBitRate().equals("无损")) {
songResult.setBitRate("320K");
}
}
list.add(songResult);
}
return list;
}
//如果常规请求不到播放地址,也就是下架地址,则采用专辑去搜索
public static String GetLostAlbumId(String id) {
String text = "[{\"id\":\"" + id + "\"}]";
HashMap<String, String> map = new HashMap<>();
map.put("c", text);
try {
String s = NetUtil.PostData("http://music.163.com/api/v3/song/detail", map);
int albumId = JSON.parseObject(s, NeteaseLostSongAlbumId.class).getSongs().get(0).getAl().getId();
return String.valueOf(albumId);
} catch (Exception e) {
return null;
}
}
//解析lrc歌词
private static String GetLrc(String sid) {
String url = "http://music.163.com/api/song/lyric?os=pc&id=" + sid + "&lv=-1&kv=-1&tv=-1";
String html = NetUtil.GetHtmlContent(url, true);
if (html.contains("uncollected")) {
return null;
}
return JSON.parseObject(html, NeteaseLrc.class).getLrc().getLyric();
}
//获取lrc歌词
private static String GetLrcUrl(String sid) {
String url = "http://music.163.com/api/song/lyric?os=pc&id=" + sid + "&lv=-1&kv=-1&tv=-1";
String html = NetUtil.GetHtmlContent(url, true);
if (html.contains("uncollected")) {
return "";
}
return url;
}
//获取mv地址
private static String GetMvUrl(String mid, String quality) {
String url = "http://music.163.com/api/song/mv?id=" + mid + "&type=mp4";
String html;
try {
html = NetUtil.GetHtmlContent(url, true);
NeteaseMv neteaseMv = JSON.parseObject(html, NeteaseMv.class);
int len = neteaseMv.getMvs().size();
HashMap<Integer, String> map = new HashMap<>();
int max = 0;
int i = 0;
while (i < len) {
NeteaseMv.MvsBean mvsBean = neteaseMv.getMvs().get(i);
int br = mvsBean.getBr();
if (br > max) {
max = br;
}
map.put(br, mvsBean.getMvurl());
i++;
}
if (!quality.equals("ld")) {
return map.get(max);
}
if (max == 1080) {
return map.get(720);
} else if (max == 720) {
return map.get(480);
} else if (max == 480) {
return map.containsKey(320) ? map.get(320) : map.get(240);
} else {
return map.get(240);
}
} catch (Exception e) {
return "";
}
}
//获取音乐播放地址
private static String GetPlayUrl(String id, String quality) {
String text = "{\"ids\":[\"" + id + "\"],\"br\":" + quality + ",\"csrf_token\":\"\"}";
String html;
try {
html = NetUtil.GetEncHtml("http://music.163.com/weapi/song/enhance/player/url?csrf_token=", text, true);
NeteaseSongUrl neteaseSongUrl = JSON.parseObject(html, NeteaseSongUrl.class);
if (200 == neteaseSongUrl.getData().get(0).getCode()) {
return neteaseSongUrl.getData().get(0).getUrl();
} else {
return GetLostPlayUrl(id, quality);
}
} catch (Exception ignored) {
}
return "";
}
//获取下架音乐地址
public static String GetLostPlayUrl(String id, String quality) {
String albumId = GetLostAlbumId(id);
try {
String s = NetUtil.GetHtmlContent("http://music.163.com/api/album/" + albumId, true);
NeteaseLostSong neteaseLostSong = JSON.parseObject(s, NeteaseLostSong.class);
List<NeteaseLostSong.AlbumBeanX.SongsBean> songs = neteaseLostSong.getAlbum().getSongs();
int size = songs.size();
for (NeteaseLostSong.AlbumBeanX.SongsBean songsBean : songs) {
if (songsBean.getId() == Integer.parseInt(id)) {
switch (quality) {
case "320000":
String dfsId;
if (songsBean.getHMusic() == null) {
if (songsBean.getMMusic() == null) {
return songsBean.getMp3Url();
}
dfsId = String.valueOf(songsBean.getMMusic().getDfsId());
} else {
dfsId = String.valueOf(songsBean.getHMusic().getDfsId());
}
return GetUrlBySid(dfsId);
case "192000":
if (songsBean.getMMusic() == null) {
return songsBean.getMp3Url();
} else {
dfsId = String.valueOf(songsBean.getMMusic().getDfsId());
return GetUrlBySid(dfsId);
}
default:
return songsBean.getMp3Url();
}
}
}
return "";
} catch (Exception e) {
return "";
}
}
//通过sid去搜索真实播放地址
private static String GetUrlBySid(String dfsId) {
String encryptPath = EncryptId(dfsId);
return "http://m2.music.126.net/" + encryptPath + "/" + dfsId + ".mp3";
}
public static String EncryptId(String id) {
byte[] byte1 = "3go8&$8*3*3h0k(2)2".getBytes();
byte[] byte2 = id.getBytes();
int byte1Length = byte1.length;
for (int i = 0; i < byte2.length; i++) {
byte tmp = byte1[(i % byte1Length)];
byte2[i] = ((byte) (byte2[i] ^ tmp));
}
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
e.printStackTrace();
return "";
}
byte[] md5Bytes = md5.digest(byte2);
String retval = Base64.encodeToString(md5Bytes, 0);
retval = retval.replace('/', '_');
retval = retval.replace('+', '-');
return retval;
}
@Override
public List<SongResult> SongSearch(String key, int page, int size) {
return search(key, page, size);
}
}