1. 程式人生 > >android 線上獲取音樂歌詞lrc檔案

android 線上獲取音樂歌詞lrc檔案

很久沒來了 昨天公司 年會 簡直無情 左邊兩個 右邊兩個 對面一個 都中獎了 我最平衡了 心都碎了 回來之後 暗下決心 還是好好敲程式碼吧 人品不行 就好好學習 做了一個線上獲取歌詞lrc的 demo 因為最近在做一款音樂播放器 有用到 就分享下 其實主要就是介面難找 我這個介面也不怎麼好 有些歌曲也搜不到歌詞第一個連結格式 http://box.zhangmen.baidu.com/x?op=12&count=1&title=%E5%80%94%E5%BC%BA$$%E4%BA%94%E6%9C%88%E5%A4%A9$$$$%E5%80%94%E5%BC%BA
這種東西肯定是編碼了的 所以上面的基本就是這個樣子
走一次
發現是XML 其中發現一個節點 lrcid 再根據 這個lrcid節點 去另一個介面
獲取lrc檔案 XML
</pre><pre>
</pre><pre name="code" class="java">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >

    <EditText
        android:id="@+id/et_song"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="倔強"
        />
    
    <EditText
        android:layout_below="@id/et_song"
        android:id="@+id/et_singer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="五月天"
         />
    
    <Button 
        android:layout_below="@id/et_singer"
        android:id="@+id/bt_submit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="提交"
        />
    
    <ScrollView 
        android:layout_below="@id/bt_submit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
    <TextView 
      
        android:id="@+id/tv_show"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="暫無資料"
        />
    </ScrollView>

</RelativeLayout>


MainActivity

