实现功能:

实现网络音乐歌词下载功能(下载音乐的同时,下载对应歌词)

下载好的歌词目前不在播放器内,可以通过文件浏览器查看。
后续将博文,将实现本地音乐歌词下载和已下载音乐扫描功能。

因为,没有自己的服务器,所以网络音乐所有相关功能(包含搜索音乐、下载音乐、下载歌词)均无法保证时效性,建议,尽快下载和练习;如果你下载时候,已经因为我采集的服务器更改规则,请给我留言,如果可以解决,我将在有空的时候献上新的源码。

截止到目前的源码下载:
http://download.csdn.net/album/detail/3105
(最新的,请下载最后一个,本博文对应版本2.0;歌词下载只修改了DownloadUtils,所以下载1.9,修改一下DownloadUtils,也是可以的;如果需要逐步实现的过程,请下载所有)

欢迎移动开发爱好者交流:我的微信是iwanghang

另外,我打算开始找工作,如果沈阳或周边城市公司有意,也请与我联系。

实现效果如图:

实现代码如下:
DownloadUtils如下:

package com.iwanghang.drmplayer.utils;import android.os.Environment;
import android.os.Handler;
import android.os.Message;import com.iwanghang.drmplayer.vo.SearchResult;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import javax.xml.parsers.ParserConfigurationException;/*** Created by iwanghang on 16/5/3.* 网络音乐下载工具类*/
public class DownloadUtils {private static final String DOWNLOAD_URL = "/download?_o=%2Fsearch%2Fsong";private static final int SUCCESS_LRC = 1;//下载歌词成功private static final int FAILED_LRC = 2;//下载歌词失败private static final int SUCCESS_MP3 = 3;//下载歌曲成功private static final int FAILED_MP3 = 4;//下载歌曲失败private static final int GET_MP3_URL = 5;//获取音乐下载地址成功private static final int GET_FAILED_MP3_URL = 6;//获取音乐下载地址失败private static final int MUSIC_EXISTS = 7;//下载时,音乐已存在private static DownloadUtils sInstance;private OnDownloadListener mListener;private ExecutorService mThreadPool;/***设置回调监听器对象* @param mListener* @return*/public DownloadUtils setListener(OnDownloadListener mListener){this.mListener = mListener;return this;}//获取下载工具的实例public synchronized static DownloadUtils getsInstance(){if (sInstance == null){try {sInstance = new DownloadUtils();} catch (ParserConfigurationException e) {e.printStackTrace();}}return  sInstance;}/*** 下载的具体业务方法* @throws ParserConfigurationException*/private DownloadUtils() throws ParserConfigurationException{mThreadPool = Executors.newSingleThreadExecutor();}public void download(final SearchResult searchResult){final Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what){case SUCCESS_LRC:if (mListener != null) mListener.onDowload("歌词下载成功");break;case FAILED_LRC:if (mListener != null) mListener.onFailed("歌词下载失败");break;case GET_MP3_URL:System.out.println("GET_MP3_URL:"+msg.obj);downloadMusic(searchResult,(String)msg.obj,this);break;case GET_FAILED_MP3_URL:if (mListener != null) mListener.onFailed("下载失败,该歌曲为收费或VIP类型");break;case SUCCESS_MP3:if (mListener != null) mListener.onDowload(searchResult.getMusicName()+"已经下载");String url = Constant.MIGU_URL + searchResult.getUrl();System.out.println("download lrc:"+url);downloadLRC(url,searchResult.getMusicName(),searchResult.getArtist(),this);break;case FAILED_MP3:if (mListener != null) mListener.onFailed(searchResult.getMusicName()+"下载失败");break;case MUSIC_EXISTS:if (mListener != null) mListener.onFailed("音乐已存在");break;}}};getDownloadMusicURL(searchResult,handler);}//获取下载歌词的URLprivate void getDownloadLrcURL(final SearchResult searchResult, final Handler handler) {mThreadPool.execute(new Runnable() {@Overridepublic void run() {//http://music.baidu.com/search/lrc?key=%E6%9C%89%E5%BF%83%E4%BA%BA%20G.E.M.%E9%82%93%E7%B4%AB%E6%A3%8B//"http://music.baidu.com/search/lrc?key=" + 歌名 + " " + 歌手//System.out.println("searchResult.getUrl() = " + searchResult.getUrl());//String[] aa = searchResult.getUrl().split("/");//String sn = aa[5];//System.out.println("歌曲编号 = " + sn);//从浏览器复制出来的Url是这样的,"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";//汉字经过utf8编码,比如 冰雨 == %E5%86%B0%E9%9B%A8;//经过测试 获取页面 使用"http://music.baidu.com/search?key=冰雨";无法打开正确连接//比如使用URLEncoder.encode转码,转为utf8//实际使用 获取页面 使用"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";try {String musicName = URLEncoder.encode(searchResult.getMusicName(), "utf8");String artistName = URLEncoder.encode(searchResult.getArtist(), "utf8");//String url = Constant.BAIDU_LRC_SEARCH_HEAD + searchResult.getMusicName() + " " + searchResult.getArtist();String url = Constant.BAIDU_LRC_SEARCH_HEAD + musicName + "+" + artistName;System.out.println("歌词下载页面url = " + url);Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();//System.out.println("歌词下载页面 doc : " + doc);Elements lrcUrls = doc.select("span.lyric-action");System.out.println(lrcUrls);for (int i=0;i<lrcUrls.size();i++) {Elements urlsa = lrcUrls.get(i).getElementsByTag("a");System.out.println("tag a urlsa : " + urlsa);for (int a=0;i<urlsa.size();a++) {System.out.println("----" + urlsa.get(a).toString());String urla = urlsa.get(a).toString();System.out.println("-----" + urla);//-----<a class="down-lrc-btn { 'href':'/data2/lrc/14488216/14488216.lrc' }" href="#">下载LRC歌词</a>if (urla.indexOf("'href':'")>0){String[] uu = urla.split("'href':'");System.out.println("uu1 : " + uu[1]);//uu1 : /data2/lrc/14488216/14488216.lrc' }" href="#">下载LRC歌词</a>String[] uuu = uu[1].split(".lrc");System.out.println("uuu0 : " + uuu[0]);//uuu0 : /data2/lrc/14488216/14488216String result = "http://music.baidu.com" + uuu[0] + ".lrc";System.out.println("result : " + result);//result :  http://music.baidu.com/data2/lrc/14488216/14488216.lrcMessage msg = handler.obtainMessage(SUCCESS_LRC,result);msg.sendToTarget();break;}}}} catch (IOException e) {e.printStackTrace();handler.obtainMessage(FAILED_LRC).sendToTarget();}}});}//获取下载音乐的URLprivate void getDownloadMusicURL(final SearchResult searchResult, final Handler handler) {mThreadPool.execute(new Runnable() {@Overridepublic void run() {//http://music.migu.cn/#/album/1003215276//1003215279//http://music.migu.cn/order/1003215279/down/self/P2Z3Y12L1N2/3/001002A/1003215279System.out.println("searchResult.getUrl() = " + searchResult.getUrl());String[] aa = searchResult.getUrl().split("/");String sn = aa[5];System.out.println("歌曲编号 = " + sn);String url = Constant.MIGU_DOWN_HEAD + sn + Constant.MIGU_DOWN_FOOT;System.out.println("歌曲下载页面url = " + url);try {Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();//System.out.println(doc);System.out.println("doc.toString() = " + doc.toString());String[] bb = doc.toString().split("song");//把 下载页面源码 按照"song"分割for (int i=0;i<bb.length;i++){System.out.println("bb[" + i + "] = " + bb[i]);if (bb[i].indexOf("mp3?msisdn")>0){System.out.println("mp3?msisdn = " + bb[i]);String initMp3Url = bb[i];//initMp3Url 初始Mp3下载链接,如下//mp3?msisdn = ":"http://tyst.migu.cn/public/ringmaker01/10月31日中文延期/文件/全套格式/9000首/全曲试听/Mp3_128_44_16/一起走过的日子-刘德华.mp3?msisdn\u003d7b609763f0ff","String[] arrayHttp = initMp3Url.split("http");//把 初始Mp3下载链接 按照"http"分割String[] arrayMp3 = arrayHttp[1].split(".mp3");//把 arrayHttp 按照".mp3"分割String result = "http" + arrayMp3[0] + ".mp3";//把分割去掉的"http"和".mp3",组合回来System.out.println("result");//String result = "http://tyst.migu.cn/public/ringmaker01/10月31日中文延期/文件/全套格式/9000首/全曲试听/Mp3_128_44_16/一起走过的日子-刘德华.mp3";Message msg = handler.obtainMessage(GET_MP3_URL,result);msg.sendToTarget();}}} catch (IOException e) {e.printStackTrace();handler.obtainMessage(GET_FAILED_MP3_URL).sendToTarget();}}});}//下载歌词private void downloadLRC(final String url, final String musicName, final String artistName,final Handler handler){mThreadPool.execute(new Runnable() {@Overridepublic void run() {//从浏览器复制出来的Url是这样的,"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";//汉字经过utf8编码,比如 冰雨 == %E5%86%B0%E9%9B%A8;//经过测试 获取页面 使用"http://music.baidu.com/search?key=冰雨";无法打开正确连接//比如使用URLEncoder.encode转码,转为utf8//实际使用 获取页面 使用"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";try {String musicNameEn = URLEncoder.encode(musicName, "utf8");String artistNameEn = URLEncoder.encode(artistName, "utf8");//String url = Constant.BAIDU_LRC_SEARCH_HEAD + searchResult.getMusicName() + " " + searchResult.getArtist();String url = Constant.BAIDU_LRC_SEARCH_HEAD + musicNameEn + "+" + artistNameEn;System.out.println("歌词下载页面url = " + url);Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();//System.out.println("歌词下载页面 doc : " + doc);Elements lrcUrls = doc.select("span.lyric-action");System.out.println(lrcUrls);for (int i = 0; i < lrcUrls.size(); i++) {Elements urlsa = lrcUrls.get(i).getElementsByTag("a");System.out.println("tag a urlsa : " + urlsa);for (int a = 0; a < urlsa.size(); a++) {//System.out.println("----" + urlsa.get(a).toString());String urla = urlsa.get(a).toString();System.out.println("-----" + urla);//-----<a class="down-lrc-btn { 'href':'/data2/lrc/14488216/14488216.lrc' }" href="#">下载LRC歌词</a>if (urla.indexOf("'href':'") > 0) {String[] uu = urla.split("'href':'");System.out.println("uu1 : " + uu[1]);//uu1 : /data2/lrc/14488216/14488216.lrc' }" href="#">下载LRC歌词</a>String[] uuu = uu[1].split(".lrc'");System.out.println("uuu0 : " + uuu[0]);//uuu0 : /data2/lrc/246970367/246970367.lrcString lrcDwonUrl = "http://music.baidu.com" + uuu[0] + ".lrc";System.out.println("lrcDwonUrl : " + lrcDwonUrl);//result :  http://music.baidu.com/data2/lrc/14488216/14488216.lrcFile LrcDirFile = new File(Environment.getExternalStorageDirectory() + Constant.DIR_LRC);System.out.println("LrcDirFile : " + LrcDirFile);if (!LrcDirFile.exists()) {LrcDirFile.mkdirs();}String target = LrcDirFile + "/" + musicName + ".lrc";System.out.println("lrcDwonUrl : " + lrcDwonUrl);System.out.println("target : " + target);File fileTarget = new File(target);if (fileTarget.exists()) {handler.obtainMessage(MUSIC_EXISTS).sendToTarget();return;} else {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(lrcDwonUrl).build();Response response = client.newCall(request).execute();if (response.isSuccessful()) {PrintStream ps = new PrintStream(new File(target));byte[] bytes = response.body().bytes();ps.write(bytes, 0, bytes.length);ps.close();handler.obtainMessage(SUCCESS_LRC, target).sendToTarget();}}}}}} catch (IOException e) {e.printStackTrace();}}});}//下载MP3private void downloadMusic(final SearchResult searchResult,final String url,final Handler handler){mThreadPool.execute(new Runnable() {@Overridepublic void run() {File musicDirFile = new File(Environment.getExternalStorageDirectory()+Constant.DIR_MUSIC);if (!musicDirFile.exists()){musicDirFile.mkdirs();}String mp3url = url;//String mp3url = "http://tyst.migu.cn/public/600902-2008430/tone/2008/09/10/2008年9月/4月环球106首歌曲/彩铃/7_mp3-128kbps/等你等到我心痛-张学友.mp3";String target = musicDirFile + "/" + searchResult.getMusicName() + ".mp3";System.out.println(mp3url);System.out.println(target);File fileTarget = new File(target);if (fileTarget.exists()){handler.obtainMessage(MUSIC_EXISTS).sendToTarget();return;}else {//使用OkHttpClient组件OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(mp3url).build();System.out.println(request);try {Response response = client.newCall(request).execute();if (response.isSuccessful()){PrintStream ps = new PrintStream(fileTarget);byte[] bytes = response.body().bytes();ps.write(bytes,0,bytes.length);ps.close();handler.obtainMessage(SUCCESS_MP3).sendToTarget();}} catch (IOException e) {e.printStackTrace();handler.obtainMessage(FAILED_MP3).sendToTarget();}}}});}//自定义下载事件监听器public interface OnDownloadListener {public void onDowload(String mp3Url);public void onFailed(String error);}
}

