android音乐播放器开发在线加载歌词
转载请注明出处: 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步,问题又出现了,歌词乱码。解决办法,用字符流操作比较合适,还要注意同一编码。
[java] view plain copy
- package com.huwei.sweetmusicplayer.util;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.io.UnsupportedEncodingException;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLConnection;
- import java.net.URLEncoder;
- import java.util.Random;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.os.Environment;
- import android.util.Log;
- public class OnlineLrcUtil {
- private static String TAG = "OnlineLrcUtil";
- private static OnlineLrcUtil instance;
- public static final String lrcRootPath = Environment
- .getExternalStorageDirectory().toString()
- + "/SweetMusicPlayer/Lyrics/";
- public static final String queryLrcURLRoot = "http://geci.me/api/lyric/";
- public static OnlineLrcUtil getInstance() {
- if (null == instance) {
- instance = new OnlineLrcUtil();
- }
- return instance;
- }
- public String getQueryLrcURL(String title, String artist) {
- return queryLrcURLRoot + Encode(title) + "/" + Encode(artist);
- }
- public String getLrcURL(String title, String artist) {
- String queryLrcURLStr = getQueryLrcURL(title, artist);
- try {
- URL url = new URL(queryLrcURLStr);
- URLConnection urlConnection = url.openConnection();
- urlConnection.connect();
- BufferedReader in = new BufferedReader(new InputStreamReader(
- urlConnection.getInputStream()));
- StringBuffer sb = new StringBuffer();
- String temp;
- while ((temp = in.readLine()) != null) {
- sb.append(temp);
- }
- JSONObject jObject = new JSONObject(sb.toString());
- int count = jObject.getInt("count");
- int index = count == 0 ? 0 : new Random().nextInt() % count;
- JSONArray jArray = jObject.getJSONArray("result");
- JSONObject obj = jArray.getJSONObject(index);
- return obj.getString("lrc");
- } catch (MalformedURLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
- // 歌手,歌曲名中的空格进行转码
- public String Encode(String str) {
- try {
- return URLEncoder.encode(str.trim(), "utf-8");
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return str;
- }
- // 歌词文件网络地址,歌词文件本地缓冲地址
- public boolean wrtieContentFromUrl(String urlPath, String lrcPath) {
- Log.i(TAG, "lrcURL" + urlPath);
- try {
- URL url = new URL(urlPath);
- URLConnection urlConnection = url.openConnection();
- urlConnection.connect();
- HttpURLConnection httpConn = (HttpURLConnection) urlConnection;
- if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- File file = new File(lrcRootPath);
- if (!file.exists()) {
- file.mkdirs();
- }
- BufferedReader bf = new BufferedReader(new InputStreamReader(
- urlConnection.getInputStream(), "utf-8"));
- PrintWriter out = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(new FileOutputStream(lrcPath),
- "utf-8")));
- char c[] = new char[256];
- int temp = -1;
- while ((temp = bf.read()) != -1) {
- bf.read(c);
- out.write(c);
- }
- bf.close();
- out.close();
- return true;
- }
- // System.out.println("getFile:"+str);
- } catch (MalformedURLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return false;
- }
- public String getLrcPath(String title, String artist) {
- return lrcRootPath + title + " - " + artist + ".lrc";
- }
- }
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
更多相关文章
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- 打包状态下百度的ak的获得
- [置顶] android图形系统详解二:Drawables
- 多图片上传Android,服务器端实现
- 【Android】查看程序每个方法所花费的时间
- 生成安卓证书keystor命令文件