bili_fix_player

修复B站播放器,黑科技,列表页、搜索页弹窗,破乐视限制,提供高清、低清晰源下载,弹幕下载

目前为 2014-07-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name bili_fix_player
  3. // @namespace bili
  4. // @description 修复B站播放器,黑科技,列表页、搜索页弹窗,破乐视限制,提供高清、低清晰源下载,弹幕下载
  5. // @include /^.*\.bilibili\.(tv|com|cn)\/(video\/|search)?.*$/
  6. // @include /^.*bilibili\.kankanews\.com\/(video\/|search)?.*$/
  7. // @version 3.6.2
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_addStyle
  12. // @author 绯色
  13. // ==/UserScript==
  14. /**
  15. 出现无法播放情况先关闭自动修复
  16. 2014-07-13你造吗?您可以使用一个海外的代理并将http://interface.bilibili.com/playurl?*作为代理规则加入到代理列表中j即可弹窗播放爱奇艺视频(来自田生大神)
  17. 修复弹窗播放时,点击B站FLASH播放器后,若直接点击关闭弹窗,会造成鼠标滚轮无效的问题
  18. 修复360浏览器在脚本设置的时候,被视频君挡住无法设置的问题,方案是(设置的时候先让视频君去火星,设置后再放回来)
  19. 2014-06-30按照田生大神建议,增加与其脚本匹配id,在弹窗标题增加打开播放页面的按钮,补充,发现BUG,在弹窗播放时,点击B站FLASH播放器后,若直接点击关闭弹窗,会造成鼠标滚轮无效的问题,这BUG作者暂时无修复方法
  20. 并且使用了田生大神分支里面的弹窗播放器支持网页全屏功能,感谢
  21. 2014-06-21修复搜索页面因为作者正则匹配错误(B站把域名换成com但在a标签还是tv域名,坑爹)的问题
  22. 2014-06-18修复B站更换域名的BUG,在田生大神的建议下,将所有api域名换成com,弹窗播放器增加收藏按钮
  23. 2014-06-08修复小部分bug(样式冲突、弹窗冲突)
  24. 2014-06-03增强弹窗播放器,[拖动窗口标题可移动播放器,拖动右下角可改变播放器大小,设置后自动保存宽高和位置]
  25. 2014-05-25感谢吧友lzgptdgj提供BUG,在小型播放器下,屏蔽规则会无效的问题,已经修复
  26. 2014-05-14增加首页弹窗播放,基本实现全站可弹窗(首页新番专题列表除外等)
  27. 2014-05-13增加搜索页面的弹窗播放,并且支持多P和显示当前P,增加模糊画质下载按钮
  28. 2014-05-11还是基佬要求,增加弹窗播放器分P效果,增加弹幕下载功能,在吧友大神田生的建议下,正则表达式加强匹配
  29. 2014-05-10收益于自己的B站追番计划(http://v.myacg.ga或者http://weiyun.jd-app.com),代码逻辑重构(不再区分视频源再解析视频),并重写UI
  30. 2014-05-10受诸多基佬要求,增加除首页外其他分类页面的弹窗播放(初衷是为了弹窗乐视源)
  31. 2014-03-28增加下载视频按钮
  32. 2014-01-23替换优酷、爱奇艺、搜狐为B站播放器
  33. 2013-12-14修复B站播放器无法在火狐魔镜弹窗播放
  34. ------------以下信息提供给开发者-----------
  35. //https://static-s.bilibili.tv/play.swf---新版播放器
  36. //http://static.hdslb.com/play.swf---旧版播放器
  37. //https://static-s.bilibili.tv/play_old.swf---考古级别播放器
  38. //使用https连接的播放器可以获得屏蔽列表
  39. -------------------------------------------
  40. */
  41. (function() {
  42. //初始化 init
  43. if (GM_getValue('auto') == undefined) GM_setValue('auto', 1);
  44. if (GM_getValue('player_size') == undefined) GM_setValue('player_size', 1);
  45. if (GM_getValue('pagebox_display')== undefined) GM_setValue('pagebox_display', 0);
  46. //if (GM_getValue('player_container')== undefined) GM_setValue('player_container', 1);//弹窗播放器的标签容器(iframe/embed)已经完美解决
  47. //初始化播放器宽高
  48. if (GM_getValue('player_width') == undefined) GM_setValue('player_width', 950);
  49. if (GM_getValue('player_height') == undefined) GM_setValue('player_height', 482);
  50. //初始化播放器外框位置
  51. //if (GM_getValue('div_top') == undefined) GM_setValue('div_top', 100);//设置垂直位置的时候,如果是长页而且是浮动播放器时候记录位置,会导致播放器不知所踪
  52. if (GM_getValue('div_left') == undefined) GM_setValue('div_left', 100);
  53. //初始化jquery支持
  54. var $ = unsafeWindow.$;
  55. /**
  56. -------------------------------用户界面GUI View-------------------------------------
  57. */
  58. //函数,插入可视化操作视图
  59.  
  60. function insert_html(type) {
  61. var auto = GM_getValue('auto') ? '已打开' : '已关闭';
  62. var player_size = GM_getValue('player_size') ? '大型' : '小型';
  63. var display=GM_getValue('pagebox_display') ? '悬浮' : '默认';
  64. //var container=GM_getValue('player_container')?'iframe[无滚动条bug]':'embed[无拖放bug]';
  65. var div = '<a style="color:red" id="bili-fix-player-installed">脚本(`・ω・´)</a>\
  66. <ul class="i_num" id="bili_fix_script">\
  67. <li><a class="font">遇到播放错误请关闭自动修复后刷新页面</a><a target="_blank" href="http://bilili.ml/361.html">BUG反馈</a></li>\
  68. <li><a>本页视频源:<b style="color:#F489AD">' + type + '</b></a></li>\
  69. <li><a class="font">高清视频下载HD(右键复制以下视频分段下载链接,然后在新标签粘贴打开即可不被403)</a><div class="m_num" id="av_source">\
  70. </div></li>\
  71. <li><a class="font" target="_blank" id="aid_down_av">模糊画质视频下载(单文件)</a></li>\
  72. <li><a id="down_cid_xml" target="_blank">弹幕下载</a></li>\
  73. <li><a>自动修复(修改后请刷新页面):<a id="bili_fix" class="bfpbtn">' + auto + '</a></a></li>\
  74. <li><a class="font">播放器大小(小型在火狐弹窗无BUG):<a id="player_size" class="bfpbtn">' + player_size + '</a></a></li>\
  75. <li><a>评论区分页导航:<a id="pagebox-display" class="bfpbtn">' + display + '</a></a></li>\
  76. <li><a id="bili_set_status">就绪中→_→</a></li>\
  77. </ul>\
  78. <span class="addnew_5">+10086</span>';
  79. $('div.num:nth-child(4) > ul:nth-child(1) > li:nth-child(1)').html(div);
  80. //监听修复按钮
  81. var bfpbtn = document.querySelector("#bili_fix");
  82. bfpbtn.addEventListener("click", set_auto, false);
  83. //监听播放器大小按钮
  84. var bfpbtn = document.querySelector("#player_size");
  85. bfpbtn.addEventListener("click", set_player, false);
  86. //监听评论分页功能显示切换
  87. var bfpbtn = document.querySelector("#pagebox-display");
  88. bfpbtn.addEventListener("click", change_pagebox_display, false);
  89. }
  90.  
  91. //函数,插入下载按钮
  92.  
  93. function insert_download_button(url, count) {
  94. $('#av_source').append('<a href="' + url + '" target="blank">分段【' + count + '】</a>');
  95. }
  96.  
  97. //设置参数
  98. //修复按钮事件
  99.  
  100. function set_auto() {
  101. GM_getValue('auto') ? GM_setValue('auto', 0) : GM_setValue('auto', 1);
  102. var s = GM_getValue('auto') ? '已打开' : '已关闭';
  103. document.getElementById('bili_fix').innerHTML = s;
  104. $("#bili_fix").toggleClass("active");
  105. $('#bili_set_status').html('<a class="bfpbtn notice font">已更改,刷新生效_(:3」∠)_</a>');
  106. }
  107. //播放器大小按钮事件
  108.  
  109. function set_player() {
  110. GM_getValue('player_size') ? GM_setValue('player_size', 0) : GM_setValue('player_size', 1);
  111. var s = GM_getValue('player_size') ? '大型' : '小型';
  112. document.getElementById('player_size').innerHTML = s;
  113. $("#player_size").toggleClass("active");
  114. $('#bili_set_status').html('<a class="bfpbtn active font">已更改,刷新生效_(:3」∠)_</a>');
  115. }
  116. //函数 评论分页功能显示切换(悬浮、原来位置)
  117. function change_pagebox_display(){
  118. GM_getValue('pagebox_display') ? GM_setValue('pagebox_display', 0) : GM_setValue('pagebox_display', 1);
  119. var s = GM_getValue('pagebox_display') ? '悬浮' : '默认';
  120. document.getElementById('pagebox-display').innerHTML = s;
  121. $("#pagebox-display").toggleClass("active");
  122. $('#bili_set_status').html('<a class="bfpbtn notice font">已更改,刷新生效_(:3」∠)_</a>');
  123. }
  124. /**
  125. -------------------------------函数 Model-------------------------------------
  126. */
  127. //函数,替换播放器
  128.  
  129. function Replace_player(aid, cid) {
  130. if (GM_getValue('auto') == '1') {
  131. if (GM_getValue('player_size') == '1') {
  132. document.getElementById('bofqi').innerHTML = '<iframe id="bofqi_embed" class="player" src="https://secure.bilibili.com/secure,cid=' + cid + '&amp;aid=' + aid + '" scrolling="no" border="0" framespacing="0" onload="window.securePlayerFrameLoaded=true" frameborder="no" height="482" width="950"></iframe> ';
  133. } else {
  134. document.getElementById('bofqi').outerHTML = '<embed id="bofqi_embed" class="player" allowfullscreeninteractive="true" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" allowscriptaccess="always" rel="noreferrer" flashvars="cid=' + cid + '&amp;aid=' + aid + '" src="https://static-s.bilibili.com/play.swf" type="application/x-shockwave-flash" allowfullscreen="true" quality="high" wmode="window" height="482" width="950">';
  135. }
  136. }
  137. }
  138. //api获取cid
  139.  
  140. function api_get_cid(aid, page) {
  141. var url = 'http://api.bilibili.com/view?type=json&appkey=0a99fa1d87fdd38c&batch=1&id=' + aid;
  142. GM_xmlhttpRequest({
  143. method: 'GET',
  144. url: url,
  145. synchronous: false,
  146. onload: function(responseDetails) {
  147. if (responseDetails.status == 200) {
  148. var Content = eval('(' + responseDetails.responseText + ')');
  149. var list = Content.list;
  150. var p = page - 1;
  151. if (list != undefined) {
  152. var lp = (list[p] == undefined) ? list[0] : list[p]; //针对某些aid只有一个cid但是有分P的情况
  153. //console.log(lp);
  154. var cid = lp.cid;
  155. var type = lp.type;
  156. insert_html(type); //UI
  157. //修复360浏览器flash霸占脚本设置区域
  158. $("#bili_fix_script,#bili-fix-player-installed").mouseover(function(){
  159. $("#bofqi,bofqi_embed").addClass("hide");
  160. });
  161. $("#bili_fix_script,#bili-fix-player-installed").mouseout(function(){
  162. $("#bofqi,bofqi_embed").removeClass("hide");
  163. });
  164. var cid_xml_url = 'http://comment.bilibili.com/' + cid + '.xml';
  165. $('#down_cid_xml').attr('href', cid_xml_url); //弹幕下载
  166. Replace_player(aid, cid); //替换播放器
  167. cid_get_videodown_hd(cid); //获取高清下载链接
  168. aid_down_av(aid, page); //av画质下载(单文件)
  169. } else {
  170. window_player_init(); //执行弹窗函数
  171. }
  172. }
  173. }
  174. });
  175. }
  176.  
  177. //弹框播放器支持页面全屏 来自田生
  178. function fix_player_fullwin() {
  179. unsafeWindow.player_fullwin = function(is_full) {
  180. $('#window-player').css({
  181. 'position': is_full ? 'fixed' : 'static'
  182. });
  183. $('.z, .header, .z_top, .footer').css({
  184. 'display': is_full ? 'none' : 'block'
  185. });
  186. }
  187. };
  188. //在新番页面,通过弹窗,获取aid,cid然后进行播放
  189. function aid_build_player(aid) {
  190. var url = 'http://api.bilibili.com/view?type=json&appkey=0a99fa1d87fdd38c&batch=1&id=' + aid;
  191. GM_xmlhttpRequest({
  192. method: 'GET',
  193. url: url,
  194. synchronous: false,
  195. onload: function(responseDetails) {
  196. if (responseDetails.status == 200) {
  197. var Content = eval('(' + responseDetails.responseText + ')');
  198. var list = Content.list;
  199. //默认播放第一个分P-------------------
  200. var p = 0;
  201. var lp = (list[p] == undefined) ? list[0] : list[p];
  202. //console.log(lp);
  203. var cid = lp.cid;
  204. $('#player_content').html(window_player(aid, cid));
  205. //分P列表和播放器------------------------------
  206. for (var i in list) {
  207. //console.log(list[i]);
  208. var cid = list[i].cid;
  209. var p = parseInt(i) + 1;
  210. $('#window_play_list').append('<li class="single_play_list" data-field="aid=' + aid + '&cid=' + cid + '"><a href="javascript:void(0);" style="color:#00A6D8;" >' + p + 'P</a></li>');
  211. }
  212. if (!unsafeWindow.player_fullwin) setTimeout(fix_player_fullwin, 0);
  213. //弹窗的分P播放
  214. $('.single_play_list').click(
  215. function() {
  216. $('#window_play_info').html('正在播放第<span style="color:#F0CF1D">' + $(this).find('a').html() + '</span>');
  217. var info = $(this).attr('data-field');
  218. var pattern = /aid=(\d+)&cid=(\d+)/ig;
  219. var val = pattern.exec(info);
  220. var aid = val === null ? '' : val[1];
  221. var cid = val === null ? '' : val[2];
  222. // console.log(aid,cid);
  223. setTimeout(function() {
  224. $('#player_content').html(window_player(aid, cid));
  225. });
  226. });
  227. }
  228. }
  229. });
  230. }
  231. //弹窗播放器
  232.  
  233. function window_player(aid, cid) {
  234. var width = GM_getValue('player_width');
  235. var height = GM_getValue('player_height');
  236. return '<iframe id="window-player" class="player" src="https://secure.bilibili.com/secure,cid=' + cid + '&amp;aid=' + aid + '" scrolling="no" border="0" framespacing="0" onload="window.securePlayerFrameLoaded=true" frameborder="no" height="' + height + '" width="' + width + '"></iframe> ';
  237. }
  238. //cid获取高清视频链接
  239.  
  240. function cid_get_videodown_hd(cid) {
  241. var url = 'http://interface.bilibili.com/playurl?appkey=0a99fa1d87fdd38c&platform=android&quality=2&cid=' + cid;
  242. GM_xmlhttpRequest({
  243. method: 'GET',
  244. url: url,
  245. synchronous: false,
  246. onload: function(responseDetails) {
  247. if (responseDetails.status == 200) {
  248. var pattern = /<\/(?:(?:chunk)?size|length)>[\s\n]*?<url><\!\[CDATA\[(.*?)\]\]><\/url>/ig;
  249. var c = 1;
  250. while (content = pattern.exec(responseDetails.responseText)) {
  251. var url = content ? (content[1]) : 'http://interface.bilibili.cn/playurl?appkey=0a99fa1d87fdd38c&platform=android&quality=2&cid=' + cid;
  252. insert_download_button(url, c);
  253. c++;
  254. }
  255. }
  256. }
  257. });
  258. }
  259. //低画质视频下载(单文件)
  260.  
  261. function aid_down_av(aid, page) {
  262. var url = 'http://www.bilibili.com/m/html5?aid=' + aid + '&page=' + page;
  263. GM_xmlhttpRequest({
  264. method: 'GET',
  265. url: url,
  266. synchronous: false,
  267. onload: function(responseDetails) {
  268. if (responseDetails.status == 200) {
  269. var Content = eval('(' + responseDetails.responseText + ')');
  270. var downlink = Content.src;
  271. $('#aid_down_av').attr('href', downlink);
  272. }
  273. }
  274. });
  275. }
  276.  
  277. /**
  278. -------------------------------控制 Control-------------------------------------
  279. */
  280.  
  281. function window_player_init() {
  282. //弹窗------------------------------
  283. //新番列表弹窗UI
  284. $('.vd_list .title').each(
  285. function() {
  286. var href = $(this).attr('href');
  287. var pattern = /\/video\/av(\d+)\//ig;
  288. var content = pattern.exec(href);
  289. var aid = content ? (content[1]) : '';
  290. $(this).prepend('<a class="single_player" href="javascript:void(0);" style="color:red;" data-field="' + aid + '">弹▶</a>');
  291. });
  292. //搜索列表弹窗UI
  293. $('.result li .r a').each(
  294. function() {
  295. var href = $(this).attr('href');
  296. var pattern = /\/video\/av(\d+)\//ig;
  297. var content = pattern.exec(href);
  298. var aid = content ? (content[1]) : '';
  299. if (aid != '') {
  300. $(this).find('.t').prepend('<a class="single_player" href="javascript:void(0);" style="color:red;" data-field="' + aid + '">弹▶</a>');
  301. }
  302. });
  303. //带缩略图弹窗UI、和侧栏新投稿弹窗UI、首页的推荐栏弹窗、侧栏列表弹窗UI
  304. $('.video li a,.z-r.new li a,#suggest li a,.rlist li a').each(
  305. function() {
  306. var href = $(this).attr('href');
  307. var pattern = /\/video\/av(\d+)\//ig;
  308. var content = pattern.exec(href);
  309. var aid = content ? (content[1]) : '';
  310. $(this).find('.t').prepend('<a class="single_player" href="javascript:void(0);" style="color:red;" data-field="' + aid + '">弹▶</a>');
  311. });
  312. //弹窗默认的第一P,建立弹窗播放器并建立分P列表===click事件应该在each事件之后执行
  313. $('.single_player').click(
  314. function() {
  315. //$('.dialogcontainter').remove();//防止同时播放两个视频
  316. $('#player-list').remove(); //移除播放列表
  317. var a = '<p id="window_play_title">脚本(`・ω・´)正在加载中</p><div id="player_content">脚本(`・ω・´)播放器正在努力加载中....</div>';
  318. var list_html = '<div id="player-list"><div class="sort"><i>分P列表</i></div><ul id="window_play_list"></ul></div>';
  319. var title = $(this).parent('.t').html() === null ? $(this).parent('.title').html() : $(this).parent('.t').html();
  320. var aid = $(this).attr('data-field');
  321. var title_html = '<a class="mark_my_video" href="javascript:void(0);" style="color:#006766;" data-field="' + aid + '">收藏★</a>&nbsp;&nbsp;&nbsp;<a href="http://www.bilibili.com/video/av' + aid + '/" style="color:#D54851" target="_blank">打开播放页</a>&nbsp;&nbsp;&nbsp;<span style="color:#8C8983">' + title.replace('弹▶', '') + '</span>&nbsp;&nbsp;&nbsp;▶<span id="window_play_info"></span>';
  322. setTimeout(function() {
  323. creat(title_html, a); //创建可视化窗口
  324. $('.dialogcontainter').after(list_html);
  325. $('#window_play_info').html('正在播放第<span style="color:#F0CF1D">1P</span>');
  326. $('#window_play_title').html('<p><a id="div_positon_button" class="button-small button-flat-action" style="background: none repeat scroll 0% 0% #E54C7E;">固定播放器</a><a id="list_control_button" class="button-small button-flat-action" style="background: none repeat scroll 0% 0% #0CB3EE;">收缩分P列表[在左边]</a>[拖动标题可移动播放器,拖动右下角可改变播放器大小,设置后自动保存宽高和位置]</p>');
  327. //切换分P按钮
  328. $('#list_control_button').click(function() {
  329. var flag = $("#player-list").css("display");
  330. if (flag == "none") {
  331. $("#player-list").show();
  332. $('#list_control_button').html('收缩分P列表');
  333. $('#list_control_button').css('background', 'none repeat scroll 0% 0% #0CB3EE');
  334. } else {
  335. $("#player-list").hide();
  336. $('#list_control_button').html('显示分P列表');
  337. $('#list_control_button').css('background', 'none repeat scroll 0% 0% #FF2C14');
  338. }
  339. });
  340. //固定播放器按钮
  341. $('#div_positon_button').click(function() {
  342. var p = $('.dialogcontainter').css('position');
  343. if (p == "fixed") {
  344. $('.dialogcontainter').css('position', 'absolute');
  345. $('#player-list').css('position', 'absolute');
  346. $('#div_positon_button').html('浮动播放器');
  347. $('#div_positon_button').css('background', 'none repeat scroll 0% 0% #FECD3E');
  348. } else {
  349. $('.dialogcontainter').css('position', 'fixed');
  350. $('#player-list').css('position', 'fixed');
  351. $('#div_positon_button').html('固定播放器');
  352. $('#div_positon_button').css('background', 'none repeat scroll 0% 0% #E54C7E');
  353. }
  354. });
  355. //弹窗播放器收藏功能
  356. $('.mark_my_video').click(function() {
  357. var aid = $(this).attr('data-field');
  358. $.ajax({
  359. type: 'POST',
  360. url: 'http://www.bilibili.com/m/stow',
  361. data: 'dopost=save&aid=' + aid + '&stow_target=stow&ajax=1',
  362. success: function(r) {
  363. //$('#edit_status_bar').html(r);
  364. alert('收藏成功');
  365. },
  366. error: function(r) {
  367. alert('出错,请重试!');
  368. },
  369. dataType: 'text'
  370. });
  371. });
  372. }, 0);
  373. setTimeout(function() {
  374. aid_build_player(aid);
  375. }, 0);
  376. });
  377. }
  378. //END弹窗------------------------------
  379.  
  380. //替换播放器----------------------------
  381. //取出aid和分P
  382. var url = document.location.href;
  383. var aid_reg = /\/av(\d+)\/(?:index_(\d+)\.html)?/ig;
  384. var aid_array = aid_reg.exec(url);
  385.  
  386. var aid = aid_array === null ? '' : aid_array[1]; //aid
  387. var page = aid_array === null ? '1' : typeof(aid_array[2]) == 'undefined' ? '1' : aid_array[2]; //分p
  388.  
  389. //播放器的html
  390. var content; //本脚本使用了很多content变量,其中cid_get_videodown函数的while循环content变量全局,如果此处未定义content,火狐会报权限问题
  391. api_get_cid(aid, page); //按照aid和分p获取cid并且替换播放器
  392.  
  393. //当设置悬浮评论分页栏时,增加css
  394. if (GM_getValue('pagebox_display') == 1) {
  395. var css='.pagelistbox{position:fixed;bottom:100px; right:0px;background-image:url("http://nightlyfantasy.github.io/Bili_Fix_Player/bg.png");}';
  396. GM_addStyle(css);
  397. }
  398. //css插入
  399. var css = '.bfpbtn{font-size:12px;height:25.6px;line-height:25.6px;padding:0px 2px;transition-property:#000,color;transition-duration:0.3s;box-shadow:none;color:#FFF;text-shadow:none;border:medium none;background:none repeat scroll 0% 0% #00A1CB!important;}.bfpbtn.active{background:none repeat scroll 0% 0% #F489AD!important;}.bfpbtn.notice{background-color:#A300C0!important;}.font{font-size:11px!important;}#window_play_list li{float:left;position:relative;width:5em;border:1px solid #B0C4DE;font:80% Verdana,Geneva,Arial,Helvetica,sans-serif;}.ui.corner.label{height:0px;border-width:0px 3em 3em 0px;border-style:solid;border-top:0px solid transparent;border-bottom:3em solid transparent;border-left:0px solid transparent;border-right-color:rgb(217,92,92)!important;transition:border-color 0.2s ease 0s;position:absolute;content:"";right:0px;top:0px;z-index:-1;width:0px;}.ui.corner.label i{display:inline-block;margin:3px 0.25em 0px 17px;width:1.23em;height:1em;font-weight:800!important;}.dialogcontainter{height:400px;width:400px;border:1px solid #14495f;position:fixed;font-size:13px;}.dialogtitle{height:26px;width:auto;background-color:#C6C6C6;}.dialogtitleinfo{float:left;height:20px;margin-top:2px;margin-left:10px;line-height:20px;vertical-align:middle;color:#FFFFFF;font-weight:bold;}.dialogtitleico{float:right;height:20px;width:21px;margin-top:2px;margin-right:5px;text-align:center;line-height:20px;vertical-align:middle;background-image:url("http://nightlyfantasy.github.io/Bili_Fix_Player/bg.gif");background-position:-21px 0px}.dialogbody{padding:10px;width:auto;background-color:#FFFFFF;background-image:url("http://nightlyfantasy.github.io/Bili_Fix_Player/bg.png");}.dialogbottom{bottom:1px;right:1px;cursor:nw-resize;position:absolute;background-image:url("http://nightlyfantasy.github.io/Bili_Fix_Player/bg.gif");background-position:-42px -10px;width:10px;height:10px;font-size:0;}.button-small{font-size:12px;height:25.6px;line-height:25.6px;padding:0px 5px;}.button-flat-action{transition-duration:0.3s;box-shadow:none;background:none repeat scroll 0% 0% #7DB500;color:#FFF!important;text-shadow:none;border:medium none;border-radius:3px;}#player-list{position:fixed;z-index:1000;left:10px;top:50px;width:400px!important;background-image:url("http://nightlyfantasy.github.io/Bili_Fix_Player/bg.png");min-height:200px!Important;}#player_content{position:absolute;top:60px;left:10px;right:10px;bottom:10px;}#window-player{bottom:0;height:100%;left:0;right:0;top:0;width:100%;}a.single_player{display:none;}a:hover .single_player{display:inline;}#bofqi_embed.hide,#bofqi.hide,#player_content.hide{margin-left:3000px!important;transition:0.5s;-moz-transition:0.5s;-webkit-transition:0.5s;-o-transition:0.5s;}#bofqi_embed,#bofqi,#player_content{transition:0.5s;-moz-transition:0.5s;-webkit-transition:0.5s;-o-transition:0.5s;}';
  400. GM_addStyle(css);
  401.  
  402. //高大上的拖动DIV和改变DIV大小功能,来自互联网脚本之家www.jb51.net
  403. var z = 1,i = 1,left = 10;
  404. var isIE = (document.all) ? true : false;
  405. var Extend = function(destination, source) {
  406. for (var property in source) {
  407. destination[property] = source[property];
  408. }
  409. }
  410.  
  411. var Bind = function(object, fun, args) {
  412. return function() {
  413. return fun.apply(object, args || []);
  414. }
  415. }
  416.  
  417. var BindAsEventListener = function(object, fun) {
  418. var args = Array.prototype.slice.call(arguments).slice(2);
  419. return function(event) {
  420. return fun.apply(object, [event || window.event].concat(args));
  421. }
  422. }
  423.  
  424. var CurrentStyle = function(element) {
  425. return element.currentStyle || document.defaultView.getComputedStyle(element, null);
  426. }
  427.  
  428. function create(elm, parent, fn) {
  429. var element = document.createElement(elm);
  430. fn && fn(element);
  431. parent && parent.appendChild(element);
  432. return element
  433. };
  434.  
  435. function addListener(element, e, fn) {
  436. element.addEventListener ? element.addEventListener(e, fn, false) : element.attachEvent("on" + e, fn)
  437. };
  438.  
  439. function removeListener(element, e, fn) {
  440. element.removeEventListener ? element.removeEventListener(e, fn, false) : element.detachEvent("on" + e, fn)
  441. };
  442.  
  443. var Class = function(properties) {
  444. var _class = function() {
  445. return (arguments[0] !== null && this.initialize && typeof(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
  446. };
  447. _class.prototype = properties;
  448. return _class;
  449. };
  450.  
  451. var Dialog = new Class({
  452. options: {
  453. Width: 400,
  454. Height: 400,
  455. Left: 100,
  456. Top: 10,
  457. Titleheight: 26,
  458. Minwidth: 200,
  459. Minheight: 200,
  460. CancelIco: true,
  461. ResizeIco: true,
  462. Info: "标题",
  463. Content: "无内容",
  464. Zindex: 2
  465. },
  466. initialize: function(options) {
  467. this._dragobj = null;
  468. this._resize = null;
  469. this._cancel = null;
  470. this._body = null;
  471. this._x = 0;
  472. this._y = 0;
  473. this._fM = BindAsEventListener(this, this.Move);
  474. this._fS = Bind(this, this.Stop);
  475. this._isdrag = null;
  476. this._Css = null;
  477. ////////////////////////////////////////////////////////////////////////////////
  478. this.Width = this.options.Width;
  479. this.Height = this.options.Height;
  480. this.Left = this.options.Left;
  481. this.Top = this.options.Top;
  482. this.CancelIco = this.options.CancelIco;
  483. this.Info = this.options.Info;
  484. this.Content = this.options.Content;
  485. this.Minwidth = this.options.Minwidth;
  486. this.Minheight = this.options.Minheight;
  487. this.Titleheight = this.options.Titleheight;
  488. this.Zindex = this.options.Zindex;
  489. Extend(this, options);
  490. Dialog.Zindex = this.Zindex
  491. //////////////////////////////////////////////////////////////////////////////// 构造dialog
  492. var obj = ['dialogcontainter', 'dialogtitle', 'dialogtitleinfo', 'dialogtitleico', 'dialogbody', 'dialogbottom'];
  493. for (var i = 0; i < obj.length; i++) {
  494. obj[i] = create('div', null, function(elm) {
  495. elm.className = obj[i];
  496. });
  497. }
  498. obj[2].innerHTML = this.Info;
  499. obj[4].innerHTML = this.Content;
  500. obj[1].appendChild(obj[2]);
  501. obj[1].appendChild(obj[3]);
  502. obj[0].appendChild(obj[1]);
  503. obj[0].appendChild(obj[4]);
  504. obj[0].appendChild(obj[5]);
  505. document.body.appendChild(obj[0]);
  506. this._dragobj = obj[0];
  507. this._resize = obj[5];
  508. this._cancel = obj[3];
  509. this._body = obj[4];
  510. ////////////////////////////////////////////////////////////////////////////////o,x1,x2
  511. ////设置Dialog的长 宽 ,left ,top
  512. with(this._dragobj.style) {
  513. height = this.Height + "px";
  514. top = this.Top + "px";
  515. width = this.Width + "px";
  516. left = this.Left + "px";
  517. zIndex = this.Zindex;
  518. }
  519. this._body.style.height = this.Height - this.Titleheight - parseInt(CurrentStyle(this._body).paddingLeft) * 2 + 'px';
  520. /////////////////////////////////////////////////////////////////////////////// 添加事件
  521. addListener(this._dragobj, 'mousedown', BindAsEventListener(this, this.Start, true));
  522. addListener(this._cancel, 'mouseover', Bind(this, this.Changebg, [this._cancel, '0px 0px', '-21px 0px']));
  523. addListener(this._cancel, 'mouseout', Bind(this, this.Changebg, [this._cancel, '0px 0px', '-21px 0px']));
  524. addListener(this._cancel, 'mousedown', BindAsEventListener(this, this.Disappear));
  525. addListener(this._body, 'mousedown', BindAsEventListener(this, this.Cancelbubble));
  526. addListener(this._resize, 'mousedown', BindAsEventListener(this, this.Start, false));
  527. },
  528. Disappear: function(e) {
  529. this.Cancelbubble(e);
  530. document.body.removeChild(this._dragobj);
  531. $('#player-list').remove();
  532. },
  533. Cancelbubble: function(e) {
  534. this._dragobj.style.zIndex = ++Dialog.Zindex;
  535. document.all ? (e.cancelBubble = true) : (e.stopPropagation())
  536. },
  537. Changebg: function(o, x1, x2) {
  538. o.style.backgroundPosition = (o.style.backgroundPosition == x1) ? x2 : x1;
  539. },
  540. Start: function(e, isdrag) {
  541. if (!isdrag) {
  542. this.Cancelbubble(e);
  543. }
  544. this._Css = isdrag ? {
  545. x: "left",
  546. y: "top"
  547. } : {
  548. x: "width",
  549. y: "height"
  550. }
  551. this._dragobj.style.zIndex = ++Dialog.Zindex;
  552. this._isdrag = isdrag;
  553. this._x = isdrag ? (e.clientX - this._dragobj.offsetLeft || 0) : (this._dragobj.offsetLeft || 0);
  554. this._y = isdrag ? (e.clientY - this._dragobj.offsetTop || 0) : (this._dragobj.offsetTop || 0);
  555. if (isIE) {
  556. addListener(this._dragobj, "losecapture", this._fS);
  557. this._dragobj.setCapture();
  558. } else {
  559. e.preventDefault();
  560. addListener(window, "blur", this._fS);
  561. }
  562. addListener(document, 'mousemove', this._fM);
  563. addListener(document, 'mouseup', this._fS);
  564. $("#player_content").addClass("hide");
  565. },
  566. Move: function(e) {
  567. window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
  568. var i_x = e.clientX - this._x,
  569. i_y = e.clientY - this._y;
  570. this._dragobj.style[this._Css.x] = (this._isdrag ? Math.max(i_x, 0) : Math.max(i_x, this.Minwidth)) + 'px';
  571. this._dragobj.style[this._Css.y] = (this._isdrag ? Math.max(i_y, 0) : Math.max(i_y, this.Minheight)) + 'px'
  572. if (!this._isdrag)
  573. this._body.style.height = Math.max(i_y - this.Titleheight, this.Minheight - this.Titleheight) - 2 * parseInt(CurrentStyle(this._body).paddingLeft) + 'px';
  574. },
  575. Stop: function() {
  576. $("#player_content").removeClass("hide");
  577. removeListener(document, 'mousemove', this._fM);
  578. removeListener(document, 'mouseup', this._fS);
  579. //实时改变播放器大小,保存播放器大小
  580. $('#window-player').width($('.dialogcontainter').width() - 20);
  581. GM_setValue('player_width', ($('.dialogcontainter').width() - 20));
  582. $('#window-player').height($('.dialogcontainter').height() - 70);
  583. GM_setValue('player_height', ($('.dialogcontainter').height() - 70));
  584. //保存位置
  585. //GM_setValue('div_top', ($('.dialogcontainter').offset().top));//设置垂直位置的时候,如果是长页而且是浮动播放器时候记录位置,会导致播放器不知所踪
  586. GM_setValue('div_left', ($('.dialogcontainter').offset().left));
  587. if (isIE) {
  588. removeListener(this._dragobj, "losecapture", this._fS);
  589. this._dragobj.releaseCapture();
  590. } else {
  591. removeListener(window, "blur", this._fS);
  592. };
  593. }
  594. })
  595.  
  596. function creat(title, content) {
  597. $('.dialogcontainter').remove();
  598. new Dialog({
  599. Info: title = title,
  600. Left: GM_getValue('div_left'),
  601. Top: 50,
  602. Width: (GM_getValue('player_width') + 20),
  603. Height: (GM_getValue('player_height') + 70),
  604. Content: content,
  605. Zindex: (2000)
  606. });
  607. i++;
  608. left += 10;
  609. }
  610. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址