読者です 読者をやめる 読者になる 読者になる

まめ畑

ゆるゆると書いていきます

とにかく動画を落とすだけのFeature作った

Jetpack javascript ニコニコ動画

先日のMozilla勉強会の懇親会の席の一角で、ほんの一瞬だけでた、ニコニコ動画のWatchページを開くと動画を勝手にDLするFeatureを作ってみました。Nico DLをpageModsを使うように書き換えただけなんですが、こんなのも簡単に出来るという事でgalleryに置いておきます。
DLはこちら:
あと、使わない事推薦とって言っていながら、defaultView.Ccとか使ってるので使えなくなるかもしれません(FilepickerとかtransferあたりのAPI欲しいなぁ)
コードは最後に。


とりあえず作っただけなので、ご自由に改変などしてお使いください。
インストールしてsettingsからダウンロードした動画を保存するフォルダ名を入力すればおkです。
標準では「nico_dl」というフォルダに保存します(保存先はディスクトップ)
後は、ニコニコ動画のwatchページを開くだけで動画をダウンロードします(巡回するだけで動画があなたのHDDに…)
用法用量を守ってお使いください。


Settings APIを使っていて気づいたのですが、Feature毎のSettingsを開いた時に表示される画面の挙動が少しおかしいです。

具体的には、上の画像で「Miteru Now! Beta」と表示されている部分に表示される文字が、Settingsを一番最初に表示した時のままになってしまいます。Fxを再起動すれば問題ないのですが、Settingsを閉じて別のSettingsを開いても表示される文字が変わりません(設定項目は正しいものが表示されます)


以前のエントリで、ツールバーなどにメニューを追加すると、挙動がおかしくなるというものですが、フォーラムに書き込みがありました。パッチも公開されています(このダイアリーにもコメントを頂いているのですが、他のアドオンの影響を受けたり与えたりするようです)
530169 – Jetpack 0.6.2 seems to have strange interactions with add-ons that add toolbars and toolbar buttons


また、JEPに追加がありました。

  • JEP37 JPX, the Jetpack build tool


コード

/*
   @author: con_mame
   @url: http://d.hatena.ne.jp/con_mame/
   @title: Nico DL Auto
   @description: Automaticaly Download Movie File from NicoNico Douga
   @version: 0.1
*/

var manifest = {
    settings: [
        {
            name: "nicodlauto",
            type: "group",
            label: "Nico DL DirName",
            settings: [
            { name: "nicodirname", type: "text", label: "Dir Name" }
            ]
        }
    ]
};


(function(){
    const ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAG5JREFUOE+tU+0OABAI5Jl6/2dDtjNaJR+34UdcXZdcGtILmAAgosLLghZP2mV50SNWCaIVdfm8IcPpuRCYwo0AejUq+ELgOSATXFeAh9cEs0PbJnr+byuQln7rgSnhdIgWCZjG6CzMdrt/IUJYAffFJ2uA33mhAAAAAElFTkSuQmCC";


    function getFlv(videoId, videoAddr){
        try{
            var defaultV = jetpack.tabs[0].raw.ownerDocument.defaultView;
            var Cc = defaultV.Cc;
            var Ci = defaultV.Ci;
            var nicoDir = jetpack.storage.settings.nicodlauto.nicodirname || "nico_dl";

            var saveFile = Cc['@mozilla.org/file/directory_service;1']
                            .getService(Ci.nsIProperties)
                            .get("DeskV", Ci.nsIFile);
            saveFile.append(nicoDir);
            if(!saveFile.exists() || !saveFile.isDirectory()) {
               saveFile.create(Ci.nsIFile.DIRECTORY_TYPE, 0664);
            }
            saveFile.append(videoId + ".flv");
            if(saveFile.exists()) return;

            var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
            var url = ios.newURI(videoAddr, null, null);
            saveFile = ios.newFileURI(saveFile);

            var iwp = Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(Ci.nsIWebBrowserPersist);
            var trans = Cc["@mozilla.org/transfer;1"].createInstance(Ci.nsITransfer);
            trans.init(url, saveFile, videoAddr, null, null, null, iwp);
            iwp.progressListener = trans;
            iwp.saveURI(url, null, null, null, null, saveFile);
        }catch(e){
            console.error(e);
        }
    }

    function doDownload(videoId){
        $.ajax({
            type: "GET",
            url: "http://www.nicovideo.jp/api/getflv/" + videoId,
            cache: false,
            success: function(info){
                if(/&url=(.+?)&/.test(decodeURIComponent(info))){
                    getFlv(videoId, RegExp.$1);
                }else{
                    showMessege("Error", "Check Login");
                }
            },
            error: function(xtr, status, thrown){
                showMessege("Error", status);
            }
        });
    }

    function showMessege(title, message){
        jetpack.notifications.show({
            title: title,
            body: message,
            icon: ICON
        });
    }

    jetpack.future.import("pageMods");
    jetpack.future.import("storage.settings");
    var callback = function(doc){
        if(/http:\/\/www.nicovideo.jp\/watch\/(.+)$/.test(doc.location.href)){
            doDownload(RegExp.$1);
        }else{
            return;
        }
    };
    var options = {};
    options.matches = ["http://www.nicovideo.jp/watch/sm*"];
    jetpack.pageMods.add(callback, options);
})()