Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
FreshPenguin112
GitHub Repository: FreshPenguin112/bookmarklets
Path: blob/main/ytlivestamper.js
5051 views
1
(function () {
2
if (!document.querySelector("#ytls-pane")) {
3
var pane = document.createElement("div");
4
var exit = document.createElement("span");
5
var list = document.createElement("ul");
6
var nowli = document.createElement("li");
7
var nowa = document.createElement("a");
8
var nowid;
9
var nowtext = document.createElement("input");
10
var box = document.createElement("textarea");
11
var paster = document.createElement("button");
12
var adder = document.createElement("button");
13
var copier = document.createElement("button");
14
var style = document.createElement("style");
15
16
function closePane() {
17
if (confirm("Close timestamp tool?")) {
18
pane.remove();
19
cancelAnimationFrame(nowid);
20
window.removeEventListener("beforeunload", warn);
21
}
22
}
23
24
function clickStamp(e) {
25
if (e.target.dataset.time) {
26
e.preventDefault();
27
document.querySelector("video").currentTime = e.target.dataset.time;
28
}
29
}
30
31
function watchTime() {
32
try {
33
var time = Math.floor(document.querySelector("video").duration);
34
nowa.innerHTML = formatTime(time);
35
nowa.href = "https://youtu.be/" + location.search.split(/=|&/)[1] + "?t=" + time;
36
nowa.dataset.time = time;
37
} catch (e) {}
38
nowid = requestAnimationFrame(watchTime);
39
}
40
41
function unformatTime(stamp) {
42
var hms = stamp.split(":").map(e => parseInt(e));
43
if (hms.length < 3) {
44
return 60 * hms[0] + hms[1];
45
}
46
return 3600 * hms[0] + 60 * hms[1] + hms[2];
47
}
48
49
function pasteList() {
50
var lines = box.value.split("\n");
51
list.innerHTML = "";
52
for (var i = 0; i < lines.length; i++) {
53
var stamp = lines[i].split(" ", 1)[0];
54
var time = unformatTime(stamp);
55
var note = lines[i].slice(stamp.length + 1);
56
var li = document.createElement("li");
57
var a = document.createElement("a");
58
var text = document.createElement("input");
59
a.innerHTML = stamp;
60
a.dataset.time = time;
61
a.href = "https://youtu.be/" + location.search.split(/.+v=|&/)[1] + "?t=" + time;
62
text.value = note;
63
li.appendChild(a);
64
li.appendChild(text);
65
list.appendChild(li);
66
}
67
list.appendChild(nowli);
68
}
69
70
function formatTime(time) {
71
var h = Math.floor(time / 3600);
72
var m = Math.floor(time / 60) % 60;
73
var s = Math.floor(time) % 60;
74
return (h ? (h + ":" + String(m).padStart(2, 0)) : m) + ":" + String(s).padStart(2, 0);
75
}
76
77
function addStamp() {
78
var time = Math.max(0, Math.floor(document.querySelector("video").currentTime - 5));
79
var li = document.createElement("li");
80
var a = document.createElement("a");
81
var text = document.createElement("input");
82
a.innerHTML = formatTime(time);
83
a.dataset.time = time;
84
a.href = "https://youtu.be/" + location.search.split(/.+v=|&/)[1] + "?t=" + time;
85
li.appendChild(a);
86
li.appendChild(text);
87
list.appendChild(li);
88
list.appendChild(nowli);
89
text.focus();
90
}
91
92
function copyList() {
93
var string = "";
94
for (var i = 0; i < list.children.length - 1; i++) {
95
var stamp = list.children[i].children[0].innerHTML;
96
var note = list.children[i].children[1].value;
97
string += (i > 0 ? "\n" : "") + stamp + " " + note;
98
}
99
box.value = string;
100
box.select();
101
document.execCommand("copy");
102
}
103
104
function warn(e) {
105
e.preventDefault();
106
e.returnValue = "Close timestamp tool?";
107
return e.returnValue;
108
}
109
110
pane.id = "ytls-pane";
111
exit.innerHTML = "&times;";
112
watchTime();
113
nowtext.disabled = true;
114
nowtext.value = "End of Video";
115
box.id = "ytls-box";
116
paster.innerHTML = "Import List";
117
adder.innerHTML = "Add Timestamp";
118
copier.innerHTML = "Copy List";
119
style.innerHTML = `
120
#ytls-pane {
121
background: rgba(0,0,0,.5);
122
text-align: right;
123
position: fixed;
124
bottom: 0;
125
padding: 0 5px;
126
opacity: .5;
127
z-index: 5000;
128
}
129
#ytls-pane:hover {
130
opacity: 1;
131
}
132
#ytls-pane span {
133
cursor: pointer;
134
}
135
#ytls-pane span, #ytls-pane a, #ytls-pane input {
136
background: none;
137
color: white;
138
font-family: inherit;
139
font-size: initial;
140
text-decoration: none;
141
border: none;
142
outline: none;
143
}
144
#ytls-box {
145
width: 100%;
146
display: block;
147
padding: 0;
148
border: none;
149
outline: none;
150
resize: none;
151
}
152
`;
153
154
exit.addEventListener("click", closePane);
155
list.addEventListener("click", clickStamp);
156
paster.addEventListener("click", pasteList);
157
adder.addEventListener("click", addStamp);
158
copier.addEventListener("click", copyList);
159
window.addEventListener("beforeunload", warn);
160
161
pane.appendChild(exit);
162
nowli.appendChild(nowa);
163
nowli.appendChild(nowtext);
164
list.appendChild(nowli);
165
pane.appendChild(list);
166
pane.appendChild(box);
167
pane.appendChild(paster);
168
pane.appendChild(adder);
169
pane.appendChild(copier);
170
pane.appendChild(style);
171
document.body.appendChild(pane);
172
}})();
173
174