download-video
Skill176 starsChanged 7 months agoMITView on GitHub
Downloads embedded videos from web pages. Fetches the page, identifies the video hosting service (Vimeo, YouTube, etc.), resolves the correct embed/player URL, and downloads using yt-dlp. Handles private/unlisted videos that require referer headers or embed URLs. Use this skill when someone says "download this video", "save this video", "grab the video from this page", "rip this video", or provides a URL and asks to download media from it. Also trigger when someone pastes a URL to a page with an embedded video and wants the video file locally.
- Installs packages
We split this skill into the rules it gives an agent
11 rules. 0 are common, 5 are distinctive, and 6 are very specific to this project.
0
Common
Most of the 3 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 25
Ensure yt-dlp is installed and up to date (older versions hit different errors):
- Distinctive: line 44
Use WebFetch to inspect the target URL.
- Very specific: line 66
Vimeo: Use https://player.vimeo.com/video/{id} instead of https://vimeo.com/{id}
- Distinctive: line 68
Wistia: Use the embed URL with the media hash
- Very specific: line 70
If the video has a privacy hash (Vimeo h= parameter), include it:
- Distinctive: line 101
If the user wants a specific quality:
- Distinctive: line 148
Fix: Add the referer header from the source page:
- Very specific: line 163
Fix: Consider using a VPN. yt-dlp supports --proxy flag:
- Very specific: line 190
Use player.vimeo.com/video/{id} — referer optional but recommended
- Very specific: line 195
Check for iframe elements in the page source
- Very specific: line 207
Always convert to the player.vimeo.com embed form
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Download Video
This skill downloads embedded videos from web pages by inspecting the page source, identifying the video hosting service and embed URL, then using yt-dlp to download the video file.
Why This Skill Exists
Many event replays, webinars, and talks are embedded on pages using private/unlisted video hosting (especially Vimeo). The direct video URL often returns 404 because the video is only accessible through the embed player with the correct referer. This skill handles that automatically.
Prerequisites
Ensure yt-dlp is installed and up to date (older versions hit different errors):
which yt-dlp || brew install yt-dlp
brew upgrade yt-dlpInstall the impersonation library. On modern macOS (Python installed via Homebrew), the --break-system-packages flag is required:
pip3 install --break-system-packages curl_cffiNote: curl_cffi alone does not fix private Vimeo downloads. The embed URL approach (Step 2) is what actually works. But curl_cffi prevents a misleading OAuth 400 error that obscures the real issue.
How to Use This Skill
Step 1: Fetch the Page and Identify the Video
Use WebFetch to inspect the target URL. Look for:
- iframe src attributes pointing to video players
- video/source tags with direct media URLs
- Schema.org VideoObject metadata (
contentUrl,embedUrl) - JavaScript variables containing video URLs or config objects
- Data attributes on player container elements
Extract the video hosting service and any identifying info:
| Host | URL Pattern | Embed Pattern |
| Vimeo | vimeo.com/{id} | player.vimeo.com/video/{id} |
| YouTube | youtube.com/watch?v={id} | youtube.com/embed/{id} |
| Wistia | fast.wistia.com/medias/{id} | fast.wistia.com/embed/medias/{id} |
| Brightcove | varies | players.brightcove.net/{account}/{player}/index.html?videoId={id} |
| Loom | loom.com/share/{id} | loom.com/embed/{id} |
Step 2: Resolve the Download URL
The direct URL (e.g., vimeo.com/123456) often fails for private/unlisted videos. Use the embed/player URL instead:
- Vimeo: Use
https://player.vimeo.com/video/{id}instead ofhttps://vimeo.com/{id} - YouTube: The direct URL usually works, but embed URL works too
- Wistia: Use the embed URL with the media hash
If the video has a privacy hash (Vimeo h= parameter), include it:
https://player.vimeo.com/video/{id}?h={hash}Step 3: Download with yt-dlp
For Vimeo specifically, skip the direct URL and go straight to the embed URL. The direct URL almost always fails for private/unlisted videos. For other hosts, try in order and stop at the first that works.
Attempt 1 — Embed/player URL (start here for Vimeo):
yt-dlp "https://player.vimeo.com/video/{id}"Attempt 2 — With referer header (if Attempt 1 returns 403):
yt-dlp --referer "{source_page_url}" "https://player.vimeo.com/video/{id}"Attempt 3 — With referer + origin headers:
yt-dlp --referer "{source_page_url}" --add-header "Origin: {source_origin}" "https://player.vimeo.com/video/{id}"Attempt 4 — Direct URL (only for public videos or non-Vimeo hosts):
yt-dlp "{video_url}"Step 4: Quality Selection (Optional)
If the user wants a specific quality:
# List available formats
yt-dlp -F "{url}"
# Download best quality (default)
yt-dlp -f "bestvideo+bestaudio" "{url}"
# Download specific resolution
yt-dlp -f "bestvideo[height<=1080]+bestaudio" "{url}"
# Download audio only
yt-dlp -f "bestaudio" -x --audio-format mp3 "{url}"Step 5: Output Location
By default yt-dlp saves to the current directory. To specify an output path:
yt-dlp -o "~/Downloads/%(title)s.%(ext)s" "{url}"Troubleshooting
OAuth Token Error (Vimeo)
ERROR: Failed to fetch OAuth token: HTTP Error 400: Bad RequestThis happens when yt-dlp tries the direct vimeo.com/{id} URL without impersonation support. Two things to do:
- Install
curl_cffi:pip3 install --break-system-packages curl_cffi - More importantly, switch to the embed URL — this is the actual fix. Even with
curl_cffi, the direct URL will likely fail with a 404 (see below) because the video is private.
404 Not Found (Vimeo)
ERROR: Unable to download macos API JSON: HTTP Error 404: Not FoundThis is what you get after installing curl_cffi and updating yt-dlp — the OAuth error goes away but the video still can't be found because it's private/unlisted on the direct URL. Switch to the embed URL:
vimeo.com/{id}->player.vimeo.com/video/{id}
The typical Vimeo error progression is: OAuth 400 -> (install curl_cffi + update yt-dlp) -> 404 -> (use embed URL) -> success.
403 Forbidden
ERROR: HTTP Error 403: ForbiddenFix: Add the referer header from the source page:
yt-dlp --referer "{source_page_url}" "{embed_url}"Impersonation Warning
WARNING: The extractor is attempting impersonation, but no impersonate target is availableFix: Install curl_cffi. This is a non-fatal warning but may cause downstream failures.
Geo-restricted Content
ERROR: This video is not available in your countryFix: Consider using a VPN. yt-dlp supports --proxy flag:
yt-dlp --proxy socks5://127.0.0.1:1080 "{url}"Real-World Example: OpenAI Forum Vimeo Embed
This is the exact sequence that works, tested on forum.openai.com event replay pages (2026-03-28):
# 1. Page has schema.org VideoObject with contentUrl: https://vimeo.com/1174947711
# Direct URL fails (private video).
# 2. This works — use the player embed URL:
yt-dlp --referer "https://forum.openai.com/" "https://player.vimeo.com/video/1174947711"
# 3. yt-dlp downloads HLS fragments (484 in this case), merges video+audio.
# Result: ~683MB MP4 file.The referer wasn't strictly required for this specific video (Attempt 1 worked), but including it is good practice for Vimeo embeds.
Common Video Page Patterns
OpenAI Forum Events
- Videos are Vimeo embeds, video ID found in schema.org
contentUrl - Direct Vimeo URLs return 404 (private)
- Use
player.vimeo.com/video/{id}— referer optional but recommended - Downloads as HLS stream (many fragments), yt-dlp merges automatically
Conference Talk Pages
- Often use Vimeo or YouTube embeds
- Check for
iframeelements in the page source - Some use custom players that wrap YouTube/Vimeo — look for the underlying embed URL
Course/LMS Platforms
- Often use Wistia or Vimeo with domain restrictions
- Referer header is usually required
- May require cookies — use
--cookies-from-browser chromeif needed
Gradual/Event Platforms
- Many event replay platforms (like the one OpenAI Forum uses) are built on Gradual
- They store video metadata in schema.org VideoObject in the page head
- The
contentUrlfield has the Vimeo URL, but it's the public-facing URL that won't work for download - Always convert to the
player.vimeo.comembed form
Other versions5 projects use a version of this.
Word for word · 1
- biyearly-mesothelioma790/skills★ 0100% same
Edited · 0
None found.
Wrote their own version · 4
- rameerez/claude-code-startup-skills★ 30same name
- feiskyer/video-skills★ 14same name
- cyberpinkman/awesome-capture★ 2same name
- tograf/sidebrain★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository101 other files it gives its agents.
- AGENTS.mdAGENTS.md
- accelevents-apiSkill
- accelevents-speaker-syncSkill
- agents-sdkSkill
- ai-devblogSkill
- ai-engineeringSkill
- ai-readmeSkill
- align-meSkill
- annotated-video-productionSkill
- antislop-codebaseSkill
- app-ux-paradigmsSkill
- autoreviewSkill
- babysit-runsSkill
- blog-system-designSkill
- cassandra-creatorSkill
- ceo-creatorSkill
- claude-session-introspectSkill
- cli-uxSkill
- cloudflare-do-turn-based-multiplayerSkill
- cloudflare-email-serviceSkill
- cloudflare-one-migrationsSkill
- cloudflare-oneSkill
- cloudflare-production-builderSkill
- cloudflareSkill
- conference-developer-endpointsSkill
- conference-transcribeSkill
- coordinateSkill
- data-chatbotsSkill
- data-visualization-qualitySkill
- deep-trajectory-analysisSkill
- design-apps-with-imagegenSkill
- design-preferencesSkill
- diy-netlifySkill
- download-x-videoSkill
- durable-objectsSkill
- europe-developer-apiSkill
- face-matchingSkill
- forgeSkill
- future-onlySkill
- generalizeSkill
- gsuite-setupSkill
- keep-it-simpleSkill
- latent-space-thumbnail-directorSkill
- live-ai-pipelinesSkill
- location-inputSkill
- long-running-operation-uxSkill
- media-heavy-workflowsSkill
- media-to-wiki-pipelineSkill
- media-transformSkill
- mobile-nativeSkill
- mobile-webapp-uxSkill
- multimodal-extractionSkill
- new-mac-setupSkill
- next-stepsSkill
- observability-hardeningSkill
- person-profile-writingSkill
- podcast-publishing-assistantSkill
- productionize-app-with-servicesSkill
- programmatic-agentsSkill
- provision-model-keysSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

