// ==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(); })();