youtube_helper package
Submodules
- youtube_helper.api module
- Usage Example
- Author
ChannelVideosBodyCommentsBodyDownloadBodyEngagementBatchBodyResolveBodyStreamFiltersBodyStreamFiltersBody.cookies_from_browserStreamFiltersBody.include_combinedStreamFiltersBody.include_video_onlyStreamFiltersBody.languageStreamFiltersBody.max_fpsStreamFiltersBody.model_configStreamFiltersBody.prefer_codecStreamFiltersBody.prefer_formatStreamFiltersBody.urlStreamFiltersBody.verbose
SubtitlesBodyUrlBodyYtDlpVersionBodyaudio_endpoint()channel_info_endpoint()channel_videos_endpoint()comments_endpoint()engagement_batch_endpoint()engagement_endpoint()gui()health()list_streams()metadata()pick_stream()resolve()root()subtitles_endpoint()thumbnail_endpoint()valid()video_endpoint()ytdlp_version_endpoint()
- youtube_helper.branding module
- youtube_helper.cli_argparse module
- youtube_helper.cli_click module
- youtube_helper.gui module
- youtube_helper.main module
- youtube_helper.mcp module
- youtube_helper.streaming module
- youtube_helper.streaming
DirectMediaURLVideoStreamInfoVideoStreamInfo.acodecVideoStreamInfo.containerVideoStreamInfo.extVideoStreamInfo.filesize_bytesVideoStreamInfo.format_idVideoStreamInfo.fpsVideoStreamInfo.headersVideoStreamInfo.heightVideoStreamInfo.is_liveVideoStreamInfo.languageVideoStreamInfo.noteVideoStreamInfo.protocolVideoStreamInfo.urlVideoStreamInfo.vbr_kbpsVideoStreamInfo.vcodecVideoStreamInfo.width
extract_frames_stream()list_video_streams()pick_video_stream()resolve_direct_url()
Module contents
YouTube Helper
Utilities for downloading videos, audio, thumbnails, resolving direct media URLs, and pulling public engagement metadata — from YouTube, Vimeo, DailyMotion, Twitch VOD, and any other site yt-dlp supports.
Modules
maindownload helpers (videos / audio / thumbnails) andmetadata extraction.
streamingURL resolver that turns a user-facing page URL into adirect media URL (with the right headers / cookies) so an ffmpeg-based reader can consume it without going through yt-dlp again. Pure resolution — no PCM decoding (that’s
podcast_helper’s job).
brandingno-API engagement helpers (channel info, video listswith normalised metrics, subtitles, comments). Built on yt-dlp’s public metadata — no Google Data API, no Vimeo API, no OAuth, no quota.
Multi-surface exposure
The same functions are also available as:
youtube_helper.cli_argparse— argparse-based CLI, entry pointyoutube-helper. No extra dependency.youtube_helper.cli_click— click-based twin CLI, entry pointyoutube-helper-click. Requires the[cli]extra.youtube_helper.api— FastAPI HTTP surface. Requires the[api]extra.youtube_helper.mcp— MCP tools over the FastAPI app, entry pointyoutube-helper-mcp. Requires the[api,mcp]extras.
Dependencies - yt-dlp - ffmpeg (on PATH) - os-helper / audio-helper / video-helper
Usage Example
>>> import youtube_helper as yth
>>> meta = yth.video_url_meta_data("https://www.youtube.com/watch?v=YE7VzlLtp-4")
>>> yth.download_audio("https://www.youtube.com/watch?v=YE7VzlLtp-4", "out.mp3")
- class youtube_helper.DirectMediaURL[source]
Bases:
TypedDictResolved direct-media URL ready for ffmpeg.
Keys
- urlstr
The direct media URL. Can be an HLS
.m3u8(live), DASH.mpd, or progressive.mp4/.webm— whicheveryt-dlpselected.- containerstr
Container format string (
"hls","dash","mp4","webm","audio", …). Useful for ffmpeg’s-fhint if the URL extension is ambiguous.- is_livebool
True if the source is a live stream. Callers may want to skip
-re(real-time pacing) since live is already real-time.- headersdict[str, str]
HTTP headers the player must send with the request. YouTube often requires a specific
User-AgentandRefererto avoid 403s; pass them to ffmpeg via-headers.
- class youtube_helper.VideoStreamInfo[source]
Bases:
TypedDictOne video format’s metadata, normalised across extractors.
Keys
- format_idstr
yt-dlp’s stable identifier for this format on this URL.
- urlstr
The direct media URL — ready for ffmpeg / PyAV.
- headersdict[str, str]
HTTP headers ffmpeg must send with the request (User-Agent, Referer, Cookie, …). Pass through to
video_helper.extract_frames(http_headers=...)or to ffmpeg’s-headersflag.- extstr
File extension reported by yt-dlp (
"mp4"/"webm"/"m3u8"/ …).- containerstr
Normalised container hint (
"mp4"/"webm"/"hls"/"dash") — useful when the ext is ambiguous.- vcodecstr
Video codec (
"h264"/"vp9"/"av01"/"none"if audio-only — filtered out of this list).- acodecstr
Audio codec (
"none"for video-only formats — common on YouTube DASH, paired with a separate audio-only format).- width, heightint
Pixels.
0if unknown (rare).- fpsfloat
Frames per second.
0.0if unknown.- vbr_kbpsfloat
Estimated video bitrate in kbit/s.
0.0if unknown.- filesize_bytesint
Estimated file size in bytes.
0if unknown (always 0 for live).- is_livebool
True if this is a live stream (URL is an HLS / DASH manifest).
- protocolstr
yt-dlp’s protocol string (
"https"/"m3u8_native"/"http_dash_segments"/ …).- languagestr | None
Language code if the format carries an explicit one (rare for video; common for audio).
- notestr
yt-dlp’s
format_note— typically a human-readable label ("1080p60","Premium", …).
- youtube_helper.channel_info(url, verbose=False)[source]
Return one normalised dict describing the channel / creator page.
Works with YouTube channel URLs (/@handle, /channel/UC…), Vimeo user pages, DailyMotion creators. Pulls subscriber count, channel title, description, total view count when available.
- youtube_helper.channel_videos(url, max_videos=200, include_shorts=True, include_lives=False, verbose=False)[source]
List videos of a channel / creator page with per-video engagement metadata.
For YouTube channels, walks the uploads playlist; for Vimeo / DailyMotion, walks the user page. Each entry is normalised to the same engagement schema (
id,url,title,duration_seconds,view_count,like_count,comment_count,upload_date,kind, …).Two-pass strategy: a fast flat listing first (1 call), then per-video metadata fetch (1 call per video). The second pass is what makes
view_count/like_countreliable —extract_flatreturns IDs and sometimesview_count, but rarely likes / comments.
- youtube_helper.default_ytdlp_options(overwrites=True, audio=False, video=False, cookie_dir=None)[source]
Generate default yt-dlp options based on provided parameters.
- Parameters:
overwrites (bool, optional) – Whether to overwrite existing files. Default is True.
audio (bool, optional) – Whether to download audio only. Default is False.
video (bool, optional) – Whether to download video only (overrides audio). Default is False.
cookie_dir (str or None, optional) – Directory in which yt-dlp’s session cookie jar is written. The download helpers pass their
temporary_folderhere so the jar disappears when thewithblock exits; when omitted it falls back to the system temp directory. It is never written to the current working directory.
- Returns:
A dictionary of options for yt-dlp.
- Return type:
Notes
The function sets various options for yt-dlp. If audio is set to True, the format is set to download the best audio available. If video is set to True, it overrides the audio flag and downloads video+audio.
- youtube_helper.download_audio(url, output_path=None, target_sample_rate=44100)[source]
Download the best quality audio from a given URL and save it to the specified output path.
- Parameters:
- Returns:
Path of downloaded audio
- Return type:
Notes
This function uses yt-dlp to download the best quality audio from the given URL. It handles different output formats and ensures the audio is saved with the desired sample rate using a conversion step if necessary.
- youtube_helper.download_thumbnail(url, output_path=None)[source]
Download the thumbnail of a video from a given URL and save it to the specified output path.
- Parameters:
- Returns:
Path of downloaded thumbnail
- Return type:
Notes
This function uses yt-dlp to download the thumbnail of the specified video. It handles different output formats and ensures the thumbnail is saved in the desired format using PIL.
- youtube_helper.download_video(url, output_path=None)[source]
Download video from a given URL and save it to the specified output path.
- Parameters:
- Returns:
Path of downloaded video
- Return type:
Notes
This function downloads the best quality video from the given URL using yt-dlp. It handles different formats and ensures that the video is saved in the desired format using ffmpeg if necessary. The function checks whether the downloaded video is valid and converts it to the specified output format if needed.
- youtube_helper.engagement_batch(urls, verbose=False)[source]
Map a list of URLs to normalised engagement dicts, one per URL.
Tolerant: bad URLs / unavailable videos are reported as {“url”: …, “_error”: “…”} rather than raising.
- youtube_helper.ensure_recent_ytdlp(min_version=None)[source]
Return the installed yt-dlp version. Warn if older than min_version.
YouTube changes its signature scheme roughly every quarter; an outdated yt-dlp is the #1 cause of failures. Callers that mind freshness can surface a warning early.
- youtube_helper.extract_frames_stream(url, *, prefer_codec=None, prefer_format=None, max_fps=None, language=None, include_video_only=True, include_combined=True, cookies_from_browser=None, verbose=False, **extract_frames_kwargs)[source]
Stream frames from any yt-dlp-supported URL through
video_helper.extract_frames().One-call composition of:
pick_video_stream()— resolvesurlto a singleVideoStreamInfomatching the codec / format / fps / language constraints.video_helper.extract_frames()— opens the resolved direct media URL with the righthttp_headersand yields frames under the destination of your choice (numpy BGR, torch RGB, or PIL).
Why this exists
The two-step pattern is the published recipe (see
ai-helpers/EXAMPLES.mdandyoutube-helper/EXAMPLES.md):>>> stream = yth.pick_video_stream(url, prefer_codec="h264") >>> for frame in vh.extract_frames( ... stream["url"], http_headers=stream["headers"], ... destination="torch", device="auto", batch_size=32, ... ): ... model(frame)
extract_frames_streamcollapses both calls into one, plumbs the headers automatically, and lets the caller forward anyextract_frameskwarg (destination,device,batch_size,output_width,frame_step, …) verbatim.- param url:
Any URL
yt-dlpcan extract (YouTube / Vimeo / DailyMotion / Twitch VOD / …). Live streams are accepted as well — the returned iterator runs until the live source ends.- type url:
str
- param prefer_codec:
Forwarded to
pick_video_stream(). See its docstring for the matching semantics. Defaults pick yt-dlp’s best candidate.- type prefer_codec:
optional
- param prefer_format:
Forwarded to
pick_video_stream(). See its docstring for the matching semantics. Defaults pick yt-dlp’s best candidate.- type prefer_format:
optional
- param max_fps:
Forwarded to
pick_video_stream(). See its docstring for the matching semantics. Defaults pick yt-dlp’s best candidate.- type max_fps:
optional
- param language:
Forwarded to
pick_video_stream(). See its docstring for the matching semantics. Defaults pick yt-dlp’s best candidate.- type language:
optional
- param include_video_only:
Forwarded to
pick_video_stream(). Defaults keep both.- type include_video_only:
bool, optional
- param include_combined:
Forwarded to
pick_video_stream(). Defaults keep both.- type include_combined:
bool, optional
- param cookies_from_browser:
Forwarded to
pick_video_stream(). Required for age-gated / members-only content.- type cookies_from_browser:
str, optional
- param verbose:
Forwarded to
pick_video_stream().- type verbose:
bool, optional
- param **extract_frames_kwargs:
Any keyword accepted by
video_helper.extract_frames():start_index/end_index/start_instant/end_instant/stabilize/frame_step/frame_interval/frame_indices/frame_times/backend/hwaccel/output_width/output_height/pad_color/destination/device/batch_size/layout.Note:
http_headersis wired automatically from the resolved stream — passing it yourself overrides the resolver’s headers (rare; mostly useful when the caller already authored a stable header dict).- returns:
The same iterator type that
video_helper.extract_frames()returns — numpy / torch / PIL frames or batches per the passed-indestinationandbatch_size.- rtype:
Iterator
- raises RuntimeError:
If yt-dlp can’t extract the URL (private / removed / geo-blocked).
- raises ValueError:
If no stream matches the codec / format / fps / language constraints (the catalog itself was non-empty, but every entry got filtered out).
Examples
>>> import youtube_helper as yth >>> # Sequential decode at 1 frame per second, 224×224 letterboxed. >>> for frame in yth.extract_frames_stream( ... "https://www.youtube.com/watch?v=YE7VzlLtp-4", ... prefer_codec="h264", prefer_format="mp4", max_fps=30, ... frame_interval=1.0, output_width=224, output_height=224, ... ): ... model(frame)
>>> # Batched torch tensors on a GPU device — same downstream code as >>> # the file-based path. >>> for batch in yth.extract_frames_stream( ... "https://vimeo.com/123", ... destination="torch", device="auto", batch_size=32, ... ): ... logits = model(batch.float() / 255.0)
- youtube_helper.is_short(meta)[source]
Heuristic — true if the entry looks like a Short / vertical clip.
Looks at duration (≤ 60s), webpage_url (/shorts/), and #Shorts in title.
- youtube_helper.is_valid_video_url(url)[source]
Check if a given URL is a valid video URL using yt-dlp.
- Parameters:
url (str) – The URL to check.
- Returns:
True if the URL is valid, False otherwise.
- Return type:
Notes
This function extracts metadata from the URL using yt-dlp to determine if the URL points to a valid video.
- youtube_helper.list_video_streams(url, *, include_video_only=True, include_combined=True, cookies_from_browser=None, verbose=False)[source]
Enumerate every video format yt-dlp finds for this URL.
Results are ordered by yt-dlp’s quality ranking (best last). Pure video-only formats and combined (video + audio) formats are both included by default — adjust with the boolean flags.
- Parameters:
url (str) – Any URL yt-dlp can extract.
include_video_only (bool, optional) – Keep formats with
acodec="none"(DASH-style streams that need a separate audio mux). Default True.include_combined (bool, optional) – Keep formats with both video and audio (legacy progressive streams; common on Vimeo, rare on YouTube high-quality). Default True.
cookies_from_browser (str, optional) – Pass through to yt-dlp’s
--cookies-from-browser(e.g."firefox"/"chrome"/"safari") for age-gated or login-required content.verbose (bool, optional) – Echo yt-dlp’s output to stderr (off by default).
- Returns:
Possibly empty if the URL has no video (audio-only podcast, for example).
- Return type:
- Raises:
RuntimeError – If yt-dlp could not extract info at all (private video, geo-blocked without bypass, removed, …).
- youtube_helper.pick_video_stream(url, *, prefer_codec=None, prefer_format=None, max_fps=None, language=None, include_video_only=True, include_combined=True, cookies_from_browser=None, verbose=False)[source]
Pick a single best video stream matching the given constraints.
Among the catalog returned by
list_video_streams(), applies each non-None constraint as a hard filter, then returns the highest-ranked remaining candidate (yt-dlp’s native order — typically sorts by height × bitrate).- Parameters:
url (str) – Source URL (any yt-dlp-supported site).
prefer_codec (str, optional) – Substring match against
vcodec("h264"matches both"avc1.640028"and"h264"once normalised;"vp9"matches"vp09.00.40.08";"av1"matches"av01...").prefer_format (str, optional) – Equality match against
ext("mp4"/"webm").max_fps (float, optional) – Drop formats with
fps > max_fps.language (str, optional) – Equality match against the format’s
language(rarely set for video — primarily useful when the source carries multi-track video).include_video_only (bool, optional) – See
list_video_streams().include_combined (bool, optional) – See
list_video_streams().cookies_from_browser (same as
list_video_streams().)verbose (same as
list_video_streams().)
- Returns:
The chosen stream.
- Return type:
- Raises:
RuntimeError – If yt-dlp can’t extract the URL.
ValueError – If no stream matches the constraints (the catalog itself was non-empty, but every entry got filtered out).
- youtube_helper.resolve_direct_url(url, *, prefer='audio', live='auto')[source]
Resolve
urlto a direct, ffmpeg-readable media URL.- Parameters:
url (str) – Any URL
yt-dlpcan extract (YouTube / Vimeo / DailyMotion / Twitch / …).prefer (
"audio"|"video") – Format preference."audio"selectsbestaudio— cheapest path for ASR + diarization."video"selectsbest(video + audio muxed), useful for the/videoview (Phase 7) that needs the visual track too.live (
"auto"|"force_live"|"force_vod") –"auto"propagates whatever the info dict says (the usual case). The other two override — handy for testing or when the site mislabels a stream.
- Returns:
See class docstring.
- Return type:
- Raises:
RuntimeError – If
yt-dlpcould not extract a usable URL (private video, geo-blocked without bypass, removed, …).
- youtube_helper.video_comments(url, max_count=100, cookies_from_browser=None, verbose=False)[source]
Fetch comments via yt-dlp’s getcomments.
YouTube increasingly requires browser cookies for comment scraping. If cookies_from_browser is set (e.g. “firefox”, “chrome”, “safari”), yt-dlp will pull cookies from that browser’s profile. On macOS this is the only reliable way to get YouTube comments today.
Returns a list of normalised comment dicts: id, parent, author, text, like_count, timestamp.
- youtube_helper.video_engagement(url, verbose=False)[source]
Single-video engagement snapshot. Returns the normalised dict shape.
- youtube_helper.video_subtitles(url, output_dir, langs=('fr', 'en'), auto_only=True, verbose=False)[source]
Download auto-generated (or manual) subtitles into output_dir.
Returns a dict mapping language → absolute path of the saved .vtt file. Languages that aren’t available are silently skipped.
- youtube_helper.video_url_meta_data(url)[source]
Retrieve metadata from a video URL without downloading the video.
- Parameters:
url (str) – The URL of the video.
- Returns:
A dictionary containing the video’s metadata, including title and description.
- Return type:
Notes
The function checks for metadata extraction success, logs the title and a part of the description, and returns metadata.