[置顶] 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
 
  1. package com.huwei.sweetmusicplayer.util;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.File;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStreamReader;  
  9. import java.io.OutputStreamWriter;  
  10. import java.io.PrintWriter;  
  11. import java.io.UnsupportedEncodingException;  
  12. import java.net.HttpURLConnection;  
  13. import java.net.MalformedURLException;  
  14. import java.net.URL;  
  15. import java.net.URLConnection;  
  16. import java.net.URLEncoder;  
  17. import java.util.Random;  
  18.   
  19. import org.json.JSONArray;  
  20. import org.json.JSONException;  
  21. import org.json.JSONObject;  
  22.   
  23. import android.os.Environment;  
  24. import android.util.Log;  
  25.   
  26. public class OnlineLrcUtil {  
  27.     private static String TAG = "OnlineLrcUtil";  
  28.     private static OnlineLrcUtil instance;  
  29.     public static final String lrcRootPath = Environment  
  30.             .getExternalStorageDirectory().toString()  
  31.             + "/SweetMusicPlayer/Lyrics/";  
  32.   
  33.     public static final String queryLrcURLRoot = "http://geci.me/api/lyric/";  
  34.   
  35.     public static OnlineLrcUtil getInstance() {  
  36.         if (null == instance) {  
  37.             instance = new OnlineLrcUtil();  
  38.         }  
  39.   
  40.         return instance;  
  41.     }  
  42.   
  43.     public String getQueryLrcURL(String title, String artist) {  
  44.         return queryLrcURLRoot + Encode(title) + "/" + Encode(artist);  
  45.     }  
  46.   
  47.     public String getLrcURL(String title, String artist) {  
  48.         String queryLrcURLStr = getQueryLrcURL(title, artist);  
  49.         try {  
  50.             URL url = new URL(queryLrcURLStr);  
  51.             URLConnection urlConnection = url.openConnection();  
  52.             urlConnection.connect();  
  53.   
  54.             BufferedReader in = new BufferedReader(new InputStreamReader(  
  55.                     urlConnection.getInputStream()));  
  56.   
  57.             StringBuffer sb = new StringBuffer();  
  58.   
  59.             String temp;  
  60.             while ((temp = in.readLine()) != null) {  
  61.                 sb.append(temp);  
  62.             }  
  63.   
  64.             JSONObject jObject = new JSONObject(sb.toString());  
  65.             int count = jObject.getInt("count");  
  66.             int index = count == 0 ? 0 : new Random().nextInt() % count;  
  67.             JSONArray jArray = jObject.getJSONArray("result");  
  68.             JSONObject obj = jArray.getJSONObject(index);  
  69.             return obj.getString("lrc");  
  70.   
  71.         } catch (MalformedURLException e) {  
  72.             // TODO Auto-generated catch block  
  73.             e.printStackTrace();  
  74.         } catch (IOException e) {  
  75.             // TODO Auto-generated catch block  
  76.             e.printStackTrace();  
  77.         } catch (JSONException e) {  
  78.             // TODO Auto-generated catch block  
  79.             e.printStackTrace();  
  80.         }  
  81.   
  82.         return null;  
  83.     }  
  84.   
  85.     // 歌手,歌曲名中的空格进行转码  
  86.     public String Encode(String str) {  
  87.   
  88.         try {  
  89.             return URLEncoder.encode(str.trim(), "utf-8");  
  90.         } catch (UnsupportedEncodingException e) {  
  91.             // TODO Auto-generated catch block  
  92.             e.printStackTrace();  
  93.         }  
  94.   
  95.         return str;  
  96.   
  97.     }  
  98.   
  99.     // 歌词文件网络地址,歌词文件本地缓冲地址  
  100.     public boolean wrtieContentFromUrl(String urlPath, String lrcPath) {  
  101.         Log.i(TAG, "lrcURL" + urlPath);  
  102.   
  103.         try {  
  104.             URL url = new URL(urlPath);  
  105.   
  106.             URLConnection urlConnection = url.openConnection();  
  107.             urlConnection.connect();  
  108.   
  109.             HttpURLConnection httpConn = (HttpURLConnection) urlConnection;  
  110.             if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {  
  111.                 File file = new File(lrcRootPath);  
  112.                 if (!file.exists()) {  
  113.                     file.mkdirs();  
  114.                 }  
  115.   
  116.                 BufferedReader bf = new BufferedReader(new InputStreamReader(  
  117.                         urlConnection.getInputStream(), "utf-8"));  
  118.                 PrintWriter out = new PrintWriter(new BufferedWriter(  
  119.                         new OutputStreamWriter(new FileOutputStream(lrcPath),  
  120.                                 "utf-8")));  
  121.   
  122.                 char c[] = new char[256];  
  123.                 int temp = -1;  
  124.                 while ((temp = bf.read()) != -1) {  
  125.                     bf.read(c);  
  126.                     out.write(c);  
  127.                 }  
  128.   
  129.                 bf.close();  
  130.                 out.close();  
  131.   
  132.                 return true;  
  133.             }  
  134.   
  135.             // System.out.println("getFile:"+str);  
  136.         } catch (MalformedURLException e) {  
  137.             // TODO Auto-generated catch block  
  138.             e.printStackTrace();  
  139.         } catch (IOException e) {  
  140.             // TODO Auto-generated catch block  
  141.             e.printStackTrace();  
  142.         }  
  143.   
  144.         return false;  
  145.     }  
  146.   
  147.     public String getLrcPath(String title, String artist) {  
  148.         return lrcRootPath + title + " - " + artist + ".lrc";  
  149.     }  
  150. }  

LrcProcess 类,用来保存处理下载后的文件

public class LrcProcess {
	private List<LrcContent> lrcList;	//List集合存放歌词内容对象
	private LrcContent mLrcContent;		//声明一个歌词内容对象
	/**
	 * 无参构造函数用来实例化对象
	 */
	public LrcProcess() {
		mLrcContent = new LrcContent();
		lrcList = new ArrayList<LrcContent>();
	}
	
	/**
	 * 读取歌词
	 * @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<LrcContent> 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

你可能感兴趣的:(源码,音乐)