转载请注明出处: http://blog.csdn.net/u014608640/article/details/51899239
如果没有本地歌词怎么办?现在来将一下加载在线歌词。好了,还是用那张图。
在实现这个功能的时候,lz尝试过baidu api,歌词迷api,后来选用了歌词迷api,虽然还是资源不全,而且还有很多错误。特别头疼的是有时候歌词居然不分行,解析起来简直难受。
歌词迷api歌词查询地址:http://geci.me/api/lyric/
比如我要查询: http://geci.me/api/lyric/安静/周杰伦
会得到一下json串:
{"count": 2, "code": 0, "result": [{"aid": 2223011, "artist_id": 30796, "song": "\u5b89\u9759", "lrc": "http://s.geci.me/lrc/257/25700/2570058.lrc", "sid": 2570058}, {"aid": 2336033, "artist_id": 30796, "song": "\u5b89\u9759", "lrc": "http://s.geci.me/lrc/272/27282/2728244.lrc", "sid": 2728244}]}
很容易发现里面的歌词文件,然后缓冲到本地(SweetMusicPlayer/Lryics)下,再按本地加载的方式就行了。
捋一捋,我们加载歌词文件要经过以下步骤。
1)通过地址查询出歌词的地址。(这里楼主用URLConnection)
2)通过歌词地址缓冲歌词文件。(这里楼主用URLConnection)
3)加载缓冲好的歌词文件。
上面说的看起来还是比较容易,楼主自己写了个demo,是一个Java工程,发现没啥问题,正常加载歌词文件。
等到Android上,第一步就跪了。发现URLConnection的getInputStream()抛出一个io异常,简直要命,折腾了半天才发现是因为带了http://geci.me/api/lyric/安静/周杰伦中文路径。由于默认是gbk,网络传输为utf-8,所以要把中文转码,URLEncoder.encode(str,"utf-8");即可。
到了第2步,问题又出现了,歌词乱码。解决办法,用字符流操作比较合适,还要注意同一编码。
LrcProcess 类,用来保存处理下载后的文件
public class LrcProcess {
private List lrcList; //List集合存放歌词内容对象
private LrcContent mLrcContent; //声明一个歌词内容对象
/**
* 无参构造函数用来实例化对象
*/
public LrcProcess() {
mLrcContent = new LrcContent();
lrcList = new ArrayList();
}
/**
* 读取歌词
* @param path
* @return
*/
public String readLRC(String path) {
//定义一个StringBuilder对象,用来存放歌词内容
StringBuilder stringBuilder = new StringBuilder();
File f = new File(path.replace(".mp3", ".lrc"));
try {
//创建一个文件输入流对象
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
BufferedReader br = new BufferedReader(isr);
String s = "";
while((s = br.readLine()) != null) {
//替换字符
s = s.replace("[", "");
s = s.replace("]", "@");
//分离“@”字符
String splitLrcData[] = s.split("@");
if(splitLrcData.length > 1) {
Log.i("INFO", splitLrcData[1]+"歌词");
mLrcContent.setLrcStr(splitLrcData[1]);
Log.i("INFO", splitLrcData[0]+"时间");
//处理歌词取得歌曲的时间
int lrcTime = time2Str(splitLrcData[0]);
mLrcContent.setLrcTime(lrcTime);
//添加进列表数组
lrcList.add(mLrcContent);
//新创建歌词内容对象
mLrcContent = new LrcContent();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
stringBuilder.append("木有歌词文件,赶紧去下载!...");
} catch (IOException e) {
e.printStackTrace();
stringBuilder.append("木有读取到歌词哦!");
}
return stringBuilder.toString();
}
/**
* 解析歌词时间
* 歌词内容格式如下:
* [00:02.32]陈奕迅
* [00:03.43]好久不见
* [00:05.22]歌词制作 王涛
* @param timeStr
* @return
*/
public int time2Str(String timeStr) {
timeStr = timeStr.replace(":", ".");
timeStr = timeStr.replace(".", "@");
String timeData[] = timeStr.split("@"); //将时间分隔成字符串数组
//分离出分、秒并转换为整型
int minute = Integer.parseInt(timeData[0]);
int second = Integer.parseInt(timeData[1]);
int millisecond = Integer.parseInt(timeData[2]);
//计算上一行与下一行的时间转换为毫秒数
int currentTime = (minute * 60 + second) * 1000 + millisecond * 10;
return currentTime;
}
public List getLrcList() {
return lrcList;
}
Mainactivity 大概调用方法
public class MainActivity extends Activity {
//好久不见 青花
private String mMusicName="夜曲";
//陈奕迅 周传雄
private String mMusicAutor="周杰伦";
@SuppressLint("SdCardPath")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(){
public void run() {
String lrcURL = OnlineLrcUtil.getLrcURL(mMusicName, mMusicAutor);
Log.i("INFO", lrcURL+"lrcURL");
//开始缓存歌词
boolean b = OnlineLrcUtil.wrtieContentFromUrl(lrcURL, OnlineLrcUtil.getLrcPath(mMusicName, mMusicAutor));
Log.i("INFO", "缓存歌词"+b);
Log.i("INFO", OnlineLrcUtil.getLrcPath(mMusicName, mMusicAutor)+"地址");
LrcProcess lrcP=new LrcProcess();
lrcP.readLRC(OnlineLrcUtil.getLrcPath(mMusicName, mMusicAutor));
Log.i("INFO", "歌词"+lrcP.getLrcList().size());
};
}.start();
}
http://download.csdn.net/detail/u014608640/9575221