Etherna.YoutubeDownloader
6.2.11
See the version list below for details.
dotnet add package Etherna.YoutubeDownloader --version 6.2.11
NuGet\Install-Package Etherna.YoutubeDownloader -Version 6.2.11
<PackageReference Include="Etherna.YoutubeDownloader" Version="6.2.11" />
paket add Etherna.YoutubeDownloader --version 6.2.11
#r "nuget: Etherna.YoutubeDownloader, 6.2.11"
// Install Etherna.YoutubeDownloader as a Cake Addin #addin nuget:?package=Etherna.YoutubeDownloader&version=6.2.11 // Install Etherna.YoutubeDownloader as a Cake Tool #tool nuget:?package=Etherna.YoutubeDownloader&version=6.2.11
YoutubeExplode
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.
📝 Want to learn more about how YouTube works under the hood? See Reverse-Engineering YouTube: Revisited.
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;
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
- 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.
You can request the manifest that lists all available streams for a particular video by calling Videos.Streams.GetManifestAsync(...)
:
using YoutubeExplode;
var youtube = new YoutubeClient();
var videoUrl = "https://youtube.com/watch?v=u_yIGGhubZs";
var streamManifest = await youtube.Videos.Streams.GetManifestAsync(videoUrl);
Once you get the manifest, you can filter through the streams and identify the ones you're interested in:
using YoutubeExplode;
using YoutubeExplode.Videos.Streams;
// ...
// Get highest quality muxed stream
var streamInfo = streamManifest.GetMuxedStreams().GetWithHighestVideoQuality();
// ...or highest bitrate audio-only stream
var streamInfo = streamManifest.GetAudioOnlyStreams().GetWithHighestBitrate();
// ...or 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}");
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;
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 Playlists.GetAsync(...)
method:
using YoutubeExplode;
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;
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;
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;
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;
}
}
Channels
Retrieving channel metadata
You can get the metadata associated with a YouTube channel by calling Channels.GetAsync(...)
method:
using YoutubeExplode;
var youtube = new YoutubeClient();
var channelUrl = "https://youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg";
var channel = await youtube.Channels.GetAsync(channelUrl);
var title = channel.Title; // "Blender"
You can also get the channel metadata by username with Channels.GetByUserAsync(...)
:
using YoutubeExplode;
var youtube = new YoutubeClient();
var channelUrl = "https://youtube.com/user/BlenderFoundation";
var channel = await youtube.Channels.GetByUserAsync(channelUrl);
var id = channel.Id; // "UCSMOQeBJ2RAnuFungnQOxLg"
To get the channel metadata by slug or legacy custom URL, use Channels.GetBySlugAsync(...)
:
using YoutubeExplode;
var youtube = new YoutubeClient();
var channelUrl = "https://youtube.com/c/BlenderFoundation";
var channel = await youtube.Channels.GetBySlugAsync(channelUrl);
var id = channel.Id; // "UCSMOQeBJ2RAnuFungnQOxLg"
To get the channel metadata by handle or custom URL, use Channels.GetByHandleAsync(...)
:
using YoutubeExplode;
var youtube = new YoutubeClient();
var channelUrl = "https://youtube.com/@BeauMiles";
var channel = await youtube.Channels.GetByHandleAsync(channelUrl);
var id = channel.Id; // "UCm325cMiw9B15xl22_gr6Dw"
Retrieving channel uploads
To get the list of videos uploaded by a channel, call Channels.GetUploadsAsync(...)
:
using YoutubeExplode;
using YoutubeExplode.Common;
var youtube = new YoutubeClient();
var channelUrl = "https://youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg";
var videos = await youtube.Channels.GetUploadsAsync(channelUrl);
Search
You can execute a search query and get its results by calling Search.GetResultsAsync(...)
.
Each result may represent either a video, a playlist, or a channel, so you need to apply pattern matching to handle the corresponding cases:
using YoutubeExplode;
var youtube = new YoutubeClient();
await foreach (var result in youtube.Search.GetResultsAsync("blender tutorials"))
{
// Use pattern matching to handle different results (videos, playlists, channels)
switch (result)
{
case VideoSearchResult video:
{
var id = video.Id;
var title = video.Title;
var duration = video.Duration;
break;
}
case PlaylistSearchResult playlist:
{
var id = playlist.Id;
var title = playlist.Title;
break;
}
case ChannelSearchResult channel:
{
var id = channel.Id;
var title = channel.Title;
break;
}
}
}
To limit results to a specific type, use Search.GetVideosAsync(...)
, Search.GetPlaylistsAsync(...)
, or Search.GetChannelsAsync(...)
:
using YoutubeExplode;
using YoutubeExplode.Common;
var youtube = new YoutubeClient();
var videos = await youtube.Search.GetVideosAsync("blender tutorials");
var playlists = await youtube.Search.GetPlaylistsAsync("blender tutorials");
var channels = await youtube.Search.GetChannelsAsync("blender tutorials");
Similarly to playlists, you can also enumerate results in batches by calling Search.GetResultBatchesAsync(...)
:
using YoutubeExplode;
var youtube = new YoutubeClient();
// Each batch corresponds to one request
await foreach (var batch in youtube.Search.GetResultBatchesAsync("blender tutorials"))
{
foreach (var result in batch.Items)
{
switch (result)
{
case VideoSearchResult videoResult:
{
// ...
}
case PlaylistSearchResult playlistResult:
{
// ...
}
case ChannelSearchResult channelResult:
{
// ...
}
}
}
}
Etymology
The "Explode" in YoutubeExplode comes from the name of a PHP function that splits up strings, explode(...)
. When I was starting the development of this library, most of the reference source code I read was written in PHP, hence the inspiration for the name.
Related projects
- YoutubeExplode.Converter — provides capabilities for downloading YouTube videos with conversion to other formats, using FFmpeg.
- YoutubeDownloader — desktop application for downloading YouTube videos, based on YoutubeExplode.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 is compatible. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.1
- AngleSharp (>= 1.0.1)
-
.NETFramework 4.6.1
- AngleSharp (>= 1.0.1)
- Microsoft.Bcl.AsyncInterfaces (>= 7.0.0)
- System.Text.Json (>= 7.0.2)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
.NETStandard 2.0
- AngleSharp (>= 1.0.1)
- Microsoft.Bcl.AsyncInterfaces (>= 7.0.0)
- System.Text.Json (>= 7.0.2)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
.NETStandard 2.1
- AngleSharp (>= 1.0.1)
- System.Text.Json (>= 7.0.2)
-
net5.0
- AngleSharp (>= 1.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Etherna.YoutubeDownloader:
Package | Downloads |
---|---|
Etherna.YoutubeDownloader.Converter
Extension for YoutubeExplode that provides an interface to download and convert videos using FFmpeg |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
6.4.7 | 100 | 11/20/2024 |
6.4.5 | 187 | 10/8/2024 |
6.4.4 | 160 | 9/27/2024 |
6.4.3 | 134 | 9/19/2024 |
6.4.1 | 92 | 8/5/2024 |
6.3.10 | 267 | 3/23/2024 |
6.3.9 | 318 | 11/10/2023 |
6.3.8 | 241 | 8/29/2023 |
6.3.6 | 176 | 8/29/2023 |
6.3.5 | 251 | 7/3/2023 |
6.3.4 | 243 | 5/28/2023 |
6.3.3 | 248 | 5/6/2023 |
6.2.14 | 216 | 5/3/2023 |
6.2.12 | 283 | 3/31/2023 |
6.2.11 | 316 | 3/20/2023 |