Greasy Fork

Greasy Fork is available in English.

bilibili plus bilibilijj

在bilibili界面上直接添加来自jj的三种下载链接。flv是分段超清,mp4是整段高清,ass是弹幕。请登录jj以跳过广告页。播放弹幕可使用potplayer等。视频弹幕同名即可自动加载。

当前为 2017-04-10 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        bilibili plus bilibilijj
// @namespace   http://qli5.tk/
// @description 在bilibili界面上直接添加来自jj的三种下载链接。flv是分段超清,mp4是整段高清,ass是弹幕。请登录jj以跳过广告页。播放弹幕可使用potplayer等。视频弹幕同名即可自动加载。
// @include     http://www.bilibili.com/video/av*
// @include     https://www.bilibili.com/video/av*
// @include     http://bangumi.bilibili.com/anime/*
// @include     https://bangumi.bilibili.com/anime/*
// @version     0.5
// @grant       GM_xmlhttpRequest
// @author      qli5
// @copyright   qli5, 2014+, 田生
// @license     Mozilla Public License 2.0; http://www.mozilla.org/MPL/2.0/
// @require     http://greasyfork.icu/scripts/2231-bilibili-ass-danmaku-downloader/code/bilibili%20ASS%20Danmaku%20Downloader.user.js
// @connect-src www.jijidown.com
// @connect-src comment.bilibili.com
// ==/UserScript==

