diff --git a/YoutubeExplode.Tests/Data.cs b/YoutubeExplode.Tests/Data.cs index b1ac5a96..249036a4 100644 --- a/YoutubeExplode.Tests/Data.cs +++ b/YoutubeExplode.Tests/Data.cs @@ -11,7 +11,8 @@ public static IEnumerable GetVideoIds() yield return new TestCaseData("9bZkp7q19f0"); // very popular yield return new TestCaseData("SkRSXFQerZs"); // age restricted (embed allowed) yield return new TestCaseData("hySoCSoH-g8"); // age restricted (embed not allowed) - yield return new TestCaseData("_kmeFXjjGfk"); // embed not allowed + yield return new TestCaseData("_kmeFXjjGfk"); // embed not allowed (type 1) + yield return new TestCaseData("MeJVWBSsPAY"); // embed not allowed (type 2) yield return new TestCaseData("5VGm0dczmHc"); // rating not allowed yield return new TestCaseData("ZGdLIwrGHG8"); // unlisted yield return new TestCaseData("H1O_-JVbl_k"); // very large video diff --git a/YoutubeExplode/YoutubeClient.Video.cs b/YoutubeExplode/YoutubeClient.Video.cs index bd86670f..e37dd419 100644 --- a/YoutubeExplode/YoutubeClient.Video.cs +++ b/YoutubeExplode/YoutubeClient.Video.cs @@ -51,26 +51,36 @@ private async Task GetVideoWatchPageAsync(string videoId) private async Task GetVideoInfoRawAsync(string videoId, string el = "", string sts = "") { - var eurl = $"https://youtube.googleapis.com/v/{videoId}".UrlEncode(); // this makes all videos embeddable + // This parameter does magic and a lot of videos don't work without it + var eurl = $"https://youtube.googleapis.com/v/{videoId}".UrlEncode(); + var url = $"https://www.youtube.com/get_video_info?video_id={videoId}&el={el}&sts={sts}&eurl={eurl}&hl=en"; return await _httpClient.GetStringAsync(url).ConfigureAwait(false); } private async Task> GetVideoInfoAsync(string videoId, string sts = "") { + // Get video info with 'el=embedded' var raw = await GetVideoInfoRawAsync(videoId, "embedded", sts).ConfigureAwait(false); var videoInfo = UrlEx.SplitQuery(raw); - // Check if there is an error - if (videoInfo.ContainsKey("errorcode")) - { - var errorCode = videoInfo["errorcode"].ParseInt(); - var errorReason = videoInfo["reason"]; + // If there is no error - return + if (!videoInfo.ContainsKey("errorcode")) + return videoInfo; - throw new VideoUnavailableException(videoId, errorCode, errorReason); - } + // Get video info with 'el=detailpage' + raw = await GetVideoInfoRawAsync(videoId, "detailpage", sts).ConfigureAwait(false); + videoInfo = UrlEx.SplitQuery(raw); + + // If there is no error - return + if (!videoInfo.ContainsKey("errorcode")) + return videoInfo; + + // If there is error - throw + var errorCode = videoInfo["errorcode"].ParseInt(); + var errorReason = videoInfo["reason"]; - return videoInfo; + throw new VideoUnavailableException(videoId, errorCode, errorReason); } private async Task GetVideoPlayerContextAsync(string videoId)