Android开发本地及网络Mp3音乐播放器(十五)网络音乐及歌词下载功能实现相关推荐

  1. Android音乐播放器(五)音乐的搜索实现

    这是去年大二做的一个简单音乐播放器项目:是尽可能模仿酷狗音乐写的,具体实现的功能如下: 1:启动动画:点击运行程序会出现一个两秒钟的视频,类似酷狗音乐的启动动画一样,非常可观! 2:登录注册界面:输入 ...

  2. Android开发本地及网络Mp3音乐播放器(十四)网络音乐下载功能实现

    实现功能: 实现网络音乐搜索功能 实现网络音乐下载功能 下载好的音乐目前不在播放器内,可以通过文件浏览器查看. 后续将博文,将实现歌词和下载音乐扫描功能. 经过将近4天,才发布这一篇博客,明显更新博客 ...

  3. 手把手教你做音乐播放器(五)音乐列表的存储(上)

    第5节 播放列表的存取 关于播放列表的存取需要三个组件的协同配合, MusicListActivity:让用户选择多首或一首音乐,将用户的选择项,传递给MusicService: MusicServi ...

  4. Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51290181 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 实现NetM ...

  5. android 音乐播放器ui界面设计音乐播放器毕业设计。Android studio编译,项目有源码和apk

    使用Android Studio开发一个简易的音乐播放器 界面图: 视频展示: android 音乐播放器ui界面设计音乐播放器毕业设计.Android studio编译 项目下载: android音 ...

  6. 用Qt写一个简单的音乐播放器(六):显示歌词(正则表达式)

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

  7. 计算机弹音乐百度,百度音乐播放器电脑版怎么制作歌曲歌词?

    现在很多朋友都在使用百度音乐播放器,那么在使用百度音乐播放器播放音乐的时候.音乐没有歌词应该怎么办呢?可以使用百度音乐播放器来制作歌词哦,但是很多人都不知道百度音乐播放器电脑版怎么制作歌曲歌词?下面小 ...

  8. 开源音乐播放器_使用开源音乐播放器设计生活中的配乐

    开源音乐播放器 我们围绕着自己的个人配乐. 我们的音乐让我们想起了人生中最重要的时刻,并帮助我们塑造了自己的感受和看法. 让音乐播放器支持自由选择音乐的播放方式,同时又不影响播放质量非常重要,而且我一 ...

  9. 用Qt写一个简单的音乐播放器(五):歌曲播放时间显示

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

