Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

YouTube Playlist Saver

A Safari Web Extension that adds "Add to playlist" rows to YouTube's video ⋮ menu, saving each video as a bookmark in a chosen DEVONthink group.

  • One shared codebase for macOS Safari (v1 focus) and iOS/iPadOS (later).
  • On macOS: saves silently via AppleScript into DEVONthink (no app switch).
  • On iOS (and as a macOS fallback): saves via the x-devonthink:// URL scheme.
  • Configurable playlists (each = one DEVONthink group) + optional hiding of YouTube's native "Save to Watch later" item.

Status

Work in progress. The DEVONthink save layer is verified on macOS — both the AppleScript path and the x-devonthink:// URL scheme create bookmarks correctly. The Safari packaging + in-browser flow is not yet built/tested (requires Xcode; see below). YouTube DOM selectors will likely need tuning against the live site.

Layout

extension/                 ← the web-extension source (author here)
  manifest.json
  background/service-worker.js
  content/inject.js, inject.css
  options/options.html, options.js, options.css
  lib/store.js, devonthink.js
native/
  SafariWebExtensionHandler.swift   ← paste into the generated Xcode target

Build (macOS)

The web-extension source lives in extension/. Wrap it in an Xcode app + Safari extension target with Apple's converter:

cd "/Users/andyjohansson/Dev/YouTube Playlist"
xcrun safari-web-extension-converter extension/ \
  --project-location ./xcode \
  --app-name "YouTube Playlist Saver" \
  --bundle-identifier com.example.YouTubePlaylistSaver \
  --macos-only        # drop this later to also generate the iOS target

Then in the generated Xcode project:

  1. Native handler — replace the generated SafariWebExtensionHandler.swift (in the extension target) with native/SafariWebExtensionHandler.swift.
  2. Entitlement — in the extension target's .entitlements, add: com.apple.security.automation.apple-events = YES.
  3. Info.plist — in the extension target, add NSAppleEventsUsageDescription = "Saves YouTube bookmarks to DEVONthink."
  4. Bundle id — set NATIVE_APP_ID in extension/background/service-worker.js to match the container app's bundle identifier used above.
  5. Build & run the app target (⌘R).

Enable the extension in Safari

  1. Safari → Settings → Advanced → check Show features for web developers.
  2. Safari → DevelopAllow Unsigned Extensions (needed each Safari launch for local, unsigned dev builds).
  3. Safari → Settings → Extensions → enable YouTube Playlist Saver and, when prompted, allow it to access youtube.com.
  4. On the first save, macOS prompts to let the extension control DEVONthink — allow it. (If denied/blocked, saves fall back to the URL scheme automatically.)

Configure playlists

Open the extension's options page (Safari → Settings → Extensions → YouTube Playlist SaverPreferences, or via the extension action):

  1. In DEVONthink, right-click a group → Copy Item Link (x-devonthink-item://<UUID>).
  2. In options, enter a name and paste the linkAdd playlist. Leave the link empty to save into DEVONthink's global inbox.
  3. Optionally toggle Hide "Save to Watch later" (off by default).

Verify (end-to-end, macOS)

  1. Add a playlist pointing at a real DEVONthink group.
  2. On youtube.com, open a video's ⋮ menu → a "Spellistor" section with your playlist row appears at the top. Click it.
  3. Confirm a bookmark to the correct video URL lands in that DEVONthink group.
    • Silent (native) path = no app switch.
    • Fallback path = a brief flash to DEVONthink via the URL scheme.
  4. Toggle Hide "Save to Watch later" → confirm the native item hides/returns.
  5. Repeat from a feed thumbnail and from a /watch page.

Known fragile spots

  • YouTube DOM: the ⋮ popup is a shared, reused element; selectors in content/inject.js (ytd-menu-popup-renderer, #items, the video-container tags) may need tuning as YouTube changes markup. Fallback idea if it gets too brittle: inject a button into the thumbnail hover overlay instead.
  • Watch-later hiding matches by localized label text (WATCH_LATER_LABELS in inject.js); add locales there if needed.
  • Sandboxed Apple Events: if the extension sandbox blocks AppleScript, the JS falls back to the x-devonthink:// URL scheme (functional, brief app switch).

Later (not in v1)

  • iOS target + code signing (paid Apple Developer account for stable installs).
  • Obsidian .md append as an alternate playlist target type.
  • Native handler enumerating DEVONthink groups so the options page offers a dropdown instead of pasting item links.

About

Safari extension to save YouTube videos to custom DEVONthink playlists from the video ⋮ menu (macOS + iOS)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages