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": "\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}]}
非常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
版权声明:本文博客原创文章,博客,未经同意,不得转载。
android音乐播放器开发 SweetMusicPlayer 智能负载直插式歌词的更多相关文章
- android音乐播放器开发 SweetMusicPlayer 智能匹配本地歌词
		
上一篇写了使用MediaPlayer播放音乐,http://blog.csdn.net/huweigoodboy/article/details/39861539. 代码地址:https://gith ...
 - android音乐播放器开发 SweetMusicPlayer 播放本地音乐
		
上一篇写了载入歌曲列表,http://blog.csdn.net/huweigoodboy/article/details/39856411,如今来总结下播放本地音乐. 一,MediaPlayer 首 ...
 - android音乐播放器开发   SweetMusicPlayer    实现思路
		
一,实现效果 眼下还不是特别完好,主要有下面几个功能, 1,载入歌曲列表(实现a-z字母检索) 2,播放本地音乐 3.智能匹配本地歌词 4.智能载入在线歌词(事实上不算智能.发现歌词迷api提供的歌词 ...
 - android音乐播放器开发   SweetMusicPlayer   载入歌曲列表
		
上一篇写了播放器的总体实现思路,http://blog.csdn.net/huweigoodboy/article/details/39855653,如今来总结下载入歌曲列表. 代码地址:https: ...
 - android音乐播放器开发 SweetMusicPlayer 摇一摇换歌
		
上一篇写了怎样在线匹配歌词,http://blog.csdn.net/huweigoodboy/article/details/39878063,如今来讲讲摇一摇功能开发. 相同用了一个Service ...
 - android音乐播放器开发教程
		
android音乐播放器开发教程 Android扫描sd卡和系统文件 Android 关于录音文件的编解码 实现米聊 微信一类的录音上传的功能 android操作sdcard中的多媒体文件——音乐列表 ...
 - Android音乐播放器开发
		
今日看书,看到这个播放器,我就写了个例子,感觉还行,这个播放器能播放后缀是.MP3的音乐,这个例子在main.xml设置listView的时候,注意:android:id="@+id/and ...
 - Android音乐播放器源码(歌词.均衡器.收藏.qq5.0菜单.通知)
		
一款Android音乐播放器源码,基本功能都实现了 qq5.0菜单(歌词.均衡器.收藏.qq5.0菜单.通知) 只有向右滑动出现,菜单键和指定按钮都还没有添加. 源码下载:http://code.66 ...
 - 一款非常简单的android音乐播放器源码分享给大家
		
一款非常简单的android音乐播放器源码分享给大家,该应用虽然很小,大家常用的播放器功能基本实现了,可能有点还不够完善,大家也可以自己完善一下,源码在源码天堂那里已经有了,大家可以到那里下载学习吧. ...
 
随机推荐
- STL源代码分析——STL算法merge合并算法
			
前言 因为在前文的<STL算法剖析>中.源代码剖析许多.不方便学习.也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的merge合并算法. ...
 - avalon组件
			
如何做一个avalon组件 在avalon1.5中改用更直观的自定义标签来声明组件,废掉ms-widget,引入更强大的生命周期管理,可以让组件任意套嵌. 组件是由JS,HTML,CSS构成 JS 以 ...
 - ExtJS4 动态生成grid出口excel(纯粹的接待)
			
搜索相当长的时间,寻找一些样本,因为我刚开始学习的原因,大多数人不知道怎么用.. 他曾在源代码.搞到现在终于实现了主下载.. 表的采集格不重复下载一个小BUG,一个使用grid初始化发生的BUG 以下 ...
 - linux Apache rotatelogs 故障原因及解决方案未生效
			
rotatelogs 截断日志.构造.但保存vhost.conf 之后.serverhttpd -k restart 还是无法成功重新启动. 日志文件: (2)No such file or dire ...
 - DFS PKU 1562
			
简单地DFS Oil Deposits Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12801 Accepted: 6 ...
 - JavaScript模块化编程之require.js与sea.js
			
为什么要模块化:当今,网站以不再是一个简单的页面,JavaScript也不再是做一些简单的脚本验证,随着WEB.20时代到来,前端工程师面临的必将是越来越庞大的JavaScript代码,越来越复杂的内 ...
 - uva10827-Maximum sum on a torus(矩阵最大和的变形)
			
题目;uva10827-Maximum sum on a torus(矩阵最大和的变形) 题目大意:就是uva108的变形,矩阵能够连通,就是能够从后面连到前面.这里把矩阵复制三遍,然后又一次生成一个 ...
 - csdn 博客,你很努力,有人帮你-2015年03一个月17日本
			
今天泛化 开始使用简书 正则表达式的博客写了两篇文章 回顾 Core Data 基本使用 总结 Xcode6新特性 简单聊聊 简书,事实上一開始学 MarkDown 语法的时候,已经用了,但是,一直认 ...
 - node.js高效操作mongodb
			
node.js高效操作mongodb Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为Jav ...
 - mysql_navicat_快捷键
			
快捷键能节省很多时间,之前一直研究oracle,plsql有自定义自动补全, 比如 sf 直接回车 可以出现 select * from 等等(参照http://www.cnblogs.com/cph ...