Greasy Fork is available in English.

bilibili toothbrush

牙刷科技,还原哔哩哔哩播放器,404页面视频需挂代理

Verzia zo dňa 04.09.2014. Pozri najnovšiu verziu.

// ==UserScript==
// @name        bilibili toothbrush
// @namespace   http://www.icycat.com
// @description 牙刷科技,还原哔哩哔哩播放器,404页面视频需挂代理
// @author      冻猫
// @include     *www.bilibili.tv/*
// @include     *www.bilibili.com/*
// @include     *bilibili.kankanews.com/*
// @version     3.8
// @grant       GM_xmlhttpRequest
// @run-at      document-end
// ==/UserScript==

(function() {
    var bili = {
        aid: null,
        cid: null,
        bofqi: null,
        oPlayer: null,
        title: null,
        iframe: function() {
            return '<iframe id="bofqi_embed" width="950" height="482" class="player" src="https://secure.bilibili.tv/secure,cid=' + this.cid + '&aid=' + this.aid + '" scrolling="no" border="0" frameborder="no" framespacing="0" onload="window.securePlayerFrameLoaded=true"></iframe>';
        },
        embed: function() {
            return '<embed id="bofqi_embed" rel="noreferrer" width="950" height="482" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" allowFullScreenInteractive="true" flashvars="cid=' + this.cid + '&aid=' + this.aid + '" src="http://static.hdslb.com/play.swf" type="application/x-shockwave-flash" AllowScriptAccess="always" allowfullscreen="true" quality="high" />';
        },
        embedFull: function() {
            return '<embed id="bofqi_embed" rel="noreferrer" width="100%" height="100%" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" allowFullScreenInteractive="true" flashvars="cid=' + this.cid + '&aid=' + this.aid + '" src="http://static.hdslb.com/play.swf" type="application/x-shockwave-flash" AllowScriptAccess="always" allowfullscreen="true" quality="high" />';
        },
        weekday: null,
        spNew: new Array(),
        spOld: new Array(),
        isRun: false,
        btnDelay: null,
        listDelay: null,
        observer: false
    };

    function init() {
        console.log('bilibili toothbrush 初始化');
        checkUrl();
        remind_createRemindBtn();
    }

    function checkUrl() {
        var url = document.location.href;
        if (url.match(/av/)) {
            handleAv();
        } else if (url.match(/sp/)) {
            handleSp(1);
        } else {
            console.log('页面不存在视频内容');
            return;
        }
    }

    function handleAv() {
        var playerWrapper = document.querySelector('.player-wrapper');
        if (playerWrapper) {
            var zTop = document.querySelector('.z_top');
            var scrollHeight = playerWrapper.offsetTop - zTop.offsetHeight;
            window.scrollTo(0, scrollHeight);
            console.log('滚动高度'+scrollHeight);
        }
        var ad = document.querySelector('.ad-f');
        if (ad) {
            ad.style.display = 'none';
        }
        var title = document.getElementsByTagName('title')[0].text;
        bili.bofqi = document.getElementById('bofqi');
        if (bili.bofqi) {
            var aid_array = document.location.href.match(/av(\d+)/);
            bili.aid = aid_array == null ? 'error' : aid_array[1];
            console.log('aid:' + bili.aid);
            var embed_array = bili.bofqi.getElementsByTagName('embed');
            bili.oPlayer = embed_array.length > 0 ? embed_array[0] : false;
            if (bili.oPlayer) {
                var flashvars = bili.oPlayer.getAttribute('flashvars');
                var cid_array = flashvars.match(/bili-cid=(\d+)/);
                if (cid_array) {
                    console.log('存在版权播放器');
                    bili.cid = cid_array[1];
                    console.log('cid:' + bili.cid);
                    checkCid();
                } else {
                    console.log('乐视源B站播放器,无需替换!');
                    return;
                }
            } else {
                console.log('播放器无需替换!');
                return;
            }
        } else {
            if (title == '出错啦! - bilibili.tv') {
                console.log('404啦');
                error_AddTip('尝试自动搜寻其他视频源中...');
                var errorAid = document.location.href.match(/#(\d+)/);
                if (errorAid) {
                    bili.aid = errorAid[1];
                    error_GetCid();
                } else {
                    error_AddTip('无法获取视频AV号!<br/>请从新番专题页面打开视频!');
                }
            } else {
                console.log('页面无需替换');
                return;
            }
        }
    }

    function handleSp(count) {
        var a = document.getElementById('bgm_video_container').getElementsByTagName('a');
        if (a.length > 0) {
            for (var i = 0; i < a.length; i++) {
                if (a[i].href.match(/#/)) {
                    return;
                }
                var aid = a[i].href.match(/av(\d+)/);
                if (aid) {
                    a[i].href = a[i].href + '#' + aid[1];
                    console.log(a[i].href);
                }
            }
            if (!bili.observer) {
                bili.observer = true;
                var observer = new MutationObserver(function(mutation) {
                    console.log('监听到DOM变化');
                    handleSp(1);
                });
                observer.observe(document.getElementById('bgm_video_container'), {
                    'childList': true,
                    'subtree': true
                });
            }
        } else {
            if (count < 100) {
                var t = setTimeout(function() {
                    handleSp(count + 1);
                }, 100);
            }
        }
    }

    function checkCid() {
        console.log('检查是否存在视频源');
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'http://interface.bilibili.com/playurl?appkey=11ecf7fd943dbc58&cid=' + bili.cid,
            headers: {
                'User-Agent': navigator.userAgent,
                'Cookie': document.cookies,
            },
            onload: function(responseDetails) {
                if (responseDetails.status == 200) {
                    var timelength = responseDetails.responseText.match(/<timelength>(\d+)<\/timelength>/);
                    if (timelength) {
                        console.log('存在视频源,开始替换播放器');
                        replacePlayer();
                    } else {
                        addCheckTip('暂无其他视频源啦!<br/>停止替换播放器!');
                        console.log('不存在视频源,停止替换');
                    }
                }
            }
        });
    }

    function addCheckTip(str) {
        var tip = document.createElement('div');
        tip.id = 'check_tip';
        tip.innerHTML = str;
        document.body.appendChild(tip);
        addStyle('#check_tip{transition: all 0.8s ease-out;background: none repeat scroll 0 0 #27a9d8;color: #FFFFFF;font: 1.1em "微软雅黑";right: -200px;margin-left: -250px;overflow: hidden;padding: 10px;position: fixed;text-align: center;bottom: 100px;z-index: 300;}');
        var check_tip = document.getElementById('check_tip');
        var t1 = setTimeout(function() {
            check_tip.style.right = '25px';
        }, 300);
        var t2 = setTimeout(function() {
            check_tip.style.right = '-200px';
        }, 5000);
    }

    function createButton() {
        var info = document.querySelector('.viewbox').querySelector('.info');
        var btn = document.createElement('div');
        btn.id = 'player_btn';
        btn.onclick = function() {
            playerBackControl(true);
        };
        btn.appendChild(document.createTextNode('取消替换'));
        info.appendChild(btn);
        addStyle('#player_btn {background: none repeat scroll 0 0 #27A9D8;border-radius: 5px;cursor: pointer;color: #FFFFFF;font: 1em "微软雅黑";padding: 6px;position: absolute;right: 180px;width:30px;text-align: center;top: 8px;');
    }

    function addStyle(css) {
        var style = document.createElement('style');
        style.type = 'text/css';
        var node = document.createTextNode(css);
        style.appendChild(node);
        document.head.appendChild(style);
    }

    function replacePlayer() {
        bili.bofqi.innerHTML = bili.iframe();
        var player_fullwin = unsafeWindow.player_fullwin;
        window.addEventListener("message", function(e) {
            console.log(e.data);
            eval(e.data.substr(6));
        }, false);
        createButton();
        addCheckTip('找到视频源啦!<br/>替换播放器成功!');
        console.log('播放器替换成功!');
    }

    function playerBackControl(status) {
        console.log('backStatus:' + status);
        var player_btn = document.getElementById('player_btn');
        if (status) {
            player_btn.onclick = function() {
                playerBackControl(false);
            };
            player_btn.innerHTML = '重新替换';
            bili.bofqi.removeChild(document.getElementById('bofqi_embed'));
            bili.bofqi.appendChild(bili.oPlayer);
        } else {
            player_btn.onclick = function() {
                playerBackControl(true);
            };
            player_btn.innerHTML = '取消替换';
            bili.bofqi.innerHTML = bili.iframe();
        }
    }


    /* 404页面处理 */

    function error_AddTip(str) {
        var isTip = document.getElementById('tip');
        if (isTip) {
            isTip.parentNode.removeChild(isTip);
        }
        var tip = document.createElement('div');
        tip.id = 'tip';
        tip.innerHTML = str;
        document.body.appendChild(tip);
        addStyle('body{text-align:center;}#tip{background: none repeat scroll 0 0 #27a9d8;color: #FFFFFF;font: 1.5em "微软雅黑";padding: 30px;position: fixed;text-align: center;top: 40%;z-index: 300;margin:0 auto;left:0;right:0;width:500px;}');
    }

    function error_GetCid() {
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'http://api.bilibili.com/view?type=json&batch=1&appkey=11ecf7fd943dbc58&id=' + bili.aid,
            headers: {
                'User-Agent': 'bilibili toothbrush (cat@icycat.com)',
                'Cookie': document.cookies,
            },
            onload: function(responseDetails) {
                if (responseDetails.status == 200) {
                    var data = JSON.parse(responseDetails.responseText);
                    bili.cid = data.list[0].cid;
                    bili.title = data.title;
                    console.log('cid:' + bili.cid);
                    console.log('视频来源:' + data.list[0].type);
                    error_CheckCid(data.list[0].type);
                }
            }
        });
    }

    function error_CheckCid(vtype) {
        console.log('检查是否存在视频源');
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'http://interface.bilibili.com/playurl?appkey=11ecf7fd943dbc58&cid=' + bili.cid,
            headers: {
                'User-Agent': navigator.userAgent,
                'Cookie': document.cookies,
            },
            onload: function(responseDetails) {
                if (responseDetails.status == 200) {
                    var timelength = responseDetails.responseText.match(/<timelength>(\d+)<\/timelength>/);
                    if (timelength) {
                        console.log('存在视频源,开始替换播放器');
                        error_AddPlayer();
                    } else {
                        if (vtype == "letv") {
                            error_AddTip('存在乐视源!<br/>需要挂国外代理观看!<br/>若无法观看请按CTRL+F5刷新页面!');
                        } else {
                            error_AddTip('视频被和谐啦!<br/>暂时找不到其他视频源!');
                        }
                    }
                }
            }
        });
    }

    function error_AddPlayer() {
        error_AddTip('找到视频源!<br/>2秒后开始播放!');
        addStyle('body{margin: 0px;padding: 0px;}');
        document.getElementsByTagName('title')[0].text = bili.title;
        setTimeout(function() {
            document.body.innerHTML = bili.embedFull();

        }, 2000);
    }


    /*新番提醒*/

    function remind_createRemindBtn() {
        var parent = document.querySelector('.uns_box .board');
        var remindBtn = document.createElement('div');
        remindBtn.id = 'remindBtn';
        remindBtn.className = 'b-i';
        var a = document.createElement('a');
        a.href = "javascript: void(0);";
        a.onmouseover = function() {
            if (bili.btnDelay) {
                clearTimeout(bili.btnDelay);
            }
            document.getElementById('bangumiRmind').style.display = 'block';
            if (!bili.isRun) {
                remind_getUpdateData();
            }
        };
        a.onmouseout = function() {
            bili.btnDelay = setTimeout(function() {
                document.getElementById('bangumiRmind').style.display = 'none';
            }, 500);
        }
        a.innerHTML = '新番';
        remindBtn.appendChild(a);
        parent.insertBefore(remindBtn, parent.firstChild);
        remind_addTip();
    }

    function remind_getUpdateData() {
        bili.isRun = true;
        console.log('开始获取新番更新数据');
        GM_xmlhttpRequest({
            method: 'get',
            url: 'http://api.bilibili.com/bangumi?appkey=11ecf7fd943dbc58&btype=2&weekday=' + bili.weekday,
            headers: {
                'User-Agent': 'bilibili toothbrush (cat@icycat.com)',
                'Cookie': document.cookies,
            },
            onload: function(r) {
                if (r.status == 200) {
                    var data = JSON.parse(r.responseText);
                    console.log('获取新番更新数据成功');
                    remind_parseData(data);
                }
            }
        });
    }

    function remind_parseData(data) {
        console.log('今日所有新番数量:' + Object.keys(data.list).length);
        var tipList = '';
        var count = Object.keys(data.list).length;
        for (var i = 0; i < count; i++) {
            if (data.list[i].new) {
                tipList += '<div class="bangumiListNew"><a target="_blank" href="http://www.bilibili.com/sp/' + data.list[i].title + '">' + data.list[i].title + '</a></div>';
            } else if (data.list[i].weekday == bili.weekday) {
                tipList += '<div class="bangumiListOld"><a target="_blank" href="http://www.bilibili.com/sp/' + data.list[i].title + '">' + data.list[i].title + '</a></div>';
            }
        }
        document.getElementById('remindList').innerHTML = tipList;
    }

    function remind_addTip() {
        var css = '#bangumiRmind{display:none;background-color: #FFF;border-radius: 5px;position: absolute;right: -76px;top: 37px;width: 240px;border: 1px solid #CCC;}';
        css += '#bangumiRmind a{width:100%;} #bangumiRmind .bangumiListNew a{width:100%;color: #F25D8E;} #bangumiRmind .bangumiListNew a:hover{color:#00A1D6}';
        css += '#bangumiRmind .bangumiListOld a{width:100%;color: #999;} #bangumiRmind .bangumiListOld a:hover{color:#00A1D6}';
        css += '#bangumiRmind .remindArrow{height: 8px;width: 16px;top: -7px;left: 50%;margin-left: -8px;background: url(http://static.hdslb.com/images/v2images/topicons.png) no-repeat 0 -404px;position: absolute;}';
        css += '#bangumiRmind #remindList{padding:10px;font-size:12px;line-height:20px;}';
        css += '#bangumiRmind .bgmCalendar{background-color:#F9F9F9;border-bottom: 1px solid #CCC;padding:12px 0 8px 0;font-size:14px;font-weight:bold;border-radius:5px 5px 0 0;} #bangumiRmind .bgmCalendar a:hover{color:#00A1D6}';
        addStyle(css);
        var remindBtn = document.getElementById('remindBtn');
        var bangumiRmind = document.createElement('div');
        bangumiRmind.id = 'bangumiRmind';
        var d = new Date();
        bili.weekday = d.getDay();
        var weekday;
        switch (bili.weekday) {
            case 0:
                weekday = '星期日(日曜日)';
                break;
            case 1:
                weekday = '星期一(月曜日)';
                break;
            case 2:
                weekday = '星期二(火曜日)';
                break;
            case 3:
                weekday = '星期三(水曜日)';
                break;
            case 4:
                weekday = '星期四(木曜日)';
                break;
            case 5:
                weekday = '星期五(金曜日)';
                break;
            case 6:
                weekday = '星期六(土曜日)';
                break;
        }
        bangumiRmind.innerHTML = '<div class="remindArrow"></div><div class="bgmCalendar"><a target="_blank" href="http://www.bilibili.com/video/bgm_calendar.html" title="点击打开新番放送表">' + weekday + '</a></div><div id="remindList">少女祈祷中...</div>';
        bangumiRmind.onmouseover = function() {
            if (bili.btnDelay) {
                clearTimeout(bili.btnDelay);
            }
            document.getElementById('bangumiRmind').style.display = 'block';
        };
        bangumiRmind.onmouseout = function() {
            bili.btnDelay = setTimeout(function() {
                document.getElementById('bangumiRmind').style.display = 'none';
            }, 500);
        };
        remindBtn.appendChild(bangumiRmind);
    }

    init();

})();