YoutubeExplode
Abstraction layer over YouTube's internal API
Install / Use
/learn @Tyrrrz/YoutubeExplodeREADME
YoutubeExplode
<table> <tr> <td width="99999" align="center">Development of this project is entirely funded by the community. <b><a href="https://tyrrrz.me/donate">Consider donating to support!</a></b></td> </tr> </table> <p align="center"> <img src="favicon.png" alt="Icon" /> </p>YoutubeExplode is a library that provides an interface to query metadata of YouTube videos, playlists and channels, as well as to resolve and download video streams and closed caption tracks. Behind a layer of abstraction, this library works by scraping raw page data and exploiting reverse-engineered internal endpoints.
📝 Interested in the inner workings of this library? See the Reverse-Engineering YouTube article.
Extension packages:
- YoutubeExplode.Converter — provides an interface to download and convert videos using FFmpeg
Terms of use<sup>[?]</sup>
By using this project or its source code, for any purpose and in any shape or form, you grant your implicit agreement to all the following statements:
- You condemn Russia and its military aggression against Ukraine
- You recognize that Russia is an occupant that unlawfully invaded a sovereign state
- You support Ukraine's territorial integrity, including its claims over temporarily occupied territories of Crimea and Donbas
- You reject false narratives perpetuated by Russian state propaganda
To learn more about the war and how you can help, click here. Glory to Ukraine! 🇺🇦
Install
- 📦 NuGet:
dotnet add package YoutubeExplode
Screenshots

