作為一個豆瓣fm的忠實使用者,被豆瓣fm與音樂不期而遇的理念深深吸引。 最近豆瓣推出升級到PRO享受更高品質音樂的服務,升級後確實品質提升明顯。但是有個功能仍然沒有提供,那就是無法下載喜歡的歌曲。 在對豆瓣fm網頁經過一番研究之後,決定做個下載當前歌曲的Chrome外掛程式,只是方便自己下載喜歡的音樂,不喜勿入。
第一步:找到資源
用chrome的開發人員工具開啟douban.fm首頁,通過chrome開發人員工具中的Network可以查看所有的資源,其中包括.mp3檔案。 在看看豆瓣播放器是個flash,ok了,flash通過http協議來get音頻檔案。
第二步:擷取當前播放歌曲的URL
第一步中我們瞭解到,豆瓣的flash音樂播放器直接通過http get方法擷取資源,因此我們無法直接得知flash內部現正播放的檔案地址,我們只好通過chrome extension的chrome.webRequest.onBeforeRequest.addListener 事件來監視所有的http request, 所以一旦後台監聽程式發現新的.mp3請求就告知頁面更新。 但chrome extension的頁面和背景通知機制是頁面主動詢問chrome後台。 所以也就需要更多的代碼來實現這個簡單的功能。在這裡我們在後台註冊與頁面的通訊事件, 這個事件,一旦有頁面訊息傳遞給後台,在後台中註冊的方法將會被調用:chrome.extension.onMessage.addListener(function (request, sender, sendResponse){// dosomething;} );
頁面通過 chrome.extension.sendMessage({from:"douban.fm"}, function (response) {//dosomething}); 來和後台通訊,其中第一參數用來指明請求的頁面。
還有一個後台事件很有用,chrome.webRequest.onHeadersReceived.addListener(function (details) {//dosomething},....), 這個事件發生在http reponse header 達到時,可以用來做一些小事情,比如說修改音頻儲存時使用的名字。代碼如:
chrome.webRequest.onHeadersReceived.addListener(function (details) {
if(details.url.indexOf(".mp3?douban=")!=-1){
response =details;// for debugging
for (i = 0; i < details.responseHeaders.length; i++) {
if(details.responseHeaders[i].name.toLowerCase() == "content-type"){
details.responseHeaders[i].value= "application/x-please-download-me";
}
}
details.responseHeaders.push({name:"Content-disposition",value:"attachment; filename="+tab.title.substring(0, tab.title.lastIndexOf('-')-1)+ ".mp3"});
}
return {
responseHeaders : details.responseHeaders
};
}, {
urls : ["<all_urls>"],
types : ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
},
["blocking", "responseHeaders"]);
第三步:建立頁面下載串連
用Js在頁面上添加一個下載的連結,通過這個連結就可以把當前的播放的mp3檔案下載, 為了在能當面頁面下載我們嵌入一個隱藏的iframe.
全部代碼:https://github.com/darlinglele/extensions/tree/master/fm