/// <summary> /// Obtiene la Url de un vídeo de YouTube /// </summary> public async Task <string> GetUriYouTubeVideoAsync(string videoCode) { try { Tools.YouTubeUri uri = (await new Tools.YouTube().GetVideoUriAsync(videoCode, Tools.YouTubeUri.YouTubeQuality.QualityMedium)); if (uri != null) { return(uri.Uri.ToString()); } else { return(null); } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message); return(null); } }
/// <summary>Returns all available URIs (audio-only and video) for the given YouTube ID. </summary> public async Task <YouTubeUri[]> GetUrisAsync(string youTubeId, CancellationToken token) { YouTubeDecipherer decipherer = new YouTubeDecipherer(); var urls = new List <YouTubeUri>(); string javaScriptCode = null; var response = await HttpGetAsync($"https://www.youtube.com/watch?v={youTubeId}&nomobile=1", token); var match = Regex.Match(response, "url_encoded_fmt_stream_map\": ?\"(.*?)\""); var data = Uri.UnescapeDataString(match.Groups [1].Value); match = Regex.Match(response, "adaptive_fmts\": ?\"(.*?)\""); var data2 = Uri.UnescapeDataString(match.Groups [1].Value); var arr = Regex.Split($"{data},{data2}", ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); // split by comma but outside quotes foreach (var d in arr) { string url = ""; string signature = ""; YouTubeUri tuple = new YouTubeUri(); foreach (var p in d.Replace("\\u0026", "\t").Split('\t')) { int index = p.IndexOf('='); if (index != -1 && index < p.Length) { try { string key = p.Substring(0, index); string value = Uri.UnescapeDataString(p.Substring(index + 1)); if (key == "url") { url = value; } else if (key == "itag") { tuple.Itag = int.Parse(value); } else if (key == "type" && (value.Contains("video/mp4") || value.Contains("audio/mp4"))) { tuple.Type = value; } else if (key == "sig") { signature = value; } else if (key == "s") { if (javaScriptCode == null) { string javaScriptUri; Match urlMatch = Regex.Match(response, "\"\\\\/\\\\/s.ytimg.com\\\\/yts\\\\/jsbin\\\\/html5player-(.+?)\\.js\""); if (urlMatch.Success) { javaScriptUri = $"http://s.ytimg.com/yts/jsbin/html5player-{urlMatch.Groups[1]}.js"; } else { // new format javaScriptUri = "https://s.ytimg.com/yts/jsbin/player-" + Regex.Match(response, "\"\\\\/\\\\/s.ytimg.com\\\\/yts\\\\/jsbin\\\\/player-(.+?)\\.js\"").Groups[1] + ".js"; } javaScriptCode = await HttpGetAsync(javaScriptUri, token); } signature = decipherer.Decipher(value, javaScriptCode); } } catch (Exception exception) { throw new YouTubeUriException($"YouTube parse exception: {exception.Message}"); } } } if (!string.IsNullOrEmpty(url)) { if (url.Contains("&signature=") || url.Contains("?signature=")) { tuple.Uri = new Uri(url, UriKind.Absolute); } else { tuple.Uri = new Uri(url + "&signature=" + signature, UriKind.Absolute); } if (tuple.IsValid) { urls.Add(tuple); } } } return(urls.ToArray()); }