· 4 min read coding javascript productivity

Getting Youtube timestamped URLs with a JavaScript bookmarklet, for easy note-taking

I came across a post the other day where someone was surprised that you could put JavaScript into a bookmark and run it from on any page. They even asked what to call that type of thing. I was surprised. They’re called bookmarklets and they’ve saved me on numerous occasions.

For all you folks that don’t know, before the invention of chrome extensions and browser plugins, we used to cram JavaScript into browser bookmarks so that we could do things with the pages we were using. Years ago, I made a bookmarklet for copying tweets so that they could be embedded into my own blog — long before Twitter came up with embeddable tweets.

We don’t always need a massive permission grabbing chrome extension to add some extensibility to a page. Today I’m going to show you how I made one just last weekend to scratch an itch I’d been having. If you know a bit of JavaScript, you can come up with some pretty clever ways of interacting with the code on other people’s pages.

Taking notes on YouTube videos

I played around with Memetic for taking notes on YouTube videos but I always just ended up exporting those notes into Obsidian (my second brain) and I figured I could streamline the process. The most useful feature in Memetic was adding the timestamp (and link) to the notes I was taking.

Going from Memetic and into something more useful, like Obsidian, seemed like an unnecessary step when I would normally just take all my notes in Obsidian in the first place.

I needed to fix my process.

YouTube’s sharing URL

I figured that link would exist somewhere in the page on the video I was watching — I just needed to grab it and get it into obsidian. YouTube has a bit of UI that exposed that link, but I’m not opening that up, clicking a button, and copying it out every time. That does mean that information is in the code and I can work with that.

Youtube's Sharing modal showing icons for sharing to multiple networks including twitter, embedding, or email. It also shows the url value, an option for starting the video at specific time and copying the url to the clipboard
Youtube's sharing modal with an option to start at the current time of the video.

The Plan for the bookmarklet

What did I need this thing to do?

  1. Get the URL out of the Youtube video page
  2. Format it as markdown
  3. Copy it to the clipboard (So I can paste it in Obsidian quickly)

The code

I don’t feel like I need to explain code as long as it’s well commented:

// Function to convert number of seconds into Hours::Minutes::Seconds
function minutesSeconds(s){
	return(s-(s%=60))/60+(9<s?':':':0')+s;
}

// The Main Function
function start(){
	// Current Page
	var currentURL = window.location.href;

	// Where the data is in youtube
	var bar = document.getElementsByClassName("ytp-progress-bar")[0];

	//Converting that to data
	var seconds = bar.getAttribute("aria-valuenow");
	var secondsInMS = minutesSeconds(seconds);

	//Adding the time to the url
	var URL = currentURL + "?t=" + seconds;

	//Setting up the markdown format : [This is the linkname](link.html)
	var obsidianFormat = "[" + secondsInMS + "]" + "(" + URL + ")";

	// Put the obsidian formatted link into the clipboard
	navigator.clipboard.writeText(obsidianFormat);
	null;

	// Flash the time on the page in an overlay so that I know I clicked it.
	var elemDiv = document.createElement('div');
	elemDiv.innerHTML = "<h1 style='font-size:100px; color:white; text-align:center; margin-top:2em;'>" + secondsInMS + "</h1>";
	elemDiv.style.cssText = 'position:absolute;width:100%;height:100%;opacity:0.8;z-index:1000;background:#000;';
	document.body.appendChild(elemDiv);

	// Have it fade out after a bit
	setTimeout(function(){ elemDiv.style.display = "none"; }, 600);
}

// Start
start();

The minified code for the bookmarklet

javascript:function minutesSeconds(s){return(s-(s%=60))/60+(9<s?':':':0')+s}function start(){var currentURL=window.location.href;var bar=document.getElementsByClassName("ytp-progress-bar")[0];var seconds=bar.getAttribute("aria-valuenow");var secondsInMS=minutesSeconds(seconds);var URL=currentURL+"?t="+seconds;var obsidianFormat="["+secondsInMS+"]("+URL+")";navigator.clipboard.writeText(obsidianFormat);null;var elemDiv=document.createElement('div');elemDiv.innerHTML="<h1 style='font-size:100px; color:white; text-align:center; margin-top:2em;'>"+secondsInMS+"</h1>";elemDiv.style.cssText='position:absolute;width:100%;height:100%;opacity:0.8;z-index:1000;background:#000;';document.body.appendChild(elemDiv);setTimeout(function(){elemDiv.style.display="none"},600)}start();

If I wasn’t so lazy…

Things I could do to improve this:

  • Instead of hitting the bookmarklet every time, I could have injected a button into the page that I could hit every time, but I’m cool with the simplicity of this.
  • Make it work with Vimeo. I tend to watch videos on there too sometimes, but rarely. Maybe next time I need to take notes on one that’s not private.
  • This only works on Youtube.com, not when it’s embedded in a page somewhere else. That could potentially be helpful.