时雨小径 May the Spirit be with you

通过豆瓣电台搭建自己的音乐仓库

这个是一个已经YY很久的事情了, 豆瓣电台很好, 刚出Pro服务的时候我立刻就冲了半年的会员, 可以有192kbps的音质. 不过音质什么的我觉得都不是最重要的, 主要是后面巨大的数据量比较吸引我, 尤其是歌曲的标签信息, 比较合适用来做群聚算法的测试. 一个比较可惜的事是豆瓣不能提供所以的个人音乐收听记录, 只有一个星期内的数据, 我觉得挺这点挺龟毛的, 这么点数据又用不了多少空间, 不知道是真的没有储存还是不给接口, 显然后者的可能性比较大.

花了两天算是写完了这个小项目, 由两部分组成, 一个是Chrome的插件, 一个就是服务器上一些对应的处理请求的页面以及前端. 总的来说过程还是充满趣味与收获的.

DEMO

如图:
p1

其实基本上需要的信息都已经上传到数据库了, 主要就是歌曲, 对应的专辑信息, 还有豆瓣上的标签信息. 现在的前端显示的信息有限, 完全没有体现出那些数据的作用, 方案还在构思中.
其中的via douban.fm链接可以直接转到对应歌曲在douban.fm上的页面, 这个比较简单, 因为douban.fm本身就提供了分享歌曲的功能, 所以这个只是简单的抓链接.

在右边可以看到一个耳机和一个红心, 红心显然就是douban.fm上的喜欢, 通过插件实现了当我在doubam.fm上点了喜欢后同步更新到自己的数据库里, 同样取消喜欢也是.

而耳机这个其实有一点点不完美, 因为通过一些途经我已经可以由歌曲的id来获取对应的mp3地址, 所以原来的设想是一个在当前页面直接试听的链接(直接一点说就是盗链), 用一个html5的audio来实现. 可惜豆瓣对mp3的请求作了限制, 会检查request header里referer, 不符合要求的会返回403, 所以这个也只能在插件配合下才能实现当前页面播放对应歌曲, 也就是只有装了相应插件的人才可以用= =. 这个插件其实也没做什么..只是每次在发mp3的请求时, 把header里的referer给删了就可以了, 实现这个功能的代码就几行:

var regexMP3link = /http[s]?://[a-z0-9]*.douban.com[^.]*.mp3/; 

chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
     if (details.url.match(regexMP3link) != null){ 
        for (var i = 0; i < details.requestHeaders.length; ++i) {
          if (details.requestHeaders[i].name === 'Referer') {
            details.requestHeaders.splice(i, 1);
            break;
          }
        }
        return {requestHeaders: details.requestHeaders};
    }
  },
  {urls: [
      "http://*.douban.com/*",
      "http://douban.fm/*"
    ]   },
  ["blocking", "requestHeaders"]
);

(本来还想弄个下载链接的, 怕惹麻烦.. 而且MP3文件都是没标签的, JS又不能写ID3, 就没弄了, 真要抓MP3还是python方便, 下载ID3一炮搞定, 都不用去找封面了 )

打算记下写这个的过程中主要碰到的东西: (先把坑挖起来…两个差不多了, 嗯)

浅析douban.fm的HttpRequest (蓄势待填)

关于Chrome extension的一些奇葩应用 (蓄势待填)