YoutubeExplode 6.2.4

.NET 5.0 .NET Core 3.0 .NET Standard 2.0 .NET Framework 4.6.1
dotnet add package YoutubeExplode --version 6.2.4
NuGet\Install-Package YoutubeExplode -Version 6.2.4
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="YoutubeExplode" Version="6.2.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add YoutubeExplode --version 6.2.4
#r "nuget: YoutubeExplode, 6.2.4"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install YoutubeExplode as a Cake Addin
#addin nuget:?package=YoutubeExplode&version=6.2.4

// Install YoutubeExplode as a Cake Tool
#tool nuget:?package=YoutubeExplode&version=6.2.4

YoutubeExplode

Made in Ukraine Build Coverage Version Downloads Discord Donate Fuck Russia

🟑 Project status: maintenance mode<sup>[?]</sup>

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, the library parses raw page content and uses reverse-engineered requests to retrieve information. As it doesn't rely on the official API, there's also no need for an API key and there are no usage quotas.

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

demo

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 both video ID or URL
var video = await youtube.Videos.GetAsync("https://youtube.com/watch?v=u_yIGGhubZs");

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, bit rate, frame rate, and other properties. Additionally, depending on the content of the stream, the streams are further divided into 3 categories:

  • Muxed streams β€” contain both video and audio
  • Audio-only streams β€” contain only audio
  • Video-only streams β€” contain only video

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 streamManifest = await youtube.Videos.Streams.GetManifestAsync(
    "https://youtube.com/watch?v=u_yIGGhubZs"
);

Once you get the manifest, you can filter through the streams and select 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}");

Warning: Muxed streams contain both audio and video, but these streams are very limited in quality (up to 720p30). To download video in the highest available quality, you need to resolve the best audio-only and video-only streams separately and then mux them together. This can be accomplished by using the YoutubeExplode.Converter package.

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 trackManifest = await youtube.Videos.ClosedCaptions.GetManifestAsync(
    "https://youtube.com/watch?v=u_yIGGhubZs"
);

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 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 playlist = await youtube.Playlists.GetAsync(
    "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6"
);

var title = playlist.Title; // "First Steps - Blender 2.80 Fundamentals"
var author = playlist.Author.ChannelTitle; // "Blender"
Getting 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();

// Get all playlist videos
var videos = await youtube.Playlists.GetVideosAsync(
    "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6"
);

// Get only the first 20 playlist videos
var videosSubset = await youtube.Playlists
    .GetVideosAsync(playlist.Id)
    .CollectAsync(20);

You can also enumerate the videos iteratively without waiting for the whole list to load:

using YoutubeExplode;

var youtube = new YoutubeClient();