// 感谢所有大佬,鄙人只做了微小的工作。
(function () {
    // jj的站长说被攻击了,所以加了很严格的机器人检查。可以尝试加快检查,但是如果您真的是机器人也没办法。
    var testingBypassSafedog = true;
    // 本测试功能适合一次会下载很多视频的场景,可以尽量方便地把mp4的文件名改成ass的。这是我能在同源限制下想出的最好办法。请诸大佬指教。
    var testingMP4Rename = true;
    // 本测试功能适合看完就删的场景,可以将ass的文件名改成mp4的。文件名一般是数字乱码,也有可能失败,但不需要多点击。
    var testingASSRename = true;
    // 强迫症就请自己动手改成true/false吧

    // settings
    // Nope, I will not bother you with them any more.

    // reset dalao's script
    window.removeEventListener('DOMContentLoaded', init);
    init = function () { };
    initFont();

    var paraOriginal;
    GM_xmlhttpRequest(paraOriginal = {
        method: 'GET',
        url: 'http://www.jijidown' + location.href.match(/\.com.*/)[0],
        onload: function (response) {
            var doc = new DOMParser().parseFromString(response.responseText, 'text/html');
            var links = document.createElement('div');

            // anchor to jj
            var aa;
            aa = document.createElement('a');
            aa.href = 'http://www.jijidown' + location.href.match(/\.com.*/)[0];
            aa.textContent = 'bilibilijj';
            links.appendChild(aa);

            // testingMP4Rename
            var input, button;
            if (testingMP4Rename) {
                input = document.createElement('input');
                input.type = 'text';
                input.value = '小技巧:先选ass,再重命名mp4成这里的名字,就能自动加载弹幕啦~';
                input.onclick = function () { this.select(); };
                links.appendChild(input);
                button = document.createElement('button');
                button.onclick = function () {
                    try {
                        input.select();
                        document.execCommand('copy');
                    }
                    catch (e) {
                        console.warn('Oops, copy failed' + e);
                    }
                };
                button.textContent = '复制';
                links.appendChild(button);
            }

            if (doc.getElementsByClassName('yjs-browser-verification').length > 0) {
                // jj boom
                links.appendChild(document.createTextNode('jj觉得你是机器人,请手动访问一次。'));

                // testingBypassSafedog
                if (testingBypassSafedog) {
                    links.appendChild(document.createTextNode('但是你选择了跳过jj的机器人验证,讨厌~~稍后刷新'));
                    var jschl_vc = response.responseText.match(/<input type="hidden" name="jschl_vc" value=".*(?="\/>)/)[0].slice(44);
                    var pass = response.responseText.match(/<input type="hidden" name="pass" value=".*(?="\/>)/)[0].slice(40);
                    var jschl_answer = eval(
                        response.responseText
                        .match(/setTimeout\(function\(\){[\s\S]*?}[\s\S]*?(?=})/)[0].slice(23)
                        .replace("a = document.getElementById('jschl-answer');", 'a = {}')
                        .replace("f = document.getElementById('challenge-form');", '// f')
                        .replace("f.submit();", 'a;')
                    );

                    // safedog will reject false starts. you may tweak the delay if you have a higher RTT, especially if you are not in China
                    setTimeout(function () {
                        links.remove();
                        GM_xmlhttpRequest({
                            method: 'GET',
                            url: 'http://www.jijidown.com/cdn-cgi/l/chk_jschl?' + 'jschl_vc=' + encodeURIComponent(jschl_vc) + '&pass=' + encodeURIComponent(pass) + '&jschl_answer=' + encodeURIComponent(jschl_answer.value),
                            headers: {
                                'Referer': 'http://www.jijidown.com/'
                            },
                            onload: function () {
                                GM_xmlhttpRequest(paraOriginal);
                            }
                        });
                    }, 4000);

                    testingBypassSafedog = false; // to avoid infinite loop
                }
            }
            else {
                // parse jj
                var listCols = doc.getElementById('Right_Main');
                if (listCols.children.length === 0) links.appendChild(document.createTextNode('本视频貌似太冷门了,需要到jj刷新一下。'));
                for (var i = 0; i < listCols.children.length; i++) {
                    var list = listCols.children[i];
                    for (var j = 0; j < list.children.length; j++) {
                        var flvDiv, mp4Div, assDiv;
                        var name, cid;
                        if (list.children[j].querySelector('span.PBoxName') && list.children[j].querySelector('span.PBoxName').textContent != '公告') {
                            flvDiv = list.children[j].querySelector('span.Data_Main > span.Data_Flv > span.Data_Data');
                            mp4Div = list.children[j].querySelector('span.Data_Main > span.Data_Mp4 > span.Data_Data');
                            assDiv = list.children[j].querySelector('span.Data_Main > span.Data_Ass > span.Data_Data');
                            if (list.children[j].querySelector('span.PBoxName').textContent == '下载地址(右侧方块切换类型)')
                                name = assDiv.children[0].title.slice(0, -7);
                            else
                                name = list.children[j].querySelector('span.PBoxName').textContent;
                            cid = list.children[j].getAttribute('data-cid');

                            // name
                            links.appendChild(document.createElement('br'));
                            links.appendChild(document.createTextNode(name));
                            links.appendChild(document.createTextNode(' '));

                            // flv
                            var a;
                            a = document.createElement('a');
                            a.href = 'http://www.jijidown.com' + flvDiv.querySelector('a').getAttribute('href');
                            a.textContent = 'flv';
                            links.appendChild(a);
                            links.appendChild(document.createTextNode(' '));

                            // mp4
                            a = document.createElement('a');
                            a.textContent = 'mp4';
                            if (testingASSRename)
                                a.onclick = function () { this.nextSibling.nextSibling.download = this.href.match(/\/\d*(?=(-1-hd)?\.mp4)/)[0].slice(1) + '-1-hd.ass'; };
                            if (mp4Div.querySelector('a'))
                                a.href = 'http://www.jijidown.com' + mp4Div.querySelector('a').getAttribute('href');
                            else {
                                a.textContent = '本视频貌似太冷门了,需要到jj刷新一下。';
                            }
                            links.appendChild(a);
                            links.appendChild(document.createTextNode(' '));

                            // ass
                            a = document.createElement('a');
                            a.textContent = 'ass';
                            a.onclick = (function (name, cid, self) {
                                return function () {
                                    if (self.href.slice(0, 4) != 'blob') {
                                        fetchDanmaku(cid, function (danmaku) {
                                            var ass = generateASS(setPosition(danmaku), {
                                                'title': name,
                                                'ori': location.href,
                                            });
                                            // I would assume most users are using Windows
                                            var blob = new Blob(['\ufeff' + ass], { type: 'application/octet-stream' });
                                            self.setAttribute('href', window.URL.createObjectURL(blob));
                                            self.click();
                                        });
                                        return false;
                                    }
                                    if (testingMP4Rename) {
                                        input.value = name + '.mp4';
                                        input.select();
                                    }
                                };
                            })(name, cid, a);
                            a.download = name + '.ass';
                            a.href = 'http://www.bilibilijj.com' + assDiv.querySelector('a').getAttribute('href');
                            links.appendChild(a);
                        }
                    }
                }
            }

            // set styles
            links.style.backgroundColor = 'white';
            links.style.padding = '10px';
            links.style.border = 'black';
            links.style.borderWidth = 'thin';
            links.style.borderStyle = 'dashed';

            // append to page
            if (location.hostname == 'www.bilibili.com') {
                links.style.zIndex = '500000';
                links.style.position = 'absolute';
                links.style.top = '0px';
                document.querySelector('.v_small').appendChild(links);
            }
            else if (location.hostname == 'bangumi.bilibili.com') {
                document.querySelector('.v1-bangumi-list-part-wrapper').appendChild(links);
            }
        }
    });
})();