package com.example.getlrconline;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import org.xmlpull.v1.XmlPullParser;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Xml;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

	private String et_singer_str;
	private String et_song_str;
	private String get_id_url;
	private EditText et_singer;
	private EditText et_song;
	private Button bt_submit;
	private TextView tv_show;
	private String result_xml;

	private String baseUrl = Environment.getExternalStorageDirectory()
			+ "/dting/lrc/";

	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				if ("".equals(result_xml)){
					tv_show.setText("未獲取歌詞");
				}
				else {
					getLrcByLrcId();
				}
				break;

			case 2:
				// 讀取本地儲存的 歌詞
				String path = baseUrl + et_singer_str + "-" + et_song_str
						+ ".lrc";
				String lrc_content = getString4Local(path);
				
				if ("".equals(lrc_content)) {
					tv_show.setText("沒有獲取到歌詞");
				} else {
					tv_show.setText(lrc_content);
				}
				break;
			default:
				break;
			}
		}

		/**
		 * 獲取lrc檔案
		 */
		private void getLrcByLrcId() {
			tv_show.setText(result_xml);
			// 得到 id 開始獲取 歌詞檔案 下載到地址地方 /dting/lrc/XXX.lrc
			String end_path = Integer.parseInt(result_xml) / 100 + "/"
					+ result_xml + ".lrc";

			get_lrc_url = get_lrc_url + end_path;
			
			// 開始獲取 lrc
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						boolean isOk_getLrc = requestByGet(get_lrc_url,
								baseUrl, et_singer_str + "-"
										+ et_song_str + ".lrc");
						
						if (isOk_getLrc) {
							Message msg = Message.obtain();
							msg.what = 2;
							handler.sendMessage(msg);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();
		};
	};

	private String get_lrc_url;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		et_singer = (EditText) findViewById(R.id.et_singer);
		et_song = (EditText) findViewById(R.id.et_song);
		bt_submit = (Button) findViewById(R.id.bt_submit);
		tv_show = (TextView) findViewById(R.id.tv_show);
		// http://box.zhangmen.baidu.com/x?op=12&count=1&title=
		// %E5%80%94%E5%BC%BA$$%E4%BA%94%E6%9C%88%E5%A4%A9$$$$
		
		bt_submit.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				result_xml="";
				et_singer_str = et_singer.getText().toString();
				et_song_str = et_song.getText().toString();
				
				get_id_url = "http://box.zhangmen.baidu.com/x?op=12&count=1&title=";
				get_lrc_url = "http://box.zhangmen.baidu.com/bdlrc/";
				
				if (("".equals(et_singer_str) || null == et_singer_str)
						|| ("".equals(et_song_str) || null == et_song_str)) {
					Toast.makeText(getApplicationContext(), "填入資訊", 0).show();
					return;
				}
				try {
					String name = URLEncoder.encode(et_song_str, "utf-8");
					String singer = URLEncoder.encode(et_singer_str, "utf-8");

					get_id_url = get_id_url + name + "$$" + singer + "$$$$";
					new Thread(new Runnable() {
						@Override
						public void run() {
							// 根據這個地址 得到xml 解析 xml
							try {
								result_xml = requestByGet_xml(get_id_url);
								
								System.out.println("傳送id " +result_xml);
								
								Message msg = Message.obtain();
								msg.what = 1;
								handler.sendMessage(msg);

							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}).start();
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * 本地讀取歌詞檔案
	 * @param path
	 */
	protected String getString4Local(String path) {
		try {
			InputStream in = new FileInputStream(new File(path));
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			
			byte[] buffer = new byte[1024];
			int len = -1;
			while ((len = in.read(buffer)) != -1) {
				os.write(buffer, 0, len);
			}
			return os.toString("gbk");    //檔案編碼是GBK的

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	// Get方式請求
	/**
	 * 解析XMl
	 * @param path
	 * @return
	 * @throws Exception
	 */
	public  String requestByGet_xml(String path) throws Exception {
		URL url = new URL(path);
		
		HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
		urlConn.setConnectTimeout(5 * 1000);
		urlConn.connect();
		String id = "";
		XmlPullParser xmlParser = Xml.newPullParser();
		// 判斷請求是否成功
		if (urlConn.getResponseCode() == 200) {
			// 獲取響應的輸入流物件
			InputStream is = urlConn.getInputStream();
			String itemElement = "lrcid";  //要獲取的節點name
			
			XmlPullParser xmlPullParser = Xml.newPullParser();
			xmlPullParser.setInput(is, "UTF-8");
			int event = xmlPullParser.getEventType();

			while (event != XmlPullParser.END_DOCUMENT) {
				switch (event) {
				case XmlPullParser.START_TAG:
					if (itemElement.equals(xmlPullParser.getName())) {
						id = xmlPullParser.nextText();
					}
					break;
				case XmlPullParser.END_TAG:
					if (itemElement.equals(xmlPullParser.getName())) {
					}
					break;
				}

				if ("".equals(id) || null == id) {
					event = xmlPullParser.next();
				} else {
					break;
				}
			}
			
			urlConn.disconnect();
		}
		return id;
	}

	// Get方式請求
	/**
	 * 得到lrc檔案下載本地
	 * @param path
	 * @param save_path
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	
	public boolean requestByGet(String path, String save_path, String filename)
			throws Exception {
		URL url = new URL(path);
		HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
		urlConn.setConnectTimeout(5 * 1000);
		urlConn.connect();
		// 判斷請求是否成功
		if (urlConn.getResponseCode() == 200) {
			// 獲取響應的輸入流物件
			InputStream is = urlConn.getInputStream();
			
			File file1 = new File(save_path);
			if (!file1.exists()) {
				file1.mkdirs();
			}
			File file = new File(save_path + filename);
			
			InputStreamReader isr=new InputStreamReader(is, "gbk");
			BufferedReader br=new BufferedReader(isr);
			
			
			FileOutputStream out = new FileOutputStream(file);
			OutputStreamWriter  osw=new OutputStreamWriter(out, "gbk");
			BufferedWriter bw=new BufferedWriter(osw);
			String ss="";
			while ((ss=br.readLine())!=null) {
				bw.write(ss);
				bw.newLine();
			}
			// 釋放資			i
			bw.close();
			br.close();
			
			urlConn.disconnect();
			
			return true;
		} else {
			Log.i("GET", "Get方式請求失敗");
		}
		// 關閉連線
		urlConn.disconnect();
		return false;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}




有必要說一下 我試過 有些能獲取到 有些不能獲取到  其實 這樣的話  也可以處理 多找幾個免費的api介面 第一個沒獲取 就進入第二個  依次  要是全沒獲取 那就只有自己搭建了 畢竟免費的不多 資源肯定也有限 

另外還說一下我找到一個 挺好的歌詞很多的 但是 不怎麼會獲取 比如這一個

看連線  你發現通過你的搜尋 可以得到 如下連結  

這個只能是 根據歌曲名單獨搜尋 不能歌曲名加歌手 這樣一來 如上所述 有多個  而且 主要是要拿我那個 小太陽所指向的那個連結  http://www.bzmtv.com/geci/276/119119.html  也就是這個連結  不知道如何獲取 能獲取這個 就可以獲取歌詞了 因為 如下


看到了 那個 lrc檔案 我複製 連結 直接進去 是可以下載的  難點就是  怎麼根據我搜索的歌名 獲取某個歌手的 那首歌詞的連線 http://www.bzmtv.com/geci/276/119119.html   276/119119好就可以獲取 這個網站的歌詞  哪位知道可以告訴下我  大家一起學習哈。。。