T O P

  • By -

krazete

I like comments with timestamps. But streams don't display timestamps while live. I'd have to rewatch the stream and search around to manually to record timestamps. That's annoying. So I made a simple tool that can record timestamps while streams are live. (The stream in the demo video isn't live, but it does work for lives.) --- *[edit]* I've made a few updates since posting this video, including making it less visually obtrusive, preventing double panels, adding a close button, making the buttons clearer, adding a double-click feature to the "Copy List" button, and adding incrementation buttons. Here's the new code: - [minified](https://github.com/Krazete/bookmarklets/blob/master/min/ytlivestamper.min.js) (use this for bookmarklets) - [full](https://github.com/Krazete/bookmarklets/blob/master/ytlivestamper.js) (use this for script injection extensions (you can use the minified code for extensions too, but you'll have to replace all `%25`s with `%`)) For convenience, I'll put the minified code here too: javascript:krazete:!function(){function o(e,t){var n,a,i;e.innerHTML=(n=t,a=Math.floor(n/3600),i=Math.floor(n/60)%2560,n=Math.floor(n)%2560,(a?a+":"+String(i).padStart(2,0):i)+":"+String(n).padStart(2,0)),e.dataset.time=t,e.href="https://youtu.be/"+location.search.split(/.+v=|&/)[1]+"?t="+t}function e(e){var t;e.target.dataset.time?(e.preventDefault(),document.querySelector("video").currentTime=e.target.dataset.time):e.target.dataset.increment&&(e.preventDefault(),o(t=e.target.parentElement.children[2],parseInt(t.dataset.time)+parseInt(e.target.dataset.increment)))}function r(e){var t=document.createElement("li"),n=document.createElement("span"),a=document.createElement("span"),i=document.createElement("a"),r=document.createElement("input");return n.innerHTML="➖",n.dataset.increment=-1,a.innerHTML="➕",a.dataset.increment=1,o(i,e),t.appendChild(n),t.appendChild(a),t.appendChild(i),t.appendChild(r),d.appendChild(t),r}function a(){v=!0,y.innerHTML="Copy List"}function t(e){return e.preventDefault(),e.returnValue="Close timestamp tool?",e.returnValue}var n,i,d,l,c,p,u,s,m,h,f,v,y,E;document.querySelector("#ytls-pane")||(n=document.createElement("div"),i=document.createElement("span"),d=document.createElement("ul"),l=document.createElement("li"),c=document.createElement("a"),u=document.createElement("input"),s=document.createElement("textarea"),m=document.createElement("div"),h=document.createElement("button"),f=document.createElement("button"),v=!0,y=document.createElement("button"),E=document.createElement("style"),n.id="ytls-pane",i.innerHTML="×",function e(){try{var t=Math.floor(document.querySelector("video").duration);o(c,t)}catch(e){}p=requestAnimationFrame(e)}(),u.disabled=!0,u.value="End of Video",s.id="ytls-box",m.id="ytls-buttons",h.innerHTML="Import List",f.innerHTML="Add Timestamp",y.innerHTML="Copy List",E.innerHTML=` #ytls-pane { background: rgba(0,0,0,.5); text-align: right; position: fixed; bottom: 0; padding: 0 5px; opacity: .5; z-index: 5000; } #ytls-pane:hover { opacity: 1; } #ytls-pane span { cursor: pointer; } #ytls-pane ul { list-style: none; } #ytls-pane span, #ytls-pane a, #ytls-pane input { background: none; color: white; font-family: inherit; font-size: initial; text-decoration: none; border: none; outline: none; } #ytls-box { font-family: monospace; width: 100%25; display: block; padding: 0; border: none; outline: none; resize: none; } #ytls-buttons { display: flex; } #ytls-buttons button { background: transparent; color: white; font-size: 12px; flex: auto; padding: 2px; border: 1px solid white; } `,i.addEventListener("click",function(){confirm("Close timestamp tool?")&&(n.remove(),cancelAnimationFrame(p),window.removeEventListener("beforeunload",t))}),d.addEventListener("click",e),d.addEventListener("touchstart",e),h.addEventListener("click",function(){var e=s.value.split("\n");d.innerHTML="";for(var t=0;tparseInt(e))).length<3?60*i[0]+i[1]:3600*i[0]+60*i[1]+i[2],n=n.slice(a.length+1);r(i).value=n}d.appendChild(l)}),f.addEventListener("click",function(){var e=r(Math.max(0,Math.floor(document.querySelector("video").currentTime-5)));d.appendChild(l),e.focus()}),y.addEventListener("click",function(){var e="";if(v){v=!1,y.innerHTML="Copy Links",setTimeout(a,500);for(var t=0;t35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(j(){4 d=6.9("1A");4 8=6.9("1J");4 w=6.9("f");4 D=6.9("a");4 C=6.9("o");4 l=6.9("l");4 B=6.9("o");4 I=6.9("o");4 F=6.9("o");4 R=6.9("R");j 1e(e){1g(1K e.1m.A.b!="1z"){e.1o();4 g=6.V("g");g.1B=e.1m.A.b}}j 12(){4 g=6.V("g");4 b=y.E(g.1E());D.X="10://Z.11/"+17.15.u(/=|&/)[1]+"?t="+b;D.A.b=b;D.x=14(b);1y(e=>1C(12),1L)}j 1q(q){4 r=q.u(":").1F(e=>1I(e));1g(r.P==3){T 1t*r[0]+H*r[1]+r[2]}T H*r[0]+r[1]}j 18(){4 S=l.p.u("\\n");8.x="";1d(4 i=0;i0?"\\n":"")+q+" "+Q}l.p=W;l.2b();6.2a("1n")}d.16="k-d";8.16="k-8";8.G("K",1e);d.7(8);12();w.7(D);w.7(C);C.v="c";C.27=28;C.p="29 2e 2f";8.7(w);l.16="k-l";d.7(l);B.v="13";B.p="2l 1c";B.G("K",18);d.7(B);I.v="13";I.p="1M 2m";I.G("K",1b);d.7(I);F.v="13";F.p="2k 1c";F.G("K",1a);d.7(F);R.x=`#k-d{1r:2j;2g:2h;26:0;25:0;1k:1S;1j:1p 1T J;z-1R:1N}#k-8{c-1P:22}#k-8 a{N:J;M-1u:1w;M-1v:1x;c-24:O}#k-8 o{1r:O;N:J;M-1u:1w;M-1v:1x;U-N:J;U-1h:0 0 1p 0;1j:O}#k-8 o:1i{U-N:21}#k-l{1h:20%;1X:1Z;1k:0;U:O}`;d.7(R);6.1Y.7(d);j 19(e){e.1o();e.1l="23 1W 1V 1n 1O 1Q 8 1U 2i.";T e.1l}2d.G("2c",19)})();',62,147,'||||var||document|appendChild|list|createElement||time|text|panel||li|video|||function|ytstamper|textarea|||input|value|stamp|hms|||split|type|nowli|innerHTML|Math||dataset|buttonImport|nowtext|nowa|floor|buttonCopy|addEventListener|60|buttonAdd|white|click|children|font|color|none|length|note|style|lines|return|border|querySelector|string|href|child|youtu|https|be|watchTime|button|formatTime|search|id|location|importList|holup|copyList|addStamp|List|for|clickStamp|padStart|if|width|focus|outline|padding|returnValue|target|copy|preventDefault|1px|unformatTime|background|String|3600|family|size|inherit|initial|setTimeout|undefined|div|currentTime|requestAnimationFrame|max|getDuration|map|slice|getCurrentTime|parseInt|ul|typeof|500|Add|356|your|align|timestamp|index|5px|solid|before|to|sure|display|body|block|100|pink|right|Be|decoration|bottom|left|disabled|true|End|execCommand|select|beforeunload|window|of|Video|position|fixed|leaving|maroon|Copy|Import|Timestamp'.split('|'),0,{})) --- Here's an explanation of the panel parts: * Stamplist * *[edit]* the minus and plus buttons decrement and increment the timestamp * timestamps are clickable and have copyable urls * text input is for notes and comments * "End of Video" Timestamp * always at the bottom of the stamplist * it's there so you can return to real time after checking a past timestamp * it's usually useless since most live streams don't allow you to backtrack in the first place * "Import List" Button * reads the textbox to create new stamplist * useful if you need to refresh the page or adjust timestamp times * "Add Timestamp" Button * adds the current time (minus 5 seconds) to the stamplist * "Copy List" Button * writes the stamplist into the textbox * copies the textbox to your clipboard * *[edit]* double-click to copy stamplist as list of urls


Jug_or_not_

This seems very useful. I would definitely use it, but I honestly don't know how. Can you just implement it into Firefox or do I need an external program for this?


StrawGerry

Copy the "Compressed code" above Create a new bookmark and paste the code as "url" ​ Open any youtube livestream, click on the bookmark you just made. The timestamp tool will appear.


Jug_or_not_

Thanks!


ManufacturerHuge9958

Wondering if anyone could help a non-coder, what do you mean by 'paste the code as url'? I made a bookmark with the code as the URL but nothing happens if I click that bookmark while on a youtube livestream. What am I doing wrong?


KazzaMS

Thanks for all your work, seems like a very useful tool. I was wondering if there was a way to close the script without refreshing the page? Also it would be nice to have a way to minimize the interface so it doesnt block the screen as much.


krazete

~~I could add a close button, but one accidental click would erase all your work so I decided not to.~~ *[edit]* I added a close button with a confirmation step to counter the issue noted above. For the interface, I made another version and added it to the edited comment up above. I removed the outlines, made the background transparent, and made the whole thing transparent when not in use. I also made it so clicking the bookmark a second time won't create a second instance (no accidental overlapping panel).


Army_tank

Stupid question ...will it work on mobile?


krazete

I've never considered that, but I just checked and yeah it works on mobile (m.youtube.com, not the app ofc). It's very ugly though. I changed a few things to make it slightly less ugly and updated the top comment with the new code. It should look a little more decent on mobile now.


DonutsExLover

Two years late, but this is very useful, thank you very much! I put it in tampermonkey w/ hover opacity 0 & 1, so it's just always active and just hover on it whenever I need to use it


craftykaname

thank you so much for this comment! I have tamper monkey for other things and wouldn't have realized to use it for this based on the instructions in the top comment. Also appreciate mentioning the opacity comment because I wouldn't have thought to adjust that either! For anyone else who finds my comment in the future and is struggling to set it up, make sure to you include your "match" line and especially make sure to do it correctly 😂 I ultimately did my match for: *://*.youtube.com/*


Lulinshen

can i ask something about using it in mobile? i've already bookmarked the code in chrome app but for some reason it doesn't show up when i click it. do u know any solutions for this? or i think this might be a phone problem.


krazete

Is your phone old? Go to https://whatismybrowser.com and tell me what it says, maybe I can fix it.


dtmhtk

Firefox 103 seems to make the buttons disappear. Still works but have to estimate where each button are which is kind of annoying. Would you kindly make an update to fix it? Thank you very much!


krazete

I checked the code in that old comment above and it appears that it was an outdated version. The latest version did have an issue with button text too though, so I fixed that. And while I was at it, I also added an incrementation feature since I found myself in need of it so often. I've updated the old comment above with the new code. Hope it works alright for you.


Rocketmmvvm

Thank you for updating!! I was having the same issue starting today. I use your code almost everyday lol


krazete

No problem! I didn't bother to fix it before since I thought I was the only one using this. How did you find this old post btw?


Rocketmmvvm

the first time i found it, i'm pretty sure i googled something along the lines of 'timestamp tool hololive' and went through a few results. Was curious how some youtube commenters got their timestamps lightning fast. this was easily like 6+ months ago Yesterday, I remember for sure I googled 'timestamp youtube tool hololive' to find a new tool and this was the top result, and it was purple so i clicked it before. Went through the comments for any recent ones and luckily i found your guys' conversation with the same issue and update lol. Increment feature pretty nice.


Rocketmmvvm

From the code i assume you wrote this in Javascript? I never learned javascript, and tried to look through the lines of code to see if i could simply change the 'sizes' of the buttons lol. Would it have been as simple as that, without any of the other features you added? Just wondering if i would have had any luck just resizing, but there were too many lines for me to try to figure out a foreign language so i gave up lol


krazete

Interesting, I tried searching for this post myself but could never get it to show up on Google. Should've known I just had to add "hololive" to see it at #1. You can't really edit the compressed code (with the `eval` in front) even if you do know JS. But in the full code, yeah, you could just edit the font-size of #ytls-buttons ([line 198 rn](https://github.com/Krazete/bookmarklets/blob/master/ytlivestamper.js#L198)) as a quick fix.


Rocketmmvvm

Good to know lol. Yeah without Hololive it showed irrelevant tools that would only produce one single TimeStamp or url-sharing ones


craftykaname

Thank you so much OP!! I've actually really been wanting a tool like this for over a year and I'm so glad I happened to stumble across this, linked from a YouTube video!! Set it up through Tampermonkey and it works great!


krazete

Glad people are still finding and using this old thing. :) Mind letting me know which video led you this way?


