// ==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 4.7
// @grant GM_xmlhttpRequest
// @run-at document-end
// @downloadURL none
// ==/UserScript==
(function() {
if (window.top !== window.self) {
return;
}
var bili = {
aid: null,
cid: null,
bofqi: null,
oPlayer: null,
title: null,
iframe: function() {
return '';
},
embed: function() {
return '';
},
embedFull: function() {
return '';
},
weekday: null,
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/)) {
addListener();
handleSp(1);
} else {
console.log('页面不存在视频内容');
return;
}
}
function handleAv() {
var playerArea = document.getElementById('bofqi');
if (playerArea) {
var playerAreaRect = getRect(playerArea);
setTimeout(function() {
window.scrollTo(0, playerAreaRect.pageY-20);
}, 100);
}
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号!
请从新番专题页面打开视频!');
}
} 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];
}
}
if (!bili.observer) {
bili.observer = true;
var observer = new MutationObserver(function(mutation) {
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 getRect(element) {
var rect = element.getBoundingClientRect();
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
return {
pageX: rect.left + scrollLeft,
pageY: rect.top + scrollTop
};
}
function addListener() {
document.addEventListener('mousedown',mouseDownHandle,false);
document.addEventListener('mouseup',mouseUpHandle,false);
var tDown,tUp;
var href;
var isHold = false;
function mouseDownHandle(e) {
var a = e.target;
if (a.nodeName != 'A') return;
if (tDown) {clearTimeout(tDown)};
if (tUp) {clearTimeout(tUp)};
tDown = setTimeout(function(){
isHold = true;
},500);
}
function mouseUpHandle(e) {
var a = e.target;
if (a.nodeName != 'A') return;
if (tDown) {clearTimeout(tDown)};
if (tUp) {clearTimeout(tUp)};
if (isHold) {
href = a.href;
var aid = a.href.match(/av(\d+)/);
if (aid) {
a.href = 'http://www.bilibili.com/video/av' + '#' + aid[1];
console.log(a.href);
}
tUp = setTimeout(function(){
if (href) {a.href = href;};
console.log(a.href);
},100);
}
isHold = false;
}
}
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(//);
if (timelength) {
console.log('存在视频源,开始替换播放器');
replacePlayer();
} else {
addCheckTip('暂无其他视频源啦!
停止替换播放器!');
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: 200px;z-index: 999999;}');
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 btn = document.createElement('div');
btn.id = 'player_btn';
btn.onclick = function() {
playerBackControl(true);
};
btn.appendChild(document.createTextNode('取消替换'));
document.body.appendChild(btn);
addStyle('#player_btn {cursor: pointer;font: 1em "微软雅黑";padding: 6px;width:30px;text-align: center;transition: all 0.6s ease-out;position: absolute;background-color: #27A9D8;color:#FFF;opacity:0.3;left: calc(50% + 500px);} #player_btn:hover{transform: rotateZ(360deg);opacity:1;} .widescreen #player_btn{left: calc(50% + 620px);}');
var playerBtn = document.getElementById('player_btn');
playerBtn.style.top = (getRect(document.getElementById('bofqi')).pageY) + 'px';
}
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('找到视频源啦!
替换播放器成功!');
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: 38%;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(//);
if (timelength) {
console.log('存在视频源,开始替换播放器');
error_AddPlayer();
} else {
if (vtype == "letv") {
error_AddTip('存在乐视源!
需要挂国外代理观看!
若无法观看请按CTRL+F5刷新页面!');
} else {
error_AddTip('视频被和谐啦!
暂时找不到其他视频源!');
}
}
}
}
});
}
function error_AddPlayer() {
error_AddTip('找到视频源!
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.firstElementChild);
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 += '';
} else if (data.list[i].weekday == bili.weekday) {
tipList += '';
}
}
document.getElementById('remindList').innerHTML = tipList;
}
function remind_addTip() {
var css = '#bangumiRmind{display:none;background-color: #FFF;position: absolute;right: -76px;top: 36px;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;} #bangumiRmind .bgmCalendar a:hover{color:#00A1D6}';
css += '.widescreen #remindBtn{display:inline-block;} #remindBtn{display:none;}';
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 = '少女祈祷中...
';
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();
})();