如何为豆瓣FM写一个chrome的歌词插件

对于喜欢豆瓣FM的同学来说,没有歌词是件令人苦恼的事,下面我就来总结下怎样为豆瓣FM写一个chrome的歌词插件。

---------------------------------

1.需要的技能

首先,你要会javascript,其次你要掌握一点chrome的hack,最后要有一个可以根据歌曲名查到歌词的API。


2.localStorage

localStorage与cookie类似,它是存储在客户端浏览器中的数据,它与cookie不同的一点是它没有时间限制。localStorage属于html5中的新特性。因为我们要做chrome的插件,所以按F12弹出开发者模式,点击resource,就可以看见localstorage选项了,通过localStorage,我们可以得到当前豆瓣播放的歌曲的id,歌曲名,演唱者等信息:


3.歌词迷的API

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 请求地址: http://geci.me/api/lyric/:song  
  2. 返回格式: JSON  
  3. 请求方法: GET  
  4. 示例:   
  5. curl 'http://geci.me/api/lyric/海阔天空'  

返回:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. {  
  2.     "count": 15,  
  3.     "code": 0,  
  4.     "result": [  
  5.         { "aid": 2848529, "lrc""http://s.geci.me/lrc/344/34435/3443588.lrc""sid": 3443588, "artist_id": 2, "song""\u6d77\u9614\u5929\u7a7a" },  
  6.         { "aid": 2346662, "lrc""http://s.geci.me/lrc/274/27442/2744281.lrc""sid": 2744281, "artist_id": 2396, "song""\u6d77\u9614\u5929\u7a7a" },  
  7.         { "aid": 1889264, "lrc""http://s.geci.me/lrc/210/21070/2107014.lrc""sid": 2107014, "artist_id": 8715, "song""\u6d77\u9614\u5929\u7a7a" },  
  8.         { "aid": 2075717, "lrc""http://s.geci.me/lrc/236/23651/2365157.lrc""sid": 2365157, "artist_id": 8715, "song""\u6d77\u9614\u5929\u7a7a" },  
  9.         { "aid": 1563419, "lrc""http://s.geci.me/lrc/166/16685/1668536.lrc""sid": 1668536, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  10.         { "aid": 1567586, "lrc""http://s.geci.me/lrc/167/16739/1673997.lrc""sid": 1673997, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  11.         { "aid": 1571906, "lrc""http://s.geci.me/lrc/167/16796/1679605.lrc""sid": 1679605, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  12.         { "aid": 1573814, "lrc""http://s.geci.me/lrc/168/16819/1681961.lrc""sid": 1681961, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  13.         { "aid": 1656038, "lrc""http://s.geci.me/lrc/179/17907/1790768.lrc""sid": 1790768, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  14.         { "aid": 1718741, "lrc""http://s.geci.me/lrc/187/18757/1875769.lrc""sid": 1875769, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  15.         { "aid": 2003267, "lrc""http://s.geci.me/lrc/226/22642/2264296.lrc""sid": 2264296, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  16.         { "aid": 2020610, "lrc""http://s.geci.me/lrc/228/22889/2288967.lrc""sid": 2288967, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  17.         { "aid": 2051678, "lrc""http://s.geci.me/lrc/233/23323/2332322.lrc""sid": 2332322, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  18.         { "aid": 2412704, "lrc""http://s.geci.me/lrc/283/28376/2837689.lrc""sid": 2837689, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" },  
  19.         { "aid": 2607041, "lrc""http://s.geci.me/lrc/311/31116/3111659.lrc""sid": 3111659, "artist_id": 9208, "song""\u6d77\u9614\u5929\u7a7a" }  
  20.     ]  
  21. }  

4.重头戏----javascript脚本


有了上面的准备工作,我们现在就可以安心的编码了。

首先,创建一个DoubanFM伪类(javascript中没有“真正的”类)

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. funciton DoubanFM() {  
  2.     this.name = '豆瓣FM';  
  3.     this.tmp_song_id = '';  
  4.     this.flag = 1;  
  5.     this.lyrics = this.draw_lyrics();  
  6. }  
然后,对这个伪类拓展原型,创建新的函数:

【注】关于javascript拓展函数原型,我原来写过一篇博客:http://blog.csdn.net/wusuopubupt/article/details/14520209 


用javascript创建新的节点(一个显示歌词的div,同时设置div的css):

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. DoubanFM.prototype.draw_lyrics = funciton() {  
  2.     var lyrics_div = document.createElement('div');//用document.createElement()方法可以创造新的节点  
  3.     document.body.appendChild(lyrics_div);//用document.body.appendChild()方法把新的节点附加到到document中  
  4.     lyrics_div.style.width = '900px';//下面几行是设置css  
  5.     lyrics_div.style.backgroundColor = '#F00';  
  6.     lyrics_div.style.zIndex = '42';  
  7.     lyrics_div.style.position = 'relative';  
  8.     lyrics_div.style.margin = '200px auto 0';  
  9.       
  10.     return lyrics_div;  
  11. }  

根据localstorage里获取的信息,构造获取歌词的url:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. DoubanFM.prototype.geci_entry_url = function(song, artist) {  
  2.     if (song == undefined || song == null || song == ''return '';  
  3.     var url = 'http://geci.me/api/lyric/' + song;  
  4.     if (!(artist == undefined || artist == null || artist == '')) {  
  5.         url += '/' + artist;  
  6.     }  
  7.     console.log(url);  
  8.     return url;  
  9. }  

用AJAX方式异步请求歌词:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Douban.prototype.request_geci = function() {  
  2.     eval('var stored_song = ' + localStorage['bubbler_song_info']);//这里是重点,localstorage!  
  3.     console.log('the song in localStorage:' + stored_song.artist + ' ' + stored_song.song_name);  
  4.     if (this.tmp_song_id != stored_song.id) {  
  5.         console.log(this.tmp_song_id + ' is not ' + stored_song.id);  
  6.         var url = this.geci_entry_url(stored_song.song_name, stored_song.artist);  
  7.         this.tmp_song_id = stored_song.id;  
  8.         this.ajax_get(url);  
  9.     }  
  10. }  

ajax请求:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. DoubanFM.prototype.ajax_get = function(url) {  
  2.     var XHR = new XMLHttpRequest();  
  3.     var obj = this;  
  4.     //一次典型的原生js发起的AJAX请求  
  5.     XHR.onreadystatechange = function() {  
  6.         if (XHR.readyState == 4) {  
  7.             if (XHR.status == 200) {  
  8.                 obj.deal_response(XHR.responseText);  
  9.             } else {  
  10.                 obj.print_lyrics('获取歌词失败');  
  11.             }  
  12.         } else {  
  13.             obj.print_lyrics('歌词搜索中');  
  14.         }  
  15.     }  
  16.       
  17.     XHR.open('GET', url, true);  
  18.     XHR.send();  
  19. }  
  20.   
  21. DoubanFM.prototype.deal_response = function(data) {  
  22.     if (this.flag == 1) {  
  23.         eval('var resp = ' + data);  
  24.         if (resp.count > 0) {  
  25.             this.ajax_get(resp.result[0].lrc);  
  26.             this.flag++;  
  27.         } else {  
  28.             this.print_lyrics('没有找到歌词');  
  29.         }  
  30.     } else {  
  31.         this.print_lyrics(this.format(data));  
  32.         this.ajax_flag = 1;  
  33.     }  
  34. }  


对返回的歌词做处理:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. DoubanFM.prototype.format = function(text) {  
  2.     var s = text.replace(/\[(.*)\]/g, '').trim();//去除返回数据的[]两端的内容,只保留歌词部分  
  3.     return s.replace(/\n/g, '\n<br />');//每行末尾输出html的换行符  
  4. }  

把format过后的歌词显示在上面用document.createElement()方法创建出来的div中:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. DoubanFM.prototype.print_lyrics = function(text) {  
  2.     this.lyrics.innerHTML = '<div id="mylrc" style="width: 490px; max-height: 280px; padding:10px; background-color: #9dd6c5; z-index: 42; po<span style="white-space:pre">  </span>sition: absolute; right: 0; overflow-x: hidden; overflow-y: scroll; display: block;">'+ text +'</div>';  
  3. }  


最后,用setInterval()方法,每隔一秒执行就获取歌词的方法,实现豆瓣FM歌词的更新和显示:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var  fm = new DoubanFM(true);  
  2. window.setInterval(function() { fm.request_geci(); }, 1000);  

至此,javascript的工作就完成了。


5.还需要什么?


写一个chrome的插件,你还需要一个manifest.json文件,类似这样:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. {  
  2.     "name" : "Douban FM 歌词",  
  3.     "version" : "1.0",  
  4.     "manifest_version" : 2,  
  5.     "description" : "Douban FM Lrc",  
  6.       
  7.     "page_action" : {  
  8.       "default_icon" : "icon.png",  
  9.       "default_title" : "Douban FM 歌词"  
  10.     },  
  11.   
  12.     "permissions" : ["tabs""http://douban.fm/""http://*.geci.me/*"],  
  13.     "background" : {"scripts" : ["background.js"]},  
  14.     "content_scripts" : [{  
  15.         "matches" : ["http://douban.fm/"],  
  16.         "js" : ["lyrics.js"],  
  17.         "runat" : "document_end"  
  18.     }],  
  19.     "icons" : {  
  20.         "48" : "icon-48.png",  
  21.         "128" : "icon-128.png"  
  22.     }  
  23. }  

还需要几个不同size的icon,类似这样:

 

最后,到chrome的拓展程序(直接在地址栏输入:chrome://extensions/),选择“打包拓展程序”,然后把我们的整个程序的文件夹选中,即可生成一个.crx文件,拖进chrome,即可安装。

:如果你想好好学下如何制作chrome的拓展,可以看这篇文章:http://www.cnblogs.com/walkingp/archive/2011/03/31/2001628.html


6.最后的效果


在我们的拓展程序中,可以看到:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值