最新文章

  1. android 自定义录像机,android-camera2 - 将自定义捕获请求构建器选项设置为使用Camera2 API捕获图像以使用OpenCV库进行摄像机校准 - 堆栈内存溢出...
  2. 安装CDH5时出错 5.68.168.192.in-addr.arpa domain name pointer bogon.
  3. sklearn中的回归决策树
  4. python装饰器功能是冒泡排序怎么做_传说中Python最难理解的点|看这完篇就够了(装饰器)...
  5. spring4.0之三:@RestController
  6. github 公钥 私钥_ubuntu git生成ssh key (公钥私钥)配置github或者码云
  7. python中常见的流程_Python面试中最常见的25个问题-结束
  8. Android之给控件添加水纹波效果
  9. mysql 外键_为什么大多数互联网公司不用外键约束
  10. 声纹识别PLDA模型的理解
  11. js调用android手写输入法,手机进入页面,js调取软键盘
  12. 图书管理系统c++_校园一卡通学生如何使用,图书馆分系统演示步骤,系统间资源共享...
  13. 虚拟化整合实现1+1大于2的效果
  14. 区块链相关名词解释(一)
  15. Android网络多线程断点续传下载
  16. android平板电脑 刷机工具,安卓平板电脑刷机教程之一键刷机.pdf
  17. 实验matlab滤波器心得,数字信号处理,实验,Matlab实验FIR滤波器实现
  18. QT 字符乱码的原因
  19. python3 模块 public缀_Python publicsuffixlist包_程序模块 - PyPI - Python中文网
  20. 16进制数组和ASK码字符之间的转换

热门文章

  1. Linux命令之复制文件或目录cp
  2. 经典机器学习算法:高斯判别分析GDA
  3. 辰颐物语系统(开发、奖励规则)
  4. cf1149E. Election Promises
  5. 我国计算机领域研究的状况文档,计算机应用现状与发展趋势.doc
  6. Linux内核源码分析--文件系统(九、File_dev.c)
  7. 饥荒联机版 服务器未响应,饥荒联机版常见问题汇_饥荒联机版常见问题大全_快吧单机游戏...
  8. 究极方法!!!CSDN图片上传失败无法重新上传和删除的解决
  9. 抛弃传统IPO,直接上市,你准备好了吗?
  10. 科技公司将跳过IPO直接接受机构融资