var ucjsNicovideoDownloader = { init: function(){ var contentAreaContextMenu = document.getElementById("contentAreaContextMenu"); // コンテキストメニューにダウンロード用のアイテム追加 this._menuItem = document.createElement("menuitem"); this._menuItem.setAttribute("label", "Download FLV/MP4"); contentAreaContextMenu.insertBefore(this._menuItem, contentAreaContextMenu.firstChild); contentAreaContextMenu.addEventListener("popupshowing", function(){ ucjsNicovideoDownloader.onPopupShowing(this); }, false); }, onPopupShowing: function(aPopup){ this._menuItem.hidden = true; // nicovideo.jp かチェック var location = content.document.location; if(location.href.indexOf("nicovideo.jp/watch/") == -1) return; // Video ID とタイトルの取得 /* var videoID = content.document.evaluate('.//object[@id="flvplayer"]/param[contains(@value,"flvplayer.swf")]',content.document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null); if(!videoID.singleNodeValue) return; videoID = videoID.singleNodeValue.value; if(!videoID.match(/flvplayer\.swf\?v=(\w+)/)) return; var videoID = RegExp.$1; */ var videoID = /nicovideo\.jp\/watch\/(\w+)/.exec(location.href)[1]; var title = content.document.evaluate('.//div/h1/a/text()',content.document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null); if(!title.singleNodeValue) return; var videoTitle = String(title.singleNodeValue.textContent); videoTitle = videoID + "." + videoTitle; videoTitle = videoTitle.replace(/[\$\*\?\"\'\/\\\:]/g, "_"); // メニューの有効化 this._menuItem.setAttribute("oncommand", "ucjsNicovideoDownloader.download('"+ videoTitle +"','"+ videoID +"')"); this._menuItem.hidden = false; }, download: function(aTitle, aVideoID){ var downloader = new ucjsNicovideoDownloader.downloader(); downloader.download(aTitle, aVideoID); } } ucjsNicovideoDownloader.downloader = function(){ this.SKIP_SELECT_PROMPT = true; } ucjsNicovideoDownloader.downloader.prototype = { download: function(aTitle, aVideoID){ this._title = aTitle; this._state = 0; this._ioService = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); this.wrappedJSObject = this; // Video ID から Player の URL を取得 var nicovideoURLSpec = "http://www.nicovideo.jp/api/getflv?v=" + aVideoID; var nicovideoURL = this._ioService.newURI(nicovideoURLSpec, null, null); var httpChannel = this._ioService.newChannelFromURI(nicovideoURL) .QueryInterface(Components.interfaces.nsIHttpChannel); httpChannel.requestMethod = "GET"; httpChannel.redirectionLimit = 0; httpChannel.asyncOpen(this.getListener(), this); }, onDataAvailable: function(aRequest, aContext, aistream, offset, count){ aRequest.QueryInterface(Components.interfaces.nsIHttpChannel); if(aRequest.responseStatus != 200){ alert("ERROR: ucjsNicovideoDownloader"); return; } var sstream = Components .classes ["@mozilla.org/scriptableinputstream;1"] .createInstance (Components.interfaces .nsIScriptableInputStream); sstream.init (aistream); result = sstream.read (-1); sstream.close (); var p = {}; for each(var a in result.split("&")) { if(typeof a != "string") break; var t = a.split("="); p[t[0]] = t[1]; } var url = unescape(p["url"]); this.saveMOVIE(this._title, url); //this.saveFLV(this._title, url); }, getListener: function(){ var listener = { onStartRequest: function(){}, onDataAvailable: function (aRequest, aContext, aistream, offset, count){ aContext.wrappedJSObject.onDataAvailable(aRequest, aContext, aistream, offset, count); }, onStopRequest: function(){ } } return listener; }, saveMOVIE: function(aTitle, aURLSpec){ const FLV_EXTENSION = "flv"; const MP4_EXTENSION = "mp4"; var FLV_CONTENT_TYPE = "video/flv"; var MP4_CONTENT_TYPE = "video/mp4"; var media_type = /\.nicovideo\.jp\/smile\?(.)\=/.exec(aURLSpec)[1]; if (media_type == "m"){ // 多分mp4 download var mp4Name = aTitle + "." + MP4_EXTENSION; var mp4URL = this._ioService.newURI(aURLSpec, null, null) .QueryInterface(Components.interfaces.nsIURL); var fileInfo = new FileInfo(mp4Name, mp4Name, aTitle, MP4_EXTENSION, mp4URL); var fpParams = { fpTitleKey: "", isDocument: false, fileInfo: fileInfo, contentType: MP4_CONTENT_TYPE, saveMode: GetSaveModeForContentType(MP4_CONTENT_TYPE), saveAsType: 0, file: null, fileURL: null }; }else{ // 多分flv download var flvName = aTitle + "." + FLV_EXTENSION; var flvURL = this._ioService.newURI(aURLSpec, null, null) .QueryInterface(Components.interfaces.nsIURL); var fileInfo = new FileInfo(flvName, flvName, aTitle, FLV_EXTENSION, flvURL); var fpParams = { fpTitleKey: "", isDocument: false, fileInfo: fileInfo, contentType: FLV_CONTENT_TYPE, saveMode: GetSaveModeForContentType(FLV_CONTENT_TYPE), saveAsType: 0, file: null, fileURL: null }; } if(!getTargetFile(fpParams, this.SKIP_SELECT_PROMPT)){ return; } var fileURL = fpParams.fileURL || makeFileURI(fpParams.file); var persist = makeWebBrowserPersist(); var nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist; persist.persistFlags = nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES | nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE; var transfer = Components.classes["@mozilla.org/transfer;1"] .createInstance(Components.interfaces.nsITransfer); transfer.init(fileInfo.uri, fileURL, "", null, null, null, persist); persist.progressListener = transfer; persist.saveURI(fileInfo.uri, null, null, null, null, fileURL); } /* saveFLV: function(aTitle, aFlvURLSpec){ const FLV_EXTENSION = "flv"; var FLV_CONTENT_TYPE = "video/flv"; var flvName = aTitle + "." + FLV_EXTENSION; var flvURL = this._ioService.newURI(aFlvURLSpec, null, null) .QueryInterface(Components.interfaces.nsIURL); var fileInfo = new FileInfo(flvName, flvName, aTitle, FLV_EXTENSION, flvURL); var fpParams = { fpTitleKey: "", isDocument: false, fileInfo: fileInfo, contentType: FLV_CONTENT_TYPE, saveMode: GetSaveModeForContentType(FLV_CONTENT_TYPE), saveAsType: 0, file: null, fileURL: null }; if(!getTargetFile(fpParams, this.SKIP_SELECT_PROMPT)){ return; } var fileURL = fpParams.fileURL || makeFileURI(fpParams.file); var persist = makeWebBrowserPersist(); var nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist; persist.persistFlags = nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES | nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE; var transfer = Components.classes["@mozilla.org/transfer;1"] .createInstance(Components.interfaces.nsITransfer); transfer.init(fileInfo.uri, fileURL, "", null, null, null, persist); persist.progressListener = transfer; persist.saveURI(fileInfo.uri, null, null, null, null, fileURL); } */ } ucjsNicovideoDownloader.init();