2021.1.18 更新
持续更新,仅供学习使用,请勿传播安装包
我一直在更新呀!
Github 地址:https://github.com/Moriafly/DsoMusic
开源不易,求个 Star
Dso Music(名字瞎取的)目前主要实现的是网络音乐的播放(本地的还在构思),主要用 Kotlin 编写(刚刚学安卓不久,代码不咋地),先看下界面(主要仿网易云
):
下面的播放栏用了 BlurView
用了Glide 和转换。播放 / 暂停、上一曲和下一曲按钮色彩来自封面的主题色。实现了美观的界面。
来源网易云音乐和 QQ 音乐
网易云的实现来自项目(不限于):https://github.com/Binaryify/NeteaseCloudMusicApi
QQ 音乐曲库的获取是自己实现的。
下面讲下方法:
这个比较简单
// 传入 keywords,访问这个链接直接获取
https://c.y.qq.com/soso/fcgi-bin/client_search_cp?aggr=1&cr=1&flag_qc=0&p=1&n=20&w=${
keywords}
注:只能听网页版 QQ 音乐的歌,有些需要下载客户端才能听的歌的链接这里获取不到
第一步:得到歌曲的 songmid,这个搜索返回的 json 数据里面有
第二步:传入 songmid,请求这个地址
val url = """https://u.y.qq.com/cgi-bin/musicu.fcg?g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"8348972662","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"8348972662","songmid":["${
songmid}"],"songtype":[1],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":24,"cv":0}}""".trimIndent()
会返回 json 数据,含 ip 地址和 purl。用 Gson 或其他的解析。ip 是在 ReqData -> data -> freeflowip 其中任何一个就行,purl 是在 Req_0Data -> data -> midurlinfo -> purl。
最后的歌曲链接就是:ip + purl
使用的 https://binaryify.github.io/NeteaseCloudMusicApi,十分全。
请求歌单,获取全部 trackIds ,再 Post 请求所有歌曲。(我自己测试每次最多返回 201 首,可以对全部对 ID 做分割,分页请求)
不过对于上千首的歌单,瞬间发送很多请求,很可能会被网易云封 ip,服务器会返回 -460 cheating。需要搞 ip 代理。
调用系统均衡器需要 audioSessionId。音乐播放用的是 MediaPlayer,获取 audioSessionId 的方法:
mediaPlayer.audioSessionId
调用系统均衡器
/**
* 打开系统均衡器
*/
fun openEqualizer(activity: Activity, audioSessionId: Int) {
try {
// 启动一个音频控制面板
// 参考 https://www.cnblogs.com/dongweiq/p/7998445.html
val intent = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL)
// 传入 AudioSessionId
intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioSessionId)
// 调用应用程序必须使用 startActivityForResult 方法启动控制面板,以便控制面板应用程序指示其包名称并用于跟踪此特定应用程序的更改
activity.startActivityForResult(intent, 666)
} catch (e: Exception) {
// 不支持
}
}
已经完成。具体看 Github 代码。
参考博客:https://blog.csdn.net/Moriafly/article/details/109708597