HammerSpoon - 实现音乐播放的全局键盘控制

原文链接:http://singsing.io/blog/2016/12/11/HammerSpoon-2/

关于 HammerSpoon 的基本介绍,请参考我的上一篇博文
关于本文中提到的 VOX,请点这里

概述

由于地区限制和版权原因,不得不忍痛割爱网易云音乐。从那之后便开始寻找一款 MacOS 上适合自己的播放器

先说说本篇博客的主角,VOX。作为一个颜控,第一眼确实被它的外观吸引:

vox-example.jpg

同时,他们提供一个叫 LOOP 的音乐服务,可以简单理解为音乐云盘。用户可以把自己的歌曲上传到 LOOP 提供的云空间,然后就可以通过云或者下载到本地播放了。这个空间是 "没有上限的!!!".repeat(3),至少现在是这样

另外,如果你的 iTunes 有珍藏多年的音乐,VOX 一样可以读取出来,无缝同步,这个功能并不需要付费
通过一段时间的调查,做了一个价格、服务方面的横向对比,分享给大家,如有错误欢迎指正:

名称 价格 (美元/月) 试用 在线/跨平台 格式支持 无损支持
VOX (LOOP) $10.99 ~ $15.99 15天免费 通过 VOX Free/只支持 MacOS 和 iOS 绝大部分格式 是,需用户上传
Apple Music $9.99 3个月免费 是/需要 iTunes AAC, MP3 否,但接近无损
Spotify $9.99 $0.99 三个月试用 是/全平台 320K MP3 (Spotify Premium)
Google Play Music $9.99 30天免费 是/全平台 MP3 否,上传无损会转为 320K MP3
TIDAL $9.99/$19.99 30天免费 是/不支持 Windows FLAC, MP3 需要购买 $19.99 的服务
Deezer $9.99/$14.99 30天免费 是/全平台 MP3 需要第三方硬件
Clementine 免费,开源 N/A 否/全平台 绝大部分格式 是,需用户上传 (支持 Dropbox,Spotify 等)
foobar2000 免费,开源 N/A 否/Windows, 安卓,iOS 绝大部分格式 是,需用户上传
  • Foobar2000 就不用说了,懂的人自然懂,可惜没有 Mac 版,这款软件一直都是资深音乐爱好者首推的神器
  • Clementine 则胜在全平台兼容,以及可以读取 Dropbox 之类的网盘,当然前提是你的网盘空间得足够大 (好像不支持百度云。。)
  • Deezer 和 TIDAL 一样,提供在线的无损音乐播放。虽然他们宣称的总歌曲数比 Google Play 和 Apple Music 都要多,但中文歌曲数量还是太少了。另外,Deezer 需要第三方的硬件 SONOS 才能提供无损音乐播放服务
  • Google Play 其实中文歌不少。当然,肯定是不全的,至于一些小众的歌曲就别指望找到了。播放器网页版中规中矩,本地版,能用肯定是能用,但颜控估计是不会喜欢的
  • Spotify,付费用户可以选择高音质,也即是 320K MP3,并不提供无损。其实 Spotify 界面还是不错的,而且跨平台性非常好,甚至 PS4,Bose 音箱都支持
  • Apple Music 用起来着实方便,和系统的结合度倒是值得一提,比如,你可以用在 iTunes 找到的歌来当闹钟铃声。英文歌资源非常多,从大众的 Taylor Swift 到小众的 Mono Inc,Bullet For My Valentine 都有,新砖也能找到。中文歌曲方面和 Google Play 差不多,不少,但称不上全(至少很多我爱听的歌没有)。顺便,iTunes 其实支持 FLAC 或者 APE 格式的播放,只是需要安装插件

HammerSpoon + Whatever

软件,没有最好的,只有最适合的

篇幅有限,不得不开启下一个话题。对播放器方面有问题的朋友欢迎在底下留言,大家一起讨论

HammerSpoon

上一篇博文 中已经提到,HammerSpoon 不止是窗口管理。它还可以读取系统的 API,可以执行 AppleScript。这两个特性,为我们通过键盘全局操作音乐播放提供了坚实的基础。实现全局的音乐播放控制,我们只需要 HammerSpoon 的这几个 API:

  • hs.osascript.applescript() - 执行 AppleScript。同时, hs.osascript.javascript() 也提供了执行 JavaScript 的接口
  • hs.hotkey.bind() - 既然是用键盘来控制音乐播放,那么绑定键盘快捷键的方法肯定是必不可少的
  • hs.alert - 可选,非必备。我是用这个来显示曲目信息的

AppleScript 概述

AppleScript 是苹果公司开发的脚本语言,可以用来控制 MacOS 上运行的程序,也可以写成独立的 Applet

