zolrath / obsidian-auto-link-title

Automatically fetch the titles of pasted links
MIT License
415 stars 55 forks source link

[Feature Request] DeArrow support for YouTube links #107

Open old4ever opened 4 months ago

old4ever commented 4 months ago

Description

Hello! I would like to suggest adding a DeArrow support for YouTube links. DeArrow is an open source browser extension for crowdsourcing better titles and thumbnails on YouTube, avoiding clickbait and providing more accurate titles. While in this case it being a browser extension and having thumbnail support is irrelevant, the author of the extension provides a free API which we can use to get submitted titles for specific videos.

Workaround

I'm currently using a hacky solution in the experimental scraper for my own use that consists of editing scraper.ts file:

// Most of the stuff here is irrelevant for us, but I'm including this in this issue anyway for the sake of completion
// Types are taken from API docs - https://wiki.sponsor.ajay.app/w/API_Docs/DeArrow

type dearrowResponse = {
  titles: Array<{
    title: string; // Note: Titles will sometimes contain > before a word. This tells the auto-formatter to not format a word. If you have no auto-formatter, you can ignore this and replace it with an empty string
    original: boolean;
    votes: number;
    locked: true;
    UUID: string;
  }>;
  thumbnails: Array<{
    timestamp: number; // Missing if original is true
    original: boolean;
    votes: number;
    locked: true;
    UUID: string;
  }>;
  randomTime: number;
  videoDuration: number | null;
};

...

async function scrape(url: string): Promise<string> {
  const urlObj = new URL(url);
  if (urlObj.host === "youtube.com" || urlObj.host === "www.youtube.com") {
    // Try to get YouTube video ID
    const id = urlObj.searchParams.get("v");
    if (!!id) {
      try {
        const response = await requestUrl(
          `https://sponsor.ajay.app/api/branding/?videoID=${id}`
        );
        const json = response.json as dearrowResponse;

        // Checking if there are titles submitted by other users to the db
        // If not, we fallback to the regular scraping process
        if (json.titles.length !== 0) {
          // Titles are returned in the order of quality, so using the first element is the best option in general
          return `${json.titles[0].title} - YouTube`;
        }
      } catch (error) {
        console.error(error);
      }
    }
  }

  try {
    const response = await requestUrl(url);
    if (!response.headers["content-type"].includes("text/html"))
      return getUrlFinalSegment(url);
    const html = response.text;
    ...

Result

Comparison

Additional Information

I'm not sure if this feature aligns with the extension goals (considering this comment, perhaps even related to https://github.com/zolrath/obsidian-auto-link-title/issues/23), but I think it would be useful to some people using this extension as a playlist/bookmark list. While I don't know if it's a good idea to make it default, a good compromise will be making it a checkbox in the settings for those who want that.

P.S. Please forgive me for the spaghetti code, I have limited experience with JS/TS and this is my first contribution to open source 😅. If this is a feature that is OK to have, but none of the contributors have time or willingness to do it, I'm open to implementing it myself to the best of my abilities and opening a PR. Just wanted to check if it even has a chance of being merged in that case.