Usage
YoutubeExplode exposes its functionality through a single entry point — the YoutubeClient class.
Create an instance of this class and use the provided operations on Videos, Playlists, Channels, and Search properties to send requests.
Videos
Retrieving video metadata
To retrieve the metadata associated with a YouTube video, call Videos.GetAsync(...):
using YoutubeExplode;
using var youtube = new YoutubeClient();
// You can specify either the video URL or its ID
var videoUrl = "https://youtube.com/watch?v=u_yIGGhubZs";
var video = await youtube.Videos.GetAsync(videoUrl);
var title = video.Title; // "Collections - Blender 2.80 Fundamentals"
var author = video.Author.ChannelTitle; // "Blender"
var duration = video.Duration; // 00:07:20
Downloading video streams
Every YouTube video has a number of streams available, differing in containers, video quality, bitrate, framerate, and other parameters. Additionally, the streams are further divided into 3 categories based on their content:
- ~~Muxed streams — contain both video and audio~~ (no longer provided by YouTube)
- Audio-only streams — contain only audio
- Video-only streams — contain only video
[!WARNING] Muxed streams contain both audio and video, but these streams are limited in quality (up to 720p30). To download the video in the highest available quality, you will need to resolve the best audio-only and video-only streams separately and then mux them together. The muxing process can be performed using FFmpeg with the help of the YoutubeExplode.Converter package.
[!WARNING] Muxed streams are deprecated by YouTube and are not guaranteed to be available for every video. If possible, avoid relying on them too much and instead perform muxing manually using the provided audio-only and video-only streams.
You can request the manifest that lists all available streams for a particular video by calling Videos.Streams.GetManifestAsync(...):
using YoutubeExplode;
using var youtube = new YoutubeClient();
var videoUrl = "https://youtube.com/watch?v=u_yIGGhubZs";
var streamManifest = await youtube.Videos.Streams.GetManifestAsync(videoUrl);
Once the manifest is obtained, you can filter through the streams and identify the ones you're interested in:
using YoutubeExplode;
using YoutubeExplode.Videos.Streams;
// ...
// Get the highest bitrate audio-only stream
var streamInfo = streamManifest.GetAudioOnlyStreams().GetWithHighestBitrate();
// ...or the highest quality MP4 video-only stream
var streamInfo = streamManifest
.GetVideoOnlyStreams()
.Where(s => s.Container == Container.Mp4)
.GetWithHighestVideoQuality()
Finally, you can resolve the actual stream represented by the specified metadata using Videos.Streams.GetAsync(...) or download it directly to a file with Videos.Streams.DownloadAsync(...):
// ...
// Get the actual stream
var stream = await youtube.Videos.Streams.GetAsync(streamInfo);
// Download the stream to a file
await youtube.Videos.Streams.DownloadAsync(streamInfo, $"video.{streamInfo.Container}");
[!WARNING] While the
Urlproperty in the stream metadata can be used to access the underlying content, you need a series of carefully crafted HTTP requests in order to do so. It's highly recommended to useVideos.Streams.GetAsync(...)orVideos.Streams.DownloadAsync(...)instead, as they will perform all the heavy lifting for you.
Downloading closed captions
Closed captions can be downloaded in a similar way to media streams.
To get the list of available closed caption tracks, call Videos.ClosedCaptions.GetManifestAsync(...):
using YoutubeExplode;
using var youtube = new YoutubeClient();
var videoUrl = "https://youtube.com/watch?v=u_yIGGhubZs";
var trackManifest = await youtube.Videos.ClosedCaptions.GetManifestAsync(videoUrl);
Then retrieve the metadata for a particular track:
// ...
// Find closed caption track in English
var trackInfo = trackManifest.GetByLanguage("en");
Finally, use Videos.ClosedCaptions.GetAsync(...) to get the actual content of the track:
// ...
var track = await youtube.Videos.ClosedCaptions.GetAsync(trackInfo);
// Get the caption displayed at 0:35
var caption = track.GetByTime(TimeSpan.FromSeconds(35));
var text = caption.Text; // "collection acts as the parent collection"
You can also download the closed caption track in the SRT file format with Videos.ClosedCaptions.DownloadAsync(...):
// ...
await youtube.Videos.ClosedCaptions.DownloadAsync(trackInfo, "cc_track.srt");
Playlists
Retrieving playlist metadata
You can get the metadata associated with a YouTube playlist by calling the Playlists.GetAsync(...) method:
using YoutubeExplode;
using var youtube = new YoutubeClient();
var playlistUrl = "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6";
var playlist = await youtube.Playlists.GetAsync(playlistUrl);
var title = playlist.Title; // "First Steps - Blender 2.80 Fundamentals"
var author = playlist.Author.ChannelTitle; // "Blender"
Retrieving videos included in a playlist
To get the videos included in a playlist, call Playlists.GetVideosAsync(...):
using YoutubeExplode;
using YoutubeExplode.Common;
using var youtube = new YoutubeClient();
var playlistUrl = "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6";
// Get all playlist videos
var videos = await youtube.Playlists.GetVideosAsync(playlistUrl);
// Get only the first 20 playlist videos
var videosSubset = await youtube.Playlists.GetVideosAsync(playlistUrl).CollectAsync(20);
You can also enumerate the videos iteratively without waiting for the whole list to load:
using YoutubeExplode;
using var youtube = new YoutubeClient();
var playlistUrl = "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6";
await foreach (var video in youtube.Playlists.GetVideosAsync(playlistUrl))
{
var title = video.Title;
var author = video.Author;
}
If you need precise control over how many requests you send to YouTube, use Playlists.GetVideoBatchesAsync(...) which returns videos wrapped in batches:
using YoutubeExplode;
using var youtube = new YoutubeClient();
var playlistUrl = "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6";
// Each batch corresponds to one request
await foreach (var batch in youtube.Playlists.GetVideoBatchesAsync(playlistUrl))
{
foreach (var video in batch.Items)
{
var title = video.Title;
var author = video.Author;
}
}
[!NOTE] You can craft playlist IDs to fetch special auto-generated playlists, such as music mixes, popular channel uploads, liked videos, and more. See this reference for more information.
Channels
Retrieving channel metadata
You can get the metadata associated with a YouTube channel by calling the `
Related Skills
node-connect
329.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
81.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
329.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
81.1kCommit, push, and open a PR