所以,只要我们能获取到 App 的接口,就可以通过 AppleScript 让 App 来搞事情了。举个例子,比如咱们安装了迅雷,迅雷提供了一个开始下载的接口,叫 startDownload。这时候,我们只需要这样写 AppleScript:tell application "迅雷" to startDownload,然后执行,那么迅雷就可以开始下载了(事实上,迅雷并没有提供这样的接口=。=)

AppleScript 的这个语法,其实和英语表达非常接近(接近自然语言),直接翻译过来就是 告诉应用程序“迅雷”,(让它)开始下载。很好理解是不是?

App 接口

那么现在,我们只需要找到应用程序接口,就大功告成了。我们可以在系统里直接查看,步骤如下:

  1. 打开这个叫 ScriptEditor 的东西 (中文系统下叫“脚本编辑器”)
open-script-editor.jpg
  1. 然后就得到了这个界面,不用管它,点 "Done" 就好
script-editor-initialize.jpg
  1. 点击 File -> Open Dictionary,找到你想要折腾的 App,打开(注:如果这里面没有,那多半是没有文档,或者不支持,我没测试过所有 App)
open-dictionary.jpg
  1. 比如我们打开 VOX,就得到了如下的内容:
vox-api.jpg

至此,一切都变得很简单了。我们只要写这个代码 tell application "VOX" to play并执行,就可以让 VOX 播放歌曲了。同样道理,tell application "VOX" to next 就是切换到下一首歌。至于每个 API 是干什么的,文档里都有说明

当然,我们也可以用同样的方式找到不仅限于 iTunes,Spotify,iTerm,Alfred,Atom 的 API,然后写一些自己想实现的功能

与 HammerSpoon 合体

说了半天,终于到了合体的时候。用 VOX 的朋友可以直接使用我封装好的 API

基本操作

代码也变得非常简单,比如,我们想把 ctrl + j 设置为切换播放/暂停。那么只需要:

hs.hotkey.bind({"ctrl"}, "j", hs.vox.playpause())

我的代码中,在快捷键绑定部分又封装了一次而已,封装部分是这样:

local voxHyper = {"cmd", "alt", "shift"}

local function voxBindTable(keyFuncTable, hyper)
  for key,fn in pairs(keyFuncTable) do
    hs.hotkey.bind(hyper or voxHyper, key, function() fn() end)
  end
end

这个方法,首先接收一个 table(可以理解为 JS 的对象,或者,HashMap?),然后接收 HyperKey 设置。我的 HyperKey 设置为 cmd + alt + shift。然后遍历传入的 table,把每一组的 key 和回调方法绑定上

调用起来就很方便了。我把 hyper + j 绑定为切换播放/暂停,hyper + h 绑定为上一首

voxBindTable({
  j = hs.vox.playpause,
  h = hs.vox.previous,
  l = hs.vox.next,
  k = hs.vox.trackInfo,
  i = hs.vox.togglePlaylist
})

显示歌曲信息

之前提到了 hs.alert。用处就是,读取 API 获得当前曲目的歌曲信息 (歌名,演唱者以及专辑名),然后显示在屏幕上,持续 2 秒。效果如下图:

vox-track-info.jpg

代码就是上面的 hyper + khs.vox.trackInfo() 已经封装好了

显示/隐藏 播放列表

这个功能就是,类似于播放器的切换标准模式和 Mini 模式。API 已经封装成了 hs.vox.togglePlaylist(),实际效果如图:

vox-toggle-playlist.gif

不得不说的

  1. 每个应用程序的 API 不尽相同,比如我在 HammerSpoon 里封装的 hs.vox.trackInfo() 只适用于 VOX。如果你不放心,可以先在 Console 里执行一下:hs.vox.trackInfo(),然后你就会得到一个弹出的信息框
  2. 对于没有封装的,也很简单。按照上面提到的方法查 API 文档,比如 Spotify 也提供了一个叫 pause 的 API,那就可以在控制台里执行这段代码测试:hs.applescript.applescript('tell application "Spotify" to pause')。理论上会让 Spotify 暂停播放
  3. 用好控制台 * 3,可以帮你在写代码过程中省不少时间。关于一些小技巧,我会在下一篇文章中提到

写在最后

这是 HammerSpoon 的第二篇。下一篇打算聊聊全局的快捷键绑定,已经实现的功能是,类似于 VIM,通过 hyper + hjkl 的方式来实现全局的光标移动(方向键)。涉及到的事儿可能比较多,感兴趣的朋友可以先试用一下,提提意见和建议。代码在这里,文档在这里


欢迎在页面下方评论和留言。如果你喜欢这篇文章,请帮我点个赞👍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容