How yt-dlp Integration Works in Claude-Video for Automated Video Downloads
Claude-Video uses a Python wrapper in skills/watch/scripts/download.py that constructs deterministic yt-dlp command lines to either fetch metadata and subtitles only or perform full video downloads, automatically detecting URLs versus local file paths and post-processing outputs into standardized MP4 and VTT formats.
The bradautomates/claude-video repository implements a robust video ingestion pipeline by wrapping yt-dlp in a thin abstraction layer. This integration handles everything from bandwidth-efficient subtitle retrieval to high-performance parallel video downloads, ensuring reliable media processing for AI-powered video analysis.
Source Detection and URL Validation
Before initiating any download operation, the system determines whether the user input is a remote URL or a local file path. In skills/watch/scripts/download.py, the is_url() function (lines 20-25) performs this validation, branching the execution flow accordingly.
- Local paths bypass yt-dlp entirely and proceed directly to file validation.
- Remote URLs trigger the yt-dlp wrapper logic, beginning with either metadata retrieval or full download depending on the caller's requirements.
This early branching prevents unnecessary network operations when users provide locally stored media files.
Metadata-Only Retrieval for Bandwidth Efficiency
When the system only needs to verify subtitle availability or extract video metadata without downloading the full media stream, the fetch_captions() function (lines 66-86) constructs a lightweight yt-dlp command. This approach conserves bandwidth by skipping the actual media download while still retrieving structured data and caption files.
The function passes the following flags to yt-dlp:
--skip-download– Prevents media file retrieval--write-info-json– Outputs structured metadata to a JSON file--write-subsand--write-auto-subs– Retrieves both manual and auto-generated captions--sub-langs en.*– Filters for English language subtitles--sub-format vttand--convert-subs vtt– Standardizes output to WebVTT format
This metadata-first strategy allows the /watch skill to check for existing transcripts before committing to a full video download.
Full Video Download with Parallel Processing
For complete media ingestion, the download_url() function (lines 26-44 and 126-152) assembles a comprehensive yt-dlp command optimized for speed and compatibility. The wrapper automatically configures format selection, parallel downloads, and post-processing.
Key implementation details include:
- Format selectors – Uses
bv*[height<=720]+bafor video+audio up to 720p, orba/bestaudiofor audio-only mode when processing transcripts without visual analysis - Parallelism – The
-N 8flag enables 8 concurrent fragment downloads to maximize throughput - Output standardization –
--merge-output-format mp4ensures consistent container formats across different source platforms - Error resilience –
--ignore-errorsand--no-playlistprevent single-video failures from cascading and restrict downloads to the specific URL provided
After the subprocess completes, helper functions _pick_video() and _pick_subtitle() (lines 44-63 and 98-111) locate the generated files within the output directory. If no video file is detected, the wrapper raises an explicit error (lines 49-52) to halt downstream processing.
Orchestration Logic in the Watch Skill
The high-level entry point in skills/watch/scripts/watch.py (lines 97-123) implements intelligent fallback logic to minimize unnecessary data transfer. First, it calls fetch_captions() to check for existing subtitles without downloading the video file. Only if captions are missing or if the user explicitly requests frame extraction does the system invoke the full download() function.
This tiered approach ensures that transcript-only queries complete in seconds rather than minutes, while still supporting full video analysis when visual content is required.
Binary Validation and Dependency Management
The integration relies on three external binaries: yt-dlp, ffmpeg, and ffprobe. The setup.py file defines these requirements in the REQUIRED_BINARIES list (line 35), while download.py (lines 66-68) verifies their presence before executing any commands.
If yt-dlp is not found in the system PATH, the script aborts with installation instructions for Homebrew, pip, or Winget package managers. This pre-flight check prevents cryptic subprocess errors and ensures users receive actionable remediation guidance.
Practical Implementation Examples
Downloading a Full Video with Subtitles
from pathlib import Path
from skills.watch.scripts.download import download
# Download a YouTube video into a temporary directory
out = download(
source="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
out_dir=Path("/tmp/watch-demo"),
audio_only=False,
)
print("Video saved at:", out["video_path"])
print("Subtitle (VTT) path:", out["subtitle_path"])
print("Metadata:", out["info"])
Retrieving Only Subtitles Without Media
from skills.watch.scripts.download import fetch_captions
from pathlib import Path
info = fetch_captions(
url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
out_dir=Path("/tmp/watch-captions")
)
print("Subtitle path (if any):", info["subtitle_path"])
print("Video title from info‑json:", info["info"].get("title"))
Using the Watch Command Line Interface
python -m skills.watch.scripts.watch \
"https://www.youtube.com/watch?v=dQw4w9WgXcQ" \
--detail balanced \
--resolution 720
The CLI automatically selects between metadata-only and full download modes based on the requested detail level and existing caption availability.
Summary
- URL Detection – The
is_url()function indownload.py(lines 20-25) distinguishes between local files and remote URLs before invoking yt-dlp. - Two-Path Architecture –
fetch_captions()retrieves only metadata and VTT files, whiledownload_url()performs full media extraction with parallel downloading enabled by the-N 8flag. - Format Optimization – Dynamic format selectors ensure videos do not exceed 720p unless specified, with automatic fallback to audio-only for transcript-focused workflows.
- Post-Processing – Helper functions
_pick_video()and_pick_subtitle()standardize output handling, ensuring downstream components receive predictable file paths. - Dependency Safety –
setup.py(line 35) anddownload.py(lines 66-68) enforce binary prerequisites before execution, preventing runtime failures.
Frequently Asked Questions
How does Claude-Video handle missing yt-dlp installations?
The system validates the presence of yt-dlp, ffmpeg, and ffprobe before executing any download commands. In skills/watch/scripts/setup.py (line 35), the REQUIRED_BINARIES list defines these dependencies, and download.py (lines 66-68) checks for their availability. If yt-dlp is missing, the script exits immediately with platform-specific installation instructions for Homebrew, pip, or Winget.
Can the integration download videos without subtitles?
Yes. While the default configuration retrieves both media and subtitles, you can modify the download_url() behavior by adjusting the command construction in skills/watch/scripts/download.py. The current implementation always includes subtitle flags for comprehensive AI analysis, but the --write-subs and related flags can be removed from the argument list if only the video file is required.
What happens if a video download fails or returns no file?
The wrapper implements explicit error handling in download_url() (lines 49-52). If the _pick_video() helper cannot locate a media file after the yt-dlp subprocess completes, the function raises a FileNotFoundError with a descriptive message. This prevents the pipeline from attempting to process non-existent files and provides clear feedback for debugging URL or format selector issues.
How does the system decide between metadata-only and full downloads?
The decision logic resides in skills/watch/scripts/watch.py (lines 97-123). The code first attempts fetch_captions() to check for existing VTT subtitles without downloading the video. Only if no captions are found, or if the user explicitly requests frame extraction (visual analysis), does the system proceed to the full download() path. This tiered approach minimizes bandwidth usage for transcript-only queries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →