0%

油猴脚本

项目来源

在做笔记的时候需要大量的b站视频定位链接,自己计算当前位置对应的秒数和拼接连接很麻烦。
所以写了个脚本一键生成

实现复制b站视频的当前播放时间

本来想自动挂载到B站的分享栏上的,结果出现了点小问题,检查挂载的话不知道为什么会出现莫名其妙的bug,下面是有问题的代码

Details
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// ==UserScript==
// @name bilibili timestamp copier
// @namespace http://tampermonkey.net/
// @version 0.1
// @include https://www.bilibili.com/video/*
// @description try to take over the world!
// @require https://code.jquery.com/jquery-1.12.4.min.js
// @author ednow
// @grant none
// ==/UserScript==

(function() {
var TEXT_COPY_BUTTON = "复制时间轴";
var div = document.createElement('span');
// https://blog.csdn.net/u010565174/article/details/46909351
div.textContent = TEXT_COPY_BUTTON;
// 添加class name,方便查找
div.setAttribute('class', "copier");
// 监听点击事件
div.addEventListener('mousedown', function () {
tempAlert("复制成功",1000)
copyTextToClipboard(getTime())
});


load();
// 每三秒检查一次元素是否在页面上
setInterval(function(){
if($(".copier").length < 1){
load();
}
}, 3000);

// 挂载脚本和元素
function load(){
// 将标签塞入到页面中,插入到点赞分享的位置后面
var ops = document.getElementsByClassName('ops')[0]
ops.appendChild(div);
//$(".ops")[0].after(div);
}
function getTime(){
var [minutes,seconds] = $(".bilibili-player-video-time-now")[0].textContent.split(":")

// 拼接要复制的内容
return "https://www.bilibili.com/video/" + /BV[a-zA-Z1-9]+/.exec(window.location.href) + `?t=${parseInt(minutes)*60 + parseInt(seconds)}`

}

// https://stackoverflow.com/questions/19020830/autoclose-alert
function tempAlert(msg,duration)
{
var el = document.createElement("div");
el.setAttribute("style","position:absolute;top:50%;left:50%;background-color:white;");
el.innerHTML = msg;
setTimeout(function(){
el.parentNode.removeChild(el);
},duration);
document.body.appendChild(el);
}

// 复制内容到剪切板
// https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");

//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if the element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//

// Place in the top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;

// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';

// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;

// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';

// Avoid flash of the white box if rendered for any reason.
textArea.style.background = 'transparent';


textArea.value = text;

document.body.appendChild(textArea);
textArea.focus();
textArea.select();

try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}

document.body.removeChild(textArea);
}


})();

bug

莫名其妙?

出现下面的原因导致视频没有画面

一开始以为是变量冲突,然后一个一个函数的去检查
发现函数和变量都载入了也没有出现bug
只有运行

1
2
3
4
5
6
7
8
load();
// 每三秒检查一次元素是否在页面上
setInterval(function(){
if($(".copier").length < 1){
load();
}
}, 3000);


这几行函数的时候才会出现bug

强行解决

Details
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// ==UserScript==
// @name bilibili timestamp copier
// @namespace http://tampermonkey.net/
// @version 0.1
// @include https://www.bilibili.com/video/*
// @description try to take over the world!
// @require https://code.jquery.com/jquery-1.12.4.min.js
// @author ednow
// @grant none
// ==/UserScript==

(function() {
var TEXT_COPY_BUTTON = "复制时间轴";
var TEXT_OPEN_BUTTON = "打开复制功能";
var div = document.createElement('span'),openDiv = document.createElement('div');
var openDivCss = `left: 0;
position: fixed;
bottom: 0;
width: 100%;
z-index: 100;
`
openDiv.setAttribute('style', openDivCss);
openDiv.addEventListener('mousedown', function () {
load()
});
openDiv.textContent = TEXT_OPEN_BUTTON;
openDiv.setAttribute('class', "openMode");
// 插入开启选项
var body = document.getElementsByTagName("body")[0];
body.appendChild(openDiv);

// https://blog.csdn.net/u010565174/article/details/46909351
div.textContent = TEXT_COPY_BUTTON;
// 添加class name,方便查找
div.setAttribute('class', "copier");
// 监听点击事件
div.addEventListener('mousedown', function () {
tempAlert("复制成功",1000)
copyTextToClipboard(getTime())
});
//load();
// 每三秒检查一次元素是否在页面上
// var checkExist = setInterval(function(){
//if($(".copier").length < 1){
//load();
//}
//}, 3000);

// 挂载脚本和元素
function load(){
// 将标签塞入到页面中,插入到点赞分享的位置后面
var ops = document.getElementsByClassName('ops')[0]
ops.appendChild(div);
//$(".ops")[0].after(div);
}

function getTime(){
var [minutes,seconds] = $(".bilibili-player-video-time-now")[0].textContent.split(":")

// 拼接要复制的内容
return "https://www.bilibili.com/video/" + /BV[a-zA-Z1-9]+/.exec(window.location.href) + `?t=${parseInt(minutes)*60 + parseInt(seconds)}`

}

function tempAlert(msg,duration)
{
var el = document.createElement("div");
el.setAttribute("style","position:absolute;top:50%;left:50%;background-color:white;");
el.innerHTML = msg;
setTimeout(function(){
el.parentNode.removeChild(el);
},duration);
document.body.appendChild(el);
}

// 复制内容到剪切板
// https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");

//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if the element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//

// Place in the top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;

// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';

// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;

// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';

// Avoid flash of the white box if rendered for any reason.
textArea.style.background = 'transparent';


textArea.value = text;

document.body.appendChild(textArea);
textArea.focus();
textArea.select();

try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}

document.body.removeChild(textArea);
}
})();

使用方法

点击浏览器最左下方的「打开复制功能」

再点击「复制时间轴」,即可复制时间坐标

B站点击时间自动跳转到相应位置的标签格式

1
2
3
<a class="video-seek" data-time="120">01:55</a>
一段文本
<br>

参考文献

youtube

youtube视频时间的锚点
https://www.youtube.com/watch?v=qrYlvjwPe6Q&t=150s
youtube的锚点标签

1
<a class="yt-simple-endpoint style-scope yt-formatted-string" spellcheck="false" href="/watch?v=qrYlvjwPe6Q&amp;t=48s" dir="auto">0:48</a>

youtube直接添加标签是不行的,无论怎么修改都只会锚到之前的那个时间点

另:自动生成b站视频学习目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 获得标题
titleName = window.document.title.split("_")[0]
// 获得BV号
BVnum = /BV[a-zA-Z1-9]+/.exec(window.location.href)
str = `# ${titleName} ${BVnum}\n`
href = "//div[@class='cur-list']/ul/li/a/@href"
title = "//div[@class='cur-list']/ul/li/a/@title"
ltitle = $x(title)
lhref = $x(href)

for (var href of lhref){
str = str + "## " + href.value.split('?').pop().split('=').join("") + " " + ltitle.shift().value + '\n' + "### 笔记\n### 疑问\n### bug\n### 弹幕\n\n"
}
console.log(str)

str = str + "## " + href.value.split('?').pop().split('=').join("") + " " + ltitle.shift().value + '\n'