Hello everyone!
I’ve been playing a bit with Silverbullet and I like it a lot. I’m streamlining some of the cases that I’d like to use on my notes and one of them are adding YouTube videos (not embed but a thumbnail + link). In my specific case I’d like videos that are retrieved and linked to an Indivious instance to avoid the cluttered and add-filled YouTube.
I created an small space-script
that retrieves the video name, thumbnail and links it. This custom function input can be a YouTube URL, Indivious URL or just the video id. Add this snipplet of code to a page, reload (Control+Alt+r) and start using it as a template.
I used https://inv.tux.pizza
as the instance, but you can use your own self-hosted one or any of the public instances (Invidious Instances - Invidious Documentation).
const INVIDIOUS_INSTANCE = 'https://inv.tux.pizza'
async function invFetchVideoTitle(videoid) {
const apiUrl = `${INVIDIOUS_INSTANCE}/api/v1/videos/${videoid}`;
try {
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.title.replace(/[#\[\]{}*]/g, '');
} catch (error) {
console.error('Error fetching video title:', error);
return null;
}
}
function invGetVideoThumbnail(videoid) {
return `${INVIDIOUS_INSTANCE}/vi/${videoid}/0.jpg`
}
function invGetVideoLink(videoid) {
return `${INVIDIOUS_INSTANCE}/watch?v=${videoid}`
}
function invExtractYouTubeVideoID(url_or_videoid) {
const ytRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
const ytMatch = url_or_videoid.match(ytRegex);
if (ytMatch) {
return ytMatch[1];
}
const invRegex = /(?:https?:\/\/)?[\w.-]+\/watch\?v=([a-zA-Z0-9_-]{11})/;
const invMatch = url_or_videoid.match(invRegex);
if (invMatch) {
return invMatch[1];
}
return url_or_videoid;
}
async function invGetVideoMarkdown(url_or_videoid) {
videoid = invExtractYouTubeVideoID(url_or_videoid);
title = await invFetchVideoTitle(videoid);
thumb = invGetVideoThumbnail(videoid);
link = invGetVideoLink(videoid);
return `\n[${title}](${link})`
}
silverbullet.registerFunction({name: "youtube"}, async (videoid) => {
return invGetVideoMarkdown(videoid);
});
Example usage:
{{youtube("https://www.youtube.com/watch?v=F8EMW5pXFFM")}}
This would look like this on a page:
I hope this is useful or at least that helps you to learn a bit on how to develop these custom functions (they’re quite powerful).
Best,
Pablo