await foreach (var video in youtube.Playlists.GetVideosAsync(
    "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6"
))
{
    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();

// Each batch corresponds to one request
await foreach (var batch in youtube.Playlists.GetVideoBatchesAsync(
    "https://youtube.com/playlist?list=PLa1F2ddGya_-UvuAqHAksYnB0qL9yWDO6"
))
{
    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 channel = await youtube.Channels.GetAsync(
    "https://youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg"
);

var title = channel.Title; // "Blender"

You can also get the channel metadata by username with Channels.GetByUserAsync(...):

using YoutubeExplode;

var youtube = new YoutubeClient();

var channel = await youtube.Channels.GetByUserAsync("https://youtube.com/user/BlenderFoundation");

var id = channel.Id; // "UCSMOQeBJ2RAnuFungnQOxLg"

To get the channel metadata by slug or custom URL, use Channels.GetBySlugAsync(...):

using YoutubeExplode;

var youtube = new YoutubeClient();

var channel = await youtube.Channels.GetBySlugAsync("https://youtube.com/c/BlenderFoundation");

var id = channel.Id; // "UCSMOQeBJ2RAnuFungnQOxLg"

To get the channel metadata by handle or handle URL, use Channels.GetByHandleAsync(...):

using YoutubeExplode;

var youtube = new YoutubeClient();

var channel = await youtube.Channels.GetByHandleAsync("https://www.youtube.com/@BeauMiles");

var id = channel.Id; // "UCm325cMiw9B15xl22_gr6Dw"
Getting channel uploads

To get a list of videos uploaded by a channel, call Channels.GetUploadsAsync(...):

using YoutubeExplode;
using YoutubeExplode.Common;

var youtube = new YoutubeClient();

var videos = await youtube.Channels.GetUploadsAsync(
    "https://youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg"
);

Searching

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.

  • 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
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (11)

Showing the top 5 NuGet packages that depend on YoutubeExplode:

Package Downloads
YoutubeExplode.Converter

Extension for YoutubeExplode that provides an interface to download and convert videos using FFmpeg

N3O.Umbraco.Video.YouTube

TODO

SpiderSharp

Web Crawling and Scraping Framework

Tesses.YouTubeDownloader

A YouTube Downloader

ExtendedYouTubeAPI

Library which is used to extend the abilities of YouTube API v3 Features - DASH manifests generation for videos - HLS livestreams URLs extraction - User's history management (list, add, delete, update) - Watch later playlist management (list, add, delete) - Video captions retrieval - User's recommendations listing - User's subscriptions videos listing - Videos' URLs retrieval - UWP authorization helpers

GitHub repositories (6)

Showing the top 5 popular GitHub repositories that depend on YoutubeExplode:

Repository Stars
Tyrrrz/YoutubeDownloader
Downloads videos and playlists from YouTube
LagradOst/CloudStream-2
CloudStream 2 is an android streaming app for movies, tv-shows and anime
shaked6540/YoutubePlaylistDownloader
A tool to download whole playlists, channels or single videos from youtube and also optionally convert them to almost any format you would like
i3arnon/YouCast
Turn YouTube Channels into Subscribable Podcasts.
not-ilinked/Anarchy
The superior Discord API wrapper
Version Downloads Last updated
6.2.4 2,010 11/5/2022
6.2.3 154 11/5/2022
6.2.2 5,315 9/16/2022
6.2.1 24,070 8/8/2022
6.2.0 91,830 6/29/2022
6.1.2 179,325 4/16/2022
6.1.1 3,793 4/15/2022
6.1.0 113,686 2/19/2022
6.0.8 14,443 2/10/2022
6.0.7 125,512 12/10/2021
6.0.6 4,187 12/9/2021
6.0.5 18,743 7/28/2021
6.0.4 1,952 7/2/2021
6.0.3 1,369 6/21/2021
6.0.2 6,666 5/28/2021
6.0.1 1,871 5/21/2021
6.0.0 342,493 4/17/2021
6.0.0-alpha2 291,489 4/1/2021
6.0.0-alpha 967 2/25/2021
5.1.9 23,658 11/28/2020
5.1.8 11,548 10/25/2020
5.1.7 1,654 10/12/2020
5.1.6 2,039 9/29/2020
5.1.5 2,244 9/12/2020
5.1.4 3,006 8/14/2020
5.1.3 2,074 7/29/2020
5.1.2 1,366 7/21/2020
5.1.1 5,168 6/21/2020
5.1.0 1,500 6/14/2020
5.0.5 1,823 5/23/2020
5.0.4 1,573 5/10/2020
5.0.3 1,129 5/1/2020
5.0.2 892 4/24/2020
5.0.1 1,612 4/13/2020
5.0.0 832 4/12/2020
4.7.16 6,985 3/16/2020
4.7.15 1,556 3/11/2020
4.7.14 645 3/10/2020
4.7.13 2,741 2/10/2020
4.7.12 6,532 12/29/2019
4.7.11 1,703 12/15/2019
4.7.10 6,766 9/24/2019
4.7.9 11,804 8/15/2019
4.7.8 955 8/8/2019
4.7.7 1,311 7/30/2019
4.7.6 2,147 7/10/2019
4.7.5 803 7/4/2019
4.7.4 925 6/24/2019
4.7.3 818 6/21/2019
4.7.2 950 6/13/2019
4.7.1 1,645 5/16/2019
4.7.0 1,237 5/12/2019
4.7.0-beta2 556 5/6/2019
4.7.0-beta 657 4/25/2019
4.7.0-alpha 625 4/21/2019
4.6.8 1,880 3/30/2019
4.6.7 1,039 3/16/2019
4.6.6 1,624 2/24/2019
4.6.5 942 2/16/2019
4.6.4 2,187 1/16/2019
4.6.3 847 1/13/2019
4.6.2 1,361 1/4/2019
4.6.1 1,653 12/3/2018
4.6.0 1,082 11/22/2018
4.5.3 14,851 11/7/2018
4.5.2 982 11/2/2018
4.5.1 1,426 10/24/2018
4.5.0 868 10/20/2018
4.4.0 716 10/20/2018
4.3.4 893 10/16/2018
4.3.3 1,353 9/26/2018
4.3.2 1,316 9/10/2018
4.3.1 1,036 8/28/2018
4.3.0 14,724 7/25/2018
4.2.8 5,013 6/14/2018
4.2.7 1,073 6/9/2018
4.2.6 936 6/9/2018
4.2.5 1,299 5/20/2018
4.2.4 1,222 5/2/2018
4.2.3 1,111 4/22/2018
4.2.2 1,418 3/31/2018
4.2.1 994 3/28/2018
4.2.0 1,109 3/24/2018
4.1.1 1,521 2/20/2018
4.1.0 5,511 2/2/2018
4.1.0-alpha4 762 1/29/2018
4.1.0-alpha3 653 1/28/2018
4.1.0-alpha2 974 12/24/2017
4.1.0-alpha 863 12/16/2017
4.0.0 2,059 12/15/2017
4.0.0-alpha 876 12/10/2017
3.4.0-workaround404 855 11/28/2017
3.3.0 2,796 10/19/2017
3.2.5 1,383 8/29/2017
3.2.4 1,012 8/28/2017
3.2.3 1,301 8/11/2017
3.2.2 1,002 8/8/2017
3.2.1 977 8/5/2017
3.2.0 1,353 7/4/2017
3.1.1 1,314 6/8/2017
3.1.0 1,113 6/1/2017
3.0.2 1,070 5/12/2017
3.0.1 944 5/8/2017
3.0.0 937 4/24/2017
2.5.0 1,027 3/26/2017
2.4.0 882 3/24/2017
2.3.0 934 3/10/2017
2.2.2 888 3/8/2017
2.2.1 873 3/7/2017
2.2.0 875 3/6/2017
2.1.3 916 3/5/2017
2.1.2 864 3/3/2017
2.1.1 847 3/3/2017
2.1.0 869 3/2/2017
2.0.1 868 3/2/2017
2.0.0 877 3/2/2017
1.1.0 993 2/24/2017
1.0.4 895 2/19/2017
1.0.3 895 2/2/2017
1.0.2 902 1/28/2017
1.0.1 892 1/26/2017
1.0.0 904 1/25/2017