Skip to content

Instantly share code, notes, and snippets.

@ll14m4n
Last active February 5, 2024 01:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ll14m4n/254eb8da998ee9030d38e5dc8954a2e1 to your computer and use it in GitHub Desktop.
Save ll14m4n/254eb8da998ee9030d38e5dc8954a2e1 to your computer and use it in GitHub Desktop.
obsidian youtube templater
<%*
/*
You need to install yt-dlp and jq to use this template:
$ brew install yt-dlp jq # on macOS
You need to define user function in Templater plugin settings named "ytmeta" with the following command:
/opt/homebrew/yt-dlp -j "https://www.youtube.com/watch?v=${id}" | /opt/homebrew/jq "${query}"
replace /opt/homebrew with your path to yt-dlp and jq
*/
const query = "{title: .title, thumbnail: .thumbnail, duration_seconds: .duration, upload_date: .upload_date, description: .description, chapters: .chapters, channel_name: .channel, uploader_id: .uploader_id}"
format_duration = (duration_seconds) => {
const duration_ms = duration_seconds * 1000
duration_h = Math.floor(moment.duration(duration_ms).asHours()) || ""
duration_m_s = moment.utc(duration_ms).format("mm:ss")
return [duration_h, duration_m_s].filter(Boolean).join(":")
}
clean_obsidian_link = (name) => {
const filename_forbid_chars = /[*\/\\<>:|?"']/g
return name.replace(filename_forbid_chars, '_')
}
const url_input = await tp.system.prompt("Video URL")
const u = new URL(url_input);
const video_id = u.searchParams.get("v")
const meta_resp = await tp.user.ytmeta( { id: video_id, query: query } )
const meta = JSON.parse(meta_resp)
const title = meta.title
const thumbnail = meta.thumbnail
const duration = format_duration(meta.duration_seconds)
const ud = meta.upload_date
const upload_date = ud.slice(0, 4) + '-' + ud.slice(4, 6) + '-' + ud.slice(6, 8);
const description = meta.description
const canonical_url = `https://www.youtube.com/watch?v=${video_id}`
const filename = clean_obsidian_link('📺 ' + title)
const chapters_ar = meta.chapters || []
let chapters = ''
let notes = "## Notes\n"
if (chapters_ar.length > 0) {
chapters += chapters_ar.map((c) => {
const start = format_duration(c.start_time)
return `- [${c.title} (${start})](${canonical_url}&t=${c.start_time})`
}).join("\n")
notes += chapters_ar.map((c) => {
const start = format_duration(c.start_time)
return `### ${c.title}\n[(${start})](<${canonical_url}&t=${c.start_time}>)\n`
}).join("\n")
}
await tp.file.rename(filename)
tR += `---
tag: source/📺vid
id: "${video_id}"
channel: "[[${meta.uploader_id}]]"
title: "${title}"
duration: ${duration}
publish_date: ${upload_date}
url: ${canonical_url}
up:
---
![Thumbnail](${thumbnail})
[Watch (${duration})](${canonical_url})
${chapters}
## Description
\`\`\`
${description}
\`\`\`
${notes}
`
%>
@fbuchinger
Copy link

System function "ytmeta" mentioned in Line 8 is Linux/Unix-specific and does not work under windows, equivalent function for Windows looks like so:
C:\Tools\yt-dlp\yt-dlp.exe -j "https://www.youtube.com/watch?v=%id%" | c:\tools\jq\jq.exe "%query%"

For this function to work, you need to download https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe and copy it to the C:\Tools\yt-dlp directory. https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-windows-amd64.exe needs to be downloaded as well. Rename this file to jq.exe and place it in the c:\tools\jq directory.

Of course you can use other directories, but I recommend to avoid spaces in pathnames.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment