zoukankan      html  css  js  c++  java
  • android音乐播放器开发 SweetMusicPlayer 智能负载直插式歌词

    在一份书面的使用MediaPlayer播放音乐, http://blog.csdn.net/huweigoodboy/article/details/39862773。假设没有本地歌词怎么办?如今来将一下载入在线歌词。好了,还是用那张图。



    在实现这个功能的时候,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": "u5b89u9759", "lrc": "http://s.geci.me/lrc/257/25700/2570058.lrc", "sid": 2570058}, {"aid": 2336033, "artist_id": 30796, "song": "u5b89u9759", "lrc": "http://s.geci.me/lrc/272/27282/2728244.lrc", "sid": 2728244}]}

    非常easy发现里面的歌词文件。然后缓冲到本地(SweetMusicPlayer/Lryics)下,再按本地载入的方式即可了。


    捋一捋,我们载入歌词文件要经过下面步骤。

    1)通过地址查询出歌词的地址。

    (这里楼主用URLConnection)

    2)通过歌词地址缓冲歌词文件。

    (这里楼主用URLConnection)

    3)载入缓冲好的歌词文件。


    上面说的看起来还是比較easy,楼主自己写了个demo,是一个javaproject,发现没啥问题。正常载入歌词文件。

    等到android上,第一步就跪了。发现URLConnection的getInputStream()抛出一个io异常,简直要命。折腾了半天才发现是由于带了http://geci.me/api/lyric/安静/周杰伦中文路径。

    由于默认是gbk,网络传输为utf-8,所以要把中文转码。URLEncoder.encode(str,"utf-8");就可以。


    到了第2步,问题又出现了,歌词乱码。

    解决的方法,用字符流操作比較合适,还要注意同一编码。

    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";
    	}
    }
    


    下一篇摇一摇切歌:http://blog.csdn.net/huweigoodboy/article/details/39880779

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    C字符串和C++字符串
    Linux的用户态和内核态
    知乎问答:如何理解“In UNIX, everything is a file”?
    科普:并行计算、分布式计算、集群计算和云计算
    个人使用VIM的一些总结
    C语言回调函数学习
    Python的函数参数传递:传值?引用?
    ECMAScript 函数函数概述
    ECMAScript 函数arguments 对象
    ECMAScript 语句with 语句
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4619447.html
Copyright © 2011-2022 走看看