折腾过 Foobar2000 的人可能知道,Foobar2000 有一款叫做 foo_httpcontrol 的远程控制插件。
同时,有爱好者根据这个插件提供的接口,写出了使用手机控制 Foobar2000 的 Android 应用程序。
于是,做一个远程控制网易云音乐程序的想法就诞生了。
考虑到自己一时半会写不出像 foobar2000 controller 这样的 Android 应用程序,于是考虑借用这一套 API 格式实现一个兼容的控制服务端。
第一步是偷到插件暴露的 HTTP API。这里有个小坑:foo_httpcontrol 不同模板有不同的 API,于是干脆直接从 Android 这边抓。
咱用 CherryPy 写了个原始 API 的 “反代”。代码大概就是下面这些:
import cherrypy
import requests
class FoorbarAPI(object):
@cherrypy.expose
def index(self):
return "OK"
@cherrypy.expose
def foobar2000controller(self, cmd="", param3="", param1=""):
url = "http://pass:[email protected]:6939/foobar2000controller"
target_url = "%s?cmd=%s¶m1=%s¶m3=%s" % (url, cmd, param1, param3)
result = requests.get(target_url)
res_content = result.content
print(res_content)
return res_content
if __name__ == '__main__':
cherrypy.server.socket_host = '0.0.0.0'
cherrypy.quickstart(FoorbarAPI())
通过一个个尝试,摸清楚了大部分被调用的 API,大概就是以下这些:
连接测试
/foobar2000controller/?cmd=FormatTitles
读取当前信息
/foobar2000controller/?param3=info.json
读取当前专辑图片,此API从读信息的API中提取拼接,加上 .jpg 或 .png
/foobar2000controller/albumart_6010
切换暂停播放状态
/foobar2000controller/?cmd=PlayOrPause
重新播放当前歌曲
/foobar2000controller/?cmd=Start¶m1=
播放下一首
/foobar2000controller/?cmd=StartNext¶m1=
播放上一首
/foobar2000controller/?cmd=StartPrevious¶m1=
音量控制
/foobar2000controller/?cmd=Volume¶m1=65
读取歌曲类型列表
/foobar2000controller/?cmd=QueryRetrace¶m3=library.json
读取当前播放文件路径
/foobar2000controller/?cmd=FormatTitles¶m1=%25path%25
播放列表
/foobar2000controller/?param3=playlist.json
然后就是用 CherryPy (纯粹是顺手)实现一个了兼容的 API 服务程序。
程序源码:
可以在这个链接找到,使用 MIT License 授权分发。
功能实现大概是这样做的:
- 歌曲播放状态切换(开始、暂停、前一曲、后一曲) - win32api.keybd_event
- 音量调整及音量数值读取 - pycaw
- 歌曲信息 - 读取 %APPDATA% 目录下的 JSON 文件(详见程序实现)
- 获取当前播放歌曲 -读取程序窗体标题(详细看这个项目)
还在实现中的功能(就是懒得写):
- 实现播放列表显示(代码写好了还没检查合并)
- 结合 TagLib 通过本地歌曲完善歌曲信息识别(TagLib 编译不来,暂时咕咕)
- 封面抓取校验完整性(下次有空再填)
- 实现进度条读取(肝不动)
- 实现播放状态检测(同上咕咕咕)
- 实现点击播放列表切换歌曲(无限期咕咕)
程序依赖安装:
pip install cherrypy psutil requests pymediainfo pywin32 pycaw
其中 pycaw 应该要这么装
pip install https://github.com/AndreMiras/pycaw/archive/master.zip
还有几个需要注意的
pywin32 应该要自己找预编译安装包搞定
pymediainfo 需要自己放一个 MediaInfo.dll (与Python的编译架构相同)放在环境变量目录里
程序同目录或者环境变量里得有一个能用的 curl,用来下载封面图
程序同目录下要有一个 covers 文件夹,用来存图片缓存