function ucjsYoutubeFlvDownloader(){ this.SKIP_SELECT_PROMPT = true; } ucjsYoutubeFlvDownloader.prototype = { download: function(aServer,aTitle, aVideoID, aVideoIDopt,t){ this._title = aTitle; this._state = 0; var youtubeURLSpec = "http://" + aServer + "youtube.com/get_video?video_id=" + aVideoID + "&t=" + t + aVideoIDopt; this._ioService = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); this.wrappedJSObject = this; this.saveFLV(aTitle,youtubeURLSpec); }, 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(); persist.persistFlags = Components.interfaces.nsIWebBrowserPersist .PERSIST_FLAGS_REPLACE_EXISTING_FILES; 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); } }; var ucjsYoutubeFlvDownloaderContextMenu = { init: function(){ var contentAreaContextMenu = document.getElementById("contentAreaContextMenu"); this._menuItem = document.createElement("menuitem"); this._menuItem.setAttribute("label", "Download Flv"); contentAreaContextMenu.insertBefore(this._menuItem,contentAreaContextMenu.firstChild); contentAreaContextMenu.addEventListener("popupshowing", function(){ ucjsYoutubeFlvDownloaderContextMenu.onPopupShowing(this); }, false); }, onPopupShowing: function(aPopup){ this._menuItem.hidden = true; //if(gContextMenu.target.id != "vidTitle") return; var location = gContextMenu.target.ownerDocument.location; if(location.host.indexOf("youtube.com") == -1) return; /^http:\/\/([^\./:@]+\.|)youtube\.com\/watch\?.*v=([a-zA-Z0-9_\-]{11})(&fmt=\d+|)/.exec(location); var Server = RegExp.$1; var videoID = RegExp.$2; var videoIDopt = RegExp.$3; var videoTitle = gContextMenu.target.textContent; var html = gContextMenu.target.ownerDocument.getElementsByTagName('html')[0].innerHTML; if(html.match(/var[ \r\n\t]+swfArgs[ \r\n\t]*=[ \r\n\t]*\{(.*,|)[ \r\n\t]*(t|'t'|"t")[ \r\n\t]*\:[ \r\n\t]*['"]([a-zA-Z\-_0-9]+)['"].*\}/)){ }else{ alert('youtubeDownloader: cannot match'); return; } var t = RegExp.$3; var title = content.document.evaluate(".//div[@id='vidTitle']/span",content.document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null); if(!title.singleNodeValue) return; var videoTitle = (videoID+"." + String(title.singleNodeValue.textContent)).replace(/[\$\*\?\"\'\/\\\:]/g, "_"); this._menuItem.setAttribute("oncommand", "ucjsYoutubeFlvDownloaderContextMenu.download('"+ Server +"','"+ videoTitle +"','"+ videoID +"','"+ videoIDopt +"','"+ t +"')"); this._menuItem.hidden = false; }, download: function(aServer,aTitle, aVideoID,aVideoIDopt,t){ var d = new ucjsYoutubeFlvDownloader(); d.download(aServer,aTitle, aVideoID,aVideoIDopt,t); } }; ucjsYoutubeFlvDownloaderContextMenu.init();