由http://blog.csdn.net/wusuopubupt/article/details/21083775得到的启发,在周末自己抽空也做了一个插件,也顺便补充一下po主的教程。
准备工作:正如http://blog.csdn.net/wusuopubupt/article/details/21083775提及,我们需要JavaScript开发基础,chrome插件开发基础,本人第一次开发chrome插件,所以首先恶补了一上午,再者我们还需要知道从哪里根据歌曲名和歌手名获取歌词,感谢po主给我们推荐了http://geci.me/api/lyric/,这个好用的接口,我们可以在url后加上‘歌曲名/歌手名’从而获得歌词的json信息。如下是http://geci.me/api/lyric/listen,得到的信息:
{
"count": 8,
"code": 0,
"result": [
{
"aid": 2574902,
"lrc": "http://s.geci.me/lrc/306/30660/3066099.lrc",
"song": "Listen",
"artist_id": 2762,
"sid": 3066099
},
{
"aid": 1814321,
"lrc": "http://s.geci.me/lrc/200/20048/2004871.lrc",
"song": "Listen",
"artist_id": 15735,
"sid": 2004871
},
{
"aid": 2741204,
"lrc": "http://s.geci.me/lrc/329/32975/3297582.lrc",
"song": "Listen",
"artist_id": 25266,
"sid": 3297582
},
{
"aid": 3232739,
"lrc": "http://s.geci.me/lrc/395/39566/3956629.lrc",
"song": "Listen",
"artist_id": 32473,
"sid": 3956629
},
{
"aid": 2922563,
"lrc": "http://s.geci.me/lrc/354/35450/3545085.lrc",
"song": "Listen",
"artist_id": 34747,
"sid": 3545085
},
{
"aid": 3003590,
"lrc": "http://s.geci.me/lrc/365/36514/3651490.lrc",
"song": "Listen",
"artist_id": 34747,
"sid": 3651490
},
{
"aid": 3182564,
"lrc": "http://s.geci.me/lrc/388/38895/3889558.lrc",
"song": "Listen",
"artist_id": 35285,
"sid": 3889558
},
{
"aid": 3131255,
"lrc": "http://s.geci.me/lrc/382/38223/3822392.lrc",
"song": "Listen",
"artist_id": 39213,
"sid": 3822392
}
]
}
此外,我们需要知道如何获得豆瓣电台当前歌曲信息,感谢po主的发现,我们可以在localstorage中找到歌曲名和歌手名,如下图所示
好了,准备工作做好了,进入正题吧。我们这次是开发基于page_action的chrome插件,不知道的同学,可以上chrome插件开发文档看看。
以下是本项目的文件结构:
开发插件第一步是写manifest.json
{
"name": "Douban FM Lyric",
"version": "1.0",
"manifest_version": 2,
"description": "The lyric extension of the douban.fm",
"page_action": {
"default_icon": "img/icon.jpeg",
"default_title": "Dave's Douban FM lyric"
},
"background": {
"scripts": ["js/background.js"]
},
"content_scripts": [
{
"matches": ["http://douban.fm/*"],
"js": ["js/jquery-1.11.0.min.js", "js/lyrics.js"],
"runat": "document_end"
}
],
"permissions": [
"tabs", "http://douban.fm/*", "http://geci.me/api/lyric/*","http://*.geci.me/*"
]
}
content_scripts和permissions比较重要,规定了本插件匹配的页面以及需要访问的网站。
第二步,content_scripts,插件与豆瓣电台主要交互是在lyrics.js,以下所有代码都在lyrics.js里。
创建Song伪类,定义属性:
function Song(id, name, artist) {
this.id = id;
this.name = name;
this.artist = artist;
this.lyricUrl;
this.lyric = this.addLyric();
}
添加伪类方法,定义歌词div,嵌入电台页面。
Song.prototype.addLyric = function () {
var lyrics_div=document.createElement('div');//用document.createElement()方法可以创造新的节点
document.body.appendChild(lyrics_div);//用document.body.appendChild()方法把新的节点附加到到document中
lyrics_div.style.width = '900px';//下面几行是设置css
lyrics_div.style.backgroundColor = '#F00';
lyrics_div.style.zIndex = '42';
lyrics_div.style.position = 'relative';
lyrics_div.style.margin = '200px auto 0';
lyrics_div.id = 'lyricParent';
lyrics_div = $('<div id="myLyric" style="width: 490px;height: 280px;background-color: #9dd6c5;position: absolute;right: 0;overflow: auto;display: block;font-size: 14px;padding: 10px;"></div>')
$('div#lyricParent').append(lyrics_div);
return lyrics_div;
}
Ajax获取歌词url,首先用歌曲名+歌手名准确查找歌词,如果没有,去掉歌手名再查找一次。
Song.prototype.getLyricUrl = function () {
var withAritist = false;
if (this.name == undefined || this.name == null || this.name == '') return '';
var url = 'http://geci.me/api/lyric/' + this.name;
if (!(this.artist == undefined || this.artist == null || this.artist == '')) {
url += '/' + this.artist;
withAritist = true;
}
this.ajaxLyricUrl(url, withAritist);
}
Song.prototype.ajaxLyricUrl = function (url, withAritist) {
var song = this;
$.ajax({
url: url,
method: 'GET',
success: function (data) {
console.log(data);
var count = data.count;
console.log(count);
if (count > 0) {
song.lyricUrl = data.result[0].lrc;
song.getLyric();
} else {
if (withAritist) {
url = url.substring(0, url.lastIndexOf("/"));
song.ajaxLyricUrl(url, false);
} else
song.printLyric('找不到歌词');
}
},
error: function () {
return undefined;
}
})
}
Ajax获取歌词,把时间信息去掉,把换行符替换成\n<br>
Song.prototype.getLyric = function () {
var url = this.lyricUrl;
var song = this;
$.ajax({
url: url,
method: 'GET',
success: function (data) {
//将时间信息去掉,g全局符号,把所有匹配字符串替换
data = data.replace(/\[.*\]/g, '').trim();
data = data.replace(/\n/g, '\n<br>');
song.printLyric(data);
}
})
}
打印歌词
Song.prototype.printLyric = function (text) {
this.lyric.html(text);
}
接着,我们给页面嵌入一个Song对象以及一个保存上一首歌的id的变量,其中我监听了豆瓣电台的频道滚动事件,因为我发现频道的滚动好像拦截了该页面所有滚动事件,如果不添加该监听,我们没办法在歌词div里使用滚轮,虽然可以看到滚动条,但是相当不爽啊。即使这样,歌词滚动的实现也不好,因为有时歌词太长,无法滚动到最后一行,只能用滚动条拖动,这对于MacBook使用者简直不能忍,触摸板就像废了一样,希望大家给出更好地建议。
var lastSongId = '', song;
$(document).ready(function () {
eval('var data=' + localStorage['bubbler_song_info']);
song = new Song(data.id, data.song_name, data.artist);
$("div#fm-channel-list").scroll(function () {
var offsetTop = $(this).scrollTop();
$("div#myLyric").scrollTop(offsetTop);
});
})
最后,我们需要创建一个定时器,每2秒检查一下,是不是换歌了,因为电台使用flash插件进行播放的,所以无法直接从页面实时获取歌曲变化情况,只能不断检查localstorage变化情况,蛋疼。。。
window.setInterval(function () {
eval('var data=' + localStorage['bubbler_song_info']);
if (lastSongId != data.id) {
lastSongId = data.id;
song.setId(data.id);
song.setArtist(data.artist);
song.setName(data.song_name);
song.getLyricUrl();
}
}, 2000);
插件运行效果:
至此,主要代码已经写完,虽然写得有点复杂,不过最后实现了在别人页面嵌入自己代码还是蛮有成就感的,以后还会开发更多更有用的插件,谢谢,希望本博文对大家有帮助。
代码和打包后的插件下载地址:http://download.csdn.net/detail/xanxus46/7127063
插件安装:
首先打开扩展程序页面:
然后把下载压缩包里的douban lyric.crx拖到扩展程序的页面里安装,然后打开豆瓣就能看到效果了。