BiibiliTimer

B站H5播放器全屏时实时显示当前系统时间和播放进度

目前为 2017-10-22 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name BiibiliTimer
  3. // @version 2.1.0
  4. // @description B站H5播放器全屏时实时显示当前系统时间和播放进度
  5. // @author AnnAngela
  6. // @match *://www.bilibili.com/video/av*
  7. // @match *://www.bilibili.com/watchlater*
  8. // @match *://www.bilibili.com/html/*layer.htm*
  9. // @match *://www.bilibili.com/blackboard/*layer.htm*
  10. // @match *://live.bilibili.com/*
  11. // @compatible chrome 自Chrome 50开始兼容
  12. // @icon data:image/png;base64,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
  13. // @icon64 data:image/png;base64,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
  14. // @run-at document-start
  15. // @grant unsafeWindow
  16. // @grant GM_addStyle
  17. // @grant GM_setValue
  18. // @grant GM_getValue
  19. // @grant GM_deleteValue
  20. // @namespace https://greasyfork.org/users/129402
  21. // ==/UserScript==
  22.  
  23. (function() {
  24. 'use strict';
  25. /* 防止重复加载 */
  26. if (unsafeWindow.BilibiliTimer) return;
  27.  
  28. unsafeWindow.console.debug('%c' + GM_info.script.name + '@' + GM_info.script.version + ' by ' + GM_info.script.author + ' is running!', "padding: 32px 66px 32px 64px; line-height: 64px; background:url('" + GM_info.script.icon64 + "') top left no-repeat;");
  29. unsafeWindow.BilibiliTimerUninit = false;
  30. unsafeWindow.BilibiliTimerGM = {
  31. set: GM_setValue,
  32. get: GM_getValue,
  33. delete: GM_deleteValue
  34. };
  35. unsafeWindow.BilibiliTimer = {};
  36. /*
  37. * 出于实现上的考虑,以下代码被保存为纯文本,并通过unsafeWindow.eval运行,以操作真实环境下的DOM节点
  38. */
  39. var code = [
  40. "(function() {",
  41. " 'use strict';",
  42. " if (window.BilibiliTimerUninit || !window.jQuery) return false;",
  43. " if (!String.prototype.includes) String.prototype.includes = function includes(s) {",
  44. " return this.indexOf(s) !== -1;",
  45. " };",
  46. " var BilibiliTimer = window.BilibiliTimer || (window.BilibiliTimer = {});",
  47. " var LF = String.fromCharCode(10);",
  48. " BilibiliTimer.date = function bilibiliPlayerDate() {",
  49. " var _date = new Date();",
  50. " ['getDate', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getUTCDate', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear'].forEach(function(key) {",
  51. " _date[key] = function() {",
  52. " var result = Date.prototype[key].apply(_date, arguments);",
  53. " if (key.includes('Month')) result++;",
  54. " if (typeof result === 'number' && (result + '').length === 1) return '0' + result;",
  55. " else return result + '';",
  56. " };",
  57. " });",
  58. " return _date;",
  59. " };",
  60. " try {",
  61. " BilibiliTimer.isEmbedded = location.host === 'www.bilibili.com' && location.pathname === '/blackboard/html5player.html' && top !== window && top.location.host === 'bangumi.bilibili.com';",
  62. " } catch(_) {",
  63. " BilibiliTimer.isEmbedded = false;",
  64. " }",
  65. " BilibiliTimer.isLive = function bilibiliIsLive(a, b) {",
  66. " return location.host === 'live.bilibili.com' ? (a !== undefined ? a : true) : (b !== undefined ? b : false);",
  67. " };",
  68. " BilibiliTimer.selector = BilibiliTimer.isLive({",
  69. " container: '.bilibili-live-player-video-area',",
  70. " controller: '.bilibili-live-player-video-controller',",
  71. " fullscreenSendbar: null,",
  72. " autoHideButton: '.attend-button .right-part',",
  73. " autoHideButtonText: '.BilibiliTimerAutoHideButtonText',",
  74. " autoHideCheck: null,",
  75. " pageTitle: null,",
  76. " watchlaterPageTitle: null,",
  77. " watchlaterVideoTitle: null",
  78. " }, {",
  79. " container: '.bilibili-player-video-wrap',",
  80. " controller: '.bilibili-player-video-control',",
  81. " fullscreenSendbar: '.bilibili-player-video-sendbar.active',",
  82. " autoHideButton: '.bgray-btn-wrap .bgray-btn.show',",
  83. " autoHideButtonText: '.BilibiliTimerAutoHideButtonText',",
  84. " autoHideCheck: '.bilibili-player-no-cursor',",
  85. " pageTitle: '#plist .curPage ',",
  86. " watchlaterPageTitle: '.bilibili-player-auxiliary-area .bilibili-player-watchlater-part-item[data-state-play=true] .bilibili-player-watchlater-plist-chapter',",
  87. " watchlaterVideoTitle: '.bilibili-player-auxiliary-area .bilibili-player-watchlater-item[data-state-play=true] .bilibili-player-watchlater-info-title'",
  88. " });",
  89. " BilibiliTimer.classList = BilibiliTimer.isLive({",
  90. " timer: 'bilibili-live-player-video-info-container',",
  91. " closeButton: 'bilibili-live-player-video-info-close',",
  92. " panel: 'bilibili-live-player-video-info-panel',",
  93. " restartButton: 'live-icon-reload',",
  94. " autoHideButton: 'mid-part BilibiliTimerAutoHideButton',",
  95. " autoHideButtonText: 'BilibiliTimerAutoHideButtonText'",
  96. " }, {",
  97. " timer: 'bilibili-player-video-info-container',",
  98. " closeButton: 'bilibili-player-video-info-close',",
  99. " panel: 'bilibili-player-video-info-panel',",
  100. " restartButton: 'bilibili-player-iconfont icon-24repeaton',",
  101. " autoHideButton: 'bgray-btn show BilibiliTimerAutoHideButton',",
  102. " autoHideButtonText: 'BilibiliTimerAutoHideButtonText'",
  103. " });",
  104. " BilibiliTimer.closeButtonText = BilibiliTimer.isLive('x', '[x]');",
  105. " BilibiliTimer.globallock = false;",
  106. " BilibiliTimer.widthSet = false;",
  107. " BilibiliTimer.onResizing = 0;",
  108. " if (BilibiliTimer.selector.autoHideCheck) BilibiliTimer.mousemoveCount = 0;",
  109. " BilibiliTimer.getControllerTop = function BilibiliTimerGetControllerTop() {",
  110. " var controller = $(BilibiliTimer.selector.controller);",
  111. " if (controller.closest('.mode-miniscreen')[0]) return $(window).height();",
  112. " var _top = $(window).height() - controller.height();",
  113. " var fullscreenSendbar = $(BilibiliTimer.selector.fullscreenSendbar);",
  114. " if (fullscreenSendbar[0]) _top -= fullscreenSendbar.outerHeight(true);",
  115. " return _top;",
  116. " };",
  117. " $(window).on('resize.BilibiliTimer', function() {",
  118. " BilibiliTimer.onResizing = 1;",
  119. " });",
  120. " $(document).on({",
  121. " 'mousemove.BilibiliTimer': function(e) {",
  122. " var BilibiliTimer = window.BilibiliTimer;",
  123. " if (BilibiliTimer && BilibiliTimer.timer) {",
  124. " if (BilibiliTimer.timer.data('onMousedown')) {",
  125. " var maxTop = BilibiliTimer.getControllerTop() - BilibiliTimer.timer.outerHeight() - 10;",
  126. " var maxLeft = $(window).width() - BilibiliTimer.timer.outerWidth() - 10;",
  127. " BilibiliTimer.timer.css({",
  128. " left: Math.max(Math.min(BilibiliTimer.timer.data('baseOffset').left + e.clientX, maxLeft), 10),",
  129. " top: Math.max(Math.min(BilibiliTimer.timer.data('baseOffset').top + e.clientY, maxTop), 10)",
  130. " });",
  131. " window.getSelection().removeAllRanges();",
  132. " }",
  133. " if (BilibiliTimer.selector.autoHideCheck) BilibiliTimer.mousemoveCount = 0;",
  134. " }",
  135. " },",
  136. " 'mouseup.BilibiliTimer': function(e) {",
  137. " var BilibiliTimer = window.BilibiliTimer;",
  138. " if (BilibiliTimer && BilibiliTimer.timer && BilibiliTimer.timer.data('onMousedown')) {",
  139. " BilibiliTimer.timer.data('onMousedown', false);",
  140. " BilibiliTimerGM.set('offset', {",
  141. " top: BilibiliTimer.timer.css('top'),",
  142. " left: BilibiliTimer.timer.css('left')",
  143. " });",
  144. " }",
  145. " }",
  146. " });",
  147. " BilibiliTimer.template = {};",
  148. " var timer = BilibiliTimer.template.timer = $('<div/>');",
  149. " timer.attr('id', 'BilibiliTimer').addClass(BilibiliTimer.classList.timer);",
  150. " var closeButton = BilibiliTimer.template.closeButton = $('<a/>');",
  151. " closeButton.text(BilibiliTimer.closeButtonText).attr({",
  152. " href: 'javascript:void(0);',",
  153. " id: 'BilibiliTimerCloseButton'",
  154. " });",
  155. " closeButton.addClass(BilibiliTimer.classList.closeButton);",
  156. " var restartButton = BilibiliTimer.template.restartButton = $('<a/>');",
  157. " restartButton.attr({",
  158. " href: 'javascript:void(0);',",
  159. " id: 'BilibiliTimerRestartButton',",
  160. " title: '如果发现浮窗出现问题,' + LF + '例如无法正常拖动,无法正常显示时间等,' + LF + '请点击该按钮重建浮窗尝试修复!'",
  161. " });",
  162. " restartButton.addClass(BilibiliTimer.classList.closeButton).addClass(BilibiliTimer.classList.restartButton);",
  163. " var panel = BilibiliTimer.template.panel = $('<div/>');",
  164. " panel.addClass(BilibiliTimer.classList.panel);",
  165. " panel.append(\"<div class='info-line'><span class='info-title'>系统时间:</span><span class='info-data' id='BilibiliTimerNowTime'> - </span></div>\");",
  166. " panel.append(BilibiliTimer.isLive(\"<div class='info-line'><span class='info-title'>缓冲质量:</span><span class='info-data'>当前缓冲时长 <span id='BilibiliTimerVideoBufferedTimeRange'> - </span>s</span></div>\", \"<div class='info-line'><span class='info-title'>播放进度:</span><span class='info-data' id='BilibiliTimerVideoTime'> - </span></div><div class='info-line'><span class='info-title'>加载进度:</span><span class='info-data'><span id='BilibiliTimerVideoBufferedTime'> - </span>(剩余缓冲时长<span id='BilibiliTimerVideoBufferedTimeRange'> - </span>s,已缓冲<span id='BilibiliTimerVideoBufferedTimePercents'> - </span>%)</span></div><div class='info-line' style='display: none;'><span class='info-title' id='BilibiliTimerTitleDescription'>当前分页:</span><span class='info-data' id='BilibiliTimerTitle'> - </span></div>\"));",
  167. " var autoHideButton = BilibiliTimer.template.autoHideButton = $('<div/>');",
  168. " autoHideButton.addClass(BilibiliTimer.classList.autoHideButton);",
  169. " autoHideButton.css(BilibiliTimer.isLive('width', 'height'), 'auto');",
  170. " autoHideButton.html('浮窗自动隐藏' + BilibiliTimer.isLive('|', '<hr/>'));",
  171. " var autoHideButtonText = $('<span/>');",
  172. " autoHideButtonText.addClass(BilibiliTimer.classList.autoHideButtonText);",
  173. " if (!BilibiliTimerGM.get('autoHidden')) {",
  174. " BilibiliTimerGM.set('autoHidden', false);",
  175. " autoHideButtonText.text('OFF');",
  176. " } else autoHideButtonText.text('ON');",
  177. " autoHideButton.append(autoHideButtonText);",
  178. " BilibiliTimer.init = function BilibiliTimerInit() {",
  179. " if (window.BilibiliTimerUninit) return false;",
  180. " BilibiliTimer.onResizing = 0;",
  181. " BilibiliTimer.widthSet = false;",
  182. " BilibiliTimer.timer = BilibiliTimer.template.timer.clone();",
  183. " BilibiliTimer.closeButton = BilibiliTimer.template.closeButton.clone();",
  184. " BilibiliTimer.restartButton = BilibiliTimer.template.restartButton.clone();",
  185. " BilibiliTimer.panel = BilibiliTimer.template.panel.clone();",
  186. " BilibiliTimer.autoHideButton = BilibiliTimer.template.autoHideButton.clone();",
  187. " BilibiliTimer.timer.append(BilibiliTimer.closeButton).append(BilibiliTimer.restartButton).append(BilibiliTimer.panel);",
  188. " var title = null,",
  189. " description = null;",
  190. " if ($(BilibiliTimer.selector.pageTitle)[0]) title = $(BilibiliTimer.selector.pageTitle).text();",
  191. " else if ($(BilibiliTimer.selector.watchlaterPageTitle)[0]) {",
  192. " description = '当前分页:<br>(稍后再看)';",
  193. " title = ($(BilibiliTimer.selector.watchlaterPageTitle).closest('li').index() + 1) + '、' + $(BilibiliTimer.selector.watchlaterPageTitle).text();",
  194. " }",
  195. " if ($(BilibiliTimer.selector.watchlaterVideoTitle)[0]) {",
  196. " if (!description) description = '当前视频:<br>(稍后再看)';",
  197. " title = ($(BilibiliTimer.selector.watchlaterVideoTitle).closest('li').index() + 1) + '、' + $(BilibiliTimer.selector.watchlaterVideoTitle).text() + '<br>' + (title ? '(' + title + ')' : '');",
  198. " }",
  199. " if (title) BilibiliTimer.timer.find('#BilibiliTimerTitle').html(title).parent().removeAttr('style');",
  200. " if (description) BilibiliTimer.timer.find('#BilibiliTimerTitleDescription').html(description);",
  201. " $((BilibiliTimer.isEmbedded ? top : window).document.querySelector(BilibiliTimer.selector.autoHideButton)).before(BilibiliTimer.autoHideButton);",
  202. " BilibiliTimer.autoHideButtonText = BilibiliTimer.autoHideButton.find(BilibiliTimer.selector.autoHideButtonText);",
  203. " BilibiliTimer.timer.on('mousedown', function(e) {",
  204. " var baseX = Math.max(e.clientX, 0);",
  205. " var baseY = Math.max(e.clientY, 0);",
  206. " var baseOffsetX = Math.max(parseInt(BilibiliTimer.timer.css('left')), 0);",
  207. " var baseOffsetY = Math.max(parseInt(BilibiliTimer.timer.css('top')), 0);",
  208. " BilibiliTimer.timer.data({",
  209. " baseOffset: {",
  210. " left: baseOffsetX - baseX,",
  211. " top: baseOffsetY - baseY",
  212. " },",
  213. " onMousedown: true",
  214. " });",
  215. " });",
  216. " BilibiliTimer.closeButton.on('click', function() {",
  217. " BilibiliTimer.globallock = true;",
  218. " BilibiliTimer.timer.fadeOut(370);",
  219. " });",
  220. " BilibiliTimer.restartButton.on('click', BilibiliTimer.restart.bind(BilibiliTimer));",
  221. " BilibiliTimer.autoHideButton.on('click', function() {",
  222. " if (BilibiliTimerGM.get('autoHidden')) {",
  223. " BilibiliTimerGM.set('autoHidden', false);",
  224. " BilibiliTimer.autoHideButtonText.text('OFF');",
  225. " } else {",
  226. " BilibiliTimerGM.set('autoHidden', true);",
  227. " BilibiliTimer.autoHideButtonText.text('ON');",
  228. " }",
  229. " });",
  230. " if (!BilibiliTimerGM.get('offset')) {",
  231. " BilibiliTimer.timer.css({",
  232. " right: '10px',",
  233. " top: '10px'",
  234. " }).css({",
  235. " left: BilibiliTimer.timer.offset().left + 'px',",
  236. " right: 'auto'",
  237. " });",
  238. " } else BilibiliTimer.timer.css(BilibiliTimerGM.get('offset'));",
  239. " $(BilibiliTimer.selector.container).append(BilibiliTimer.timer);",
  240. " $(window).resize();",
  241. " };",
  242. " BilibiliTimer.globalWatcher = function BilibiliTimerGlobalWatcher() {",
  243. " if (window.BilibiliTimerUninit) return false;",
  244. " var timer = BilibiliTimer.timer;",
  245. " if (!timer || !timer[0]) {",
  246. " BilibiliTimer.init();",
  247. " return;",
  248. " }",
  249. " if ($('object#player_placeholder, object#player_object')[0]) {",
  250. " BilibiliTimer.uninit();",
  251. " return;",
  252. " }",
  253. " if (!timer.closest('body')[0]) {",
  254. " BilibiliTimer.restart();",
  255. " return;",
  256. " }",
  257. " if (!!$(':-webkit-full-screen')[0]) {",
  258. " if ((BilibiliTimer.selector.autoHideCheck ? !$(BilibiliTimer.selector.autoHideCheck)[0] : BilibiliTimer.mousemoveCount < 3) && BilibiliTimer.autoHidden) BilibiliTimer.autoHidden = false;",
  259. " if (!BilibiliTimer.globallock && !BilibiliTimer.autoHidden) {",
  260. " if (!timer.is(':visible')) timer.fadeIn();",
  261. " if (BilibiliTimer.onResizing === 2) {",
  262. " BilibiliTimer.onResizing = 0;",
  263. " var maxTop = BilibiliTimer.getControllerTop() - timer.outerHeight() - 10;",
  264. " var maxLeft = $(window).width() - timer.outerWidth() - 10;",
  265. " timer.css({",
  266. " left: Math.max(Math.min(parseInt(timer.css('left')), maxLeft), 10),",
  267. " top: Math.max(Math.min(parseInt(timer.css('top')), maxTop), 10)",
  268. " });",
  269. " BilibiliTimerGM.set('offset', {",
  270. " top: timer.css('top'),",
  271. " left: timer.css('left')",
  272. " });",
  273. " } else if (BilibiliTimer.onResizing === 1) {",
  274. " BilibiliTimer.onResizing = 2;",
  275. " }",
  276. " }",
  277. " } else {",
  278. " BilibiliTimer.onResizing = 0;",
  279. " BilibiliTimer.globallock = false;",
  280. " timer.fadeOut();",
  281. " }",
  282. " if (timer.is(':visible')) {",
  283. " var date = BilibiliTimer.date();",
  284. " timer.find('#BilibiliTimerNowTime').text(date.getFullYear() + '-' + date.getMonth() + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds());",
  285. " if (!BilibiliTimer.widthSet) BilibiliTimer.widthCalc();",
  286. " }",
  287. " var video = $('video');",
  288. " if (!video.data('onListened')) {",
  289. " video.data('onListened', true);",
  290. " video.on({",
  291. " 'timeupdate.BilibiliTimer': BilibiliTimer.videoPlayListener.bind(BilibiliTimer),",
  292. " 'progress.BilibiliTimer': BilibiliTimer.videoProgressListener.bind(BilibiliTimer)",
  293. " });",
  294. " }",
  295. " };",
  296. " BilibiliTimer.autoHideWatcher = function BilibiliTimerAutoHideWatcher() {",
  297. " if (!BilibiliTimerGM.get('autoHidden')) return;",
  298. " if ((BilibiliTimer.selector.autoHideCheck ? $(BilibiliTimer.selector.autoHideCheck)[0] : BilibiliTimer.mousemoveCount >= 3)) {",
  299. " BilibiliTimer.autoHidden = true;",
  300. " BilibiliTimer.timer.fadeOut(370);",
  301. " }",
  302. " if (BilibiliTimer.selector.autoHideCheck) BilibiliTimer.mousemoveCount++;",
  303. " };",
  304. " BilibiliTimer.widthWatcher = function BilibiliTimerWidthWatcher() {",
  305. " var BilibiliTimer = window.BilibiliTimer;",
  306. " if (!BilibiliTimer || !BilibiliTimer.timer) return;",
  307. " if (BilibiliTimer.timer.find('.info-line').width() > BilibiliTimer.timer.width()) BilibiliTimer.widthCalc();",
  308. " };",
  309. " BilibiliTimer.widthCalc = function BilibiliTimerWidthCalc() {",
  310. " var BilibiliTimer = window.BilibiliTimer;",
  311. " if (!BilibiliTimer || !BilibiliTimer.timer) return;",
  312. " var timer = BilibiliTimer.timer;",
  313. " var maxWidth = 0;",
  314. " timer.find('.info-line').each(function() {",
  315. " var width = 0,",
  316. " maxHeight = 0;",
  317. " $(this).children().each(function() {",
  318. " width += $(this).outerWidth(true);",
  319. " if (maxHeight < $(this).height()) maxHeight = $(this).height();",
  320. " });",
  321. " if (maxWidth < width) maxWidth = width;",
  322. " $(this).height(maxHeight);",
  323. " });",
  324. " timer.width(maxWidth);",
  325. " BilibiliTimer.widthSet = true;",
  326. " };",
  327. " BilibiliTimer.timeParse = function BilibiliTimerTimeParse(time) {",
  328. " time = parseInt(time)",
  329. " var sec = time % 60,",
  330. " min = (time - sec) / 60;",
  331. " if (sec < 10) sec = '0' + sec;",
  332. " return min + ':' + sec;",
  333. " };",
  334. " BilibiliTimer.videoPlayListener = function BilibiliTimerVideoPlayListener(e) {",
  335. " if (!e.target) return;",
  336. " var video = e.target;",
  337. " var curTime = video.currentTime || 0;",
  338. " var durTime = video.duration || 0;",
  339. " if (!curTime || !durTime) return;",
  340. " var BilibiliTimer = window.BilibiliTimer;",
  341. " if (BilibiliTimer && BilibiliTimer.timer) BilibiliTimer.timer.find('#BilibiliTimerVideoTime').text(BilibiliTimer.timeParse(curTime) + '/' + BilibiliTimer.timeParse(durTime));",
  342. " if (BilibiliTimer.timer.find('#BilibiliTimerVideoBufferedTime')[0]) {",
  343. " var video = e.target,",
  344. " end;",
  345. " try {",
  346. " end = video.buffered.end(video.buffered.length - 1);",
  347. " } catch (_) {",
  348. " try {",
  349. " end = video.buffered.end(0);",
  350. " } catch (_) {",
  351. " return;",
  352. " }",
  353. " }",
  354. " if (timer.find('#BilibiliTimerVideoBufferedTime').text() === ' - ') video.trigger('progress');",
  355. " BilibiliTimer.timer.find('#BilibiliTimerVideoBufferedTimeRange').text((end - curTime).toFixed(0))",
  356. " }",
  357. " };",
  358. " BilibiliTimer.videoProgressListener = function BilibiliTimerVideoProgressListener(e) {",
  359. " var BilibiliTimer = window.BilibiliTimer;",
  360. " if (!BilibiliTimer || !BilibiliTimer.timer) return;",
  361. " var timer = BilibiliTimer.timer;",
  362. " if (timer.find('#BilibiliTimerVideoBufferedTimeRange')[0]) {",
  363. " var video = e.target,",
  364. " end;",
  365. " try {",
  366. " end = video.buffered.end(video.buffered.length - 1);",
  367. " } catch (_) {",
  368. " try {",
  369. " end = video.buffered.end(0);",
  370. " } catch (_) {",
  371. " return;",
  372. " }",
  373. " }",
  374. " if (timer.find('#BilibiliTimerVideoBufferedTimeRange').text() === ' - ') BilibiliTimer.widthSet = false;",
  375. " timer.find('#BilibiliTimerVideoBufferedTime').text(BilibiliTimer.timeParse(end));",
  376. " BilibiliTimer.timer.find('#BilibiliTimerVideoBufferedTimeRange').text((end - video.currentTime).toFixed(0))",
  377. " timer.find('#BilibiliTimerVideoBufferedTimePercents').text((end * 100 / video.duration).toFixed(2));",
  378. " }",
  379. " }",
  380. " BilibiliTimer.start = function BilibiliTimerStart() {",
  381. " if (window.BilibiliTimerUninit) return false;",
  382. " if (location.host === 'bangumi.bilibili.com') return false;",
  383. " if (!BilibiliTimer.interval) BilibiliTimer.interval = {};",
  384. " if (!BilibiliTimer.interval.globalWatcher) BilibiliTimer.interval.globalWatcher = setInterval(BilibiliTimer.globalWatcher, 100);",
  385. " if (!BilibiliTimer.interval.autoHideWatcher) BilibiliTimer.interval.autoHideWatcher = setInterval(BilibiliTimer.autoHideWatcher, 1000);",
  386. " if (!BilibiliTimer.interval.widthWatcher) BilibiliTimer.interval.widthWatcher = setInterval(BilibiliTimer.widthWatcher, 5000);",
  387. " try {",
  388. " var video = $('video');",
  389. " setTimeout(function() {",
  390. " BilibiliTimer.videoPlayListener({ target: video[0] });",
  391. " BilibiliTimer.videoProgressListener({ target: video[0] });",
  392. " }, 100);",
  393. " } catch (_) {",
  394. " return;",
  395. " }",
  396. " };",
  397. " BilibiliTimer.restart = function BilibiliTimerRestart() {",
  398. " for (var i in BilibiliTimer.interval) {",
  399. " if (BilibiliTimer.interval[i]) clearInterval(BilibiliTimer.interval[i]);",
  400. " }",
  401. " $('.BilibiliTimerAutoHideButton').remove();",
  402. " if (window.BilibiliTimerUninit) return false;",
  403. " var timer = $('#BilibiliTimer');",
  404. " if (timer[0]) timer.fadeOut(370, BilibiliTimer.rebuild);",
  405. " else BilibiliTimer.rebuild();",
  406. " };",
  407. " BilibiliTimer.rebuild = function BilibiliTimerRebuild() {",
  408. " $('#BilibiliTimer').remove();",
  409. " window.BilibiliTimer = undefined;",
  410. " if (window.BilibiliTimerUninit) return false;",
  411. " if (window.BilibiliTimerCode) setTimeout(function() {",
  412. " eval(window.BilibiliTimerCode);",
  413. " }, 0);",
  414. " };",
  415. " BilibiliTimer.uninit = function BilibiliTimerUninit() {",
  416. " for (var i in BilibiliTimer.interval) {",
  417. " if (BilibiliTimer.interval[i]) clearInterval(BilibiliTimer.interval[i]);",
  418. " }",
  419. " $('.BilibiliTimerAutoHideButton').remove();",
  420. " $('#BilibiliTimer').remove();",
  421. " window.BilibiliTimer = undefined;",
  422. " window.BilibiliTimerUninit = true;",
  423. " };",
  424. " BilibiliTimer.start();",
  425. "})();"
  426. ].join('\n');
  427. var css = [
  428. "#BilibiliTimer {",
  429. " cursor: move;",
  430. " display: block;",
  431. " transition-property: opacity, width;",
  432. " transition-duration: .37s;",
  433. " transition-timing-function: initial;",
  434. " transition-delay: initial;",
  435. "}",
  436. ".bilibili-player-no-cursor #BilibiliTimer {",
  437. " opacity: .73;",
  438. "}",
  439. "#BilibiliTimer .info-title {",
  440. " width: 6em;",
  441. " margin: 0;",
  442. "}",
  443. "#BilibiliTimer .info-data {",
  444. " max-width: 25em;",
  445. " white-space: normal;",
  446. " vertical-align: top;",
  447. "}",
  448. "#BilibiliTimerCloseButton.bilibili-live-player-video-info-close {",
  449. " color: rgb(0, 0, 0);",
  450. " padding: 0px;",
  451. " height: 15px;",
  452. " background: rgb(221, 221, 221);",
  453. " width: 1em;",
  454. " text-align: center;",
  455. " top: 8px;",
  456. "}",
  457. "#BilibiliTimerRestartButton {",
  458. " top: auto;",
  459. " bottom: 10px;",
  460. "}",
  461. ".attention-btn-ctrl .mid-part {",
  462. " background-color: #4fc1e9;",
  463. " color: #fff;",
  464. " float: left;",
  465. " cursor: pointer;",
  466. " -webkit-user-select: none;",
  467. " width: 90px;",
  468. " height: 26px;",
  469. " padding: 0 5px;",
  470. " line-height: 26px;",
  471. " font-size: 12px;",
  472. " text-align: center;",
  473. " text-overflow: ellipsis;",
  474. " white-space: nowrap;",
  475. " overflow: hidden;",
  476. " box-sizing: border-box;",
  477. " box-shadow: 0 0 0.1em 0.1em #ddd;",
  478. "}"
  479. ].join('\n');
  480. unsafeWindow.addEventListener('load', function() {
  481. GM_addStyle(css);
  482. unsafeWindow.BilibiliTimerCode = code;
  483. unsafeWindow.eval([
  484. "setInterval(function() {",
  485. " if (!window.BilibiliTimerUninit && (!window.BilibiliTimer || !window.BilibiliTimer.init)) eval(window.BilibiliTimerCode);",
  486. "}, 500);",
  487. ].join('\n'));
  488. });
  489. })();