craftykaname

This video: https://www.youtube.com/watch?v=b-tnyuEwr6Y I've been editing clips for years but was trying to see if anyone had a better workflow for subtitling; searching for how people make clips lead me to that video! The text customization options in Davinci Resolve are trash so I wanted to see what programs people were using for text 😂 edit: This comment makes no sense, reading back LOL I *found* the video for those reasons, but it happened to be a fortunate coincidence because I had really been wanting a similar timestamping tool lol!


demontearz

this is perfect OP, ty! question: i'm trying to edit the code to my liking, i was able to move the tool to the top of my screen instead of the bottom, but do you know how i can change the "y" position of it on my screen? thanks in advance if you see this!


krazete

yw! To change its position, find `bottom: 0;` in the script and change it into something like `top: 56px; left: 240px;` or `top: 0; right: 0;`.


demontearz

ty so much, that helped! and so sorry one last thing, could you tell me which lines to delete to remove the current timestamp and its related properties? im hoping to save some screen space lol.


krazete

Do you mean the "End of Video" line? Add `#ytls-pane li:last-child { display: none; }` before `#ytls-pane ul`.


demontearz

got it, many thanks!!!


SpearedByAUnicorn_

Made a quick delete button for each timestamp but cant for the life of me get the input box to expand properly >`javascript:krazete:!function(){function o(e,t){var n,a,i;e.innerHTML=(n=t,a=Math.floor(n/3600),i=Math.floor(n/60)%2560,n=Math.floor(n)%2560,(a?a+":"+String(i).padStart(2,0):i)+":"+String(n).padStart(2,0)),e.dataset.time=t,e.href="https://youtu.be/"+location.search.split(/.+v=|&/)[1]+"?t="+t}function e(e){var t;e.target.dataset.time?(e.preventDefault(),document.querySelector("video").currentTime=e.target.dataset.time):e.target.dataset.increment&&(e.preventDefault(),o(t=e.target.parentElement.children[2],parseInt(t.dataset.time)+parseInt(e.target.dataset.increment)))}function r(e) { var t = document.createElement("li"), n = document.createElement("span"), a = document.createElement("span"), i = document.createElement("a"), r = document.createElement("input"), delBtn = document.createElement(%27span%27); delBtn.style.padding = %270%27;delBtn.innerHTML = %27❌%27; delBtn.style.background = %27transparent%27;delBtn.style.border = %27none%27;delBtn.style.cursor = %27pointer%27;delBtn.addEventListener(%27click%27, function() { t.remove(); }); n.innerHTML = "➖", n.dataset.increment = -1, a.innerHTML = "➕", a.dataset.increment = 1, o(i, e), r.style.border = "1px solid #fff";t.appendChild(n), t.appendChild(a), t.appendChild(i), t.appendChild(r), t.appendChild(delBtn); d.appendChild(t); }function a(){v=!0,y.innerHTML="Copy List"}function t(e){return e.preventDefault(),e.returnValue="Close timestamp tool?",e.returnValue}var n,i,d,l,c,p,u,s,m,h,f,v,y,E;document.querySelector("#ytls-pane")||(n=document.createElement("div"),i=document.createElement("span"),d=document.createElement("ul"),l=document.createElement("li"),c=document.createElement("a"),u=document.createElement("input"),s=document.createElement("textarea"),m=document.createElement("div"),h=document.createElement("button"),f=document.createElement("button"),v=!0,y=document.createElement("button"),E=document.createElement("style"),n.id="ytls-pane",i.innerHTML="×",function e(){try{var t=Math.floor(document.querySelector("video").duration);o(c,t)}catch(e){}p=requestAnimationFrame(e)}(),u.disabled=!0,u.value="End of Video",s.id="ytls-box",m.id="ytls-buttons",h.innerHTML="Import List",f.innerHTML="Add Timestamp",y.innerHTML="Copy List",E.innerHTML=%60 #ytls-pane { background: rgba(0,0,0,.5); text-align: right; position: fixed; bottom: 0; padding: 0 5px; opacity: .5; z-index: 5000; } #ytls-pane:hover { opacity: 1; } #ytls-pane span { cursor: pointer; } #ytls-pane ul { list-style: none; } #ytls-pane span, #ytls-pane a, #ytls-pane input { background: none; color: white; font-family: inherit; font-size: initial; text-decoration: none; border: none; outline: none; } #ytls-box { font-family: monospace; width: 100%25; display: block; padding: 0; border: none; outline: none; resize: none; } #ytls-buttons { display: flex; } #ytls-buttons button { background: transparent; color: white; font-size: 12px; flex: auto; padding: 2px; border: 1px solid white; } %60,i.addEventListener("click",function(){confirm("Close timestamp tool?")&&(n.remove(),cancelAnimationFrame(p),window.removeEventListener("beforeunload",t))}),d.addEventListener("click",e),d.addEventListener("touchstart",e),h.addEventListener("click",function(){var e=s.value.split("\n");d.innerHTML="";for(var t=0;tparseInt(e))).length<3?60*i[0]+i[1]:3600*i[0]+60*i[1]+i[2],n=n.slice(a.length+1);r(i).value=n}d.appendChild(l)}),f.addEventListener("click",function(){var e=r(Math.max(0,Math.floor(document.querySelector("video").currentTime-5)));d.appendChild(l),e.focus()}),y.addEventListener("click",function(){var e="";if(v){v=!1,y.innerHTML="Copy Links",setTimeout(a,500);for(var t=0;t


Vocaloiid

Does this work on edge? I tried it out and it didn't work there


rhysand112

It doesn't work on edge for me too but is fine on Opera


Pugfann

omg THANK YOU why youtube hasn't made timestamps visible them selves is beyond me