From af989c5c4587fd9000287d86d49618014d648e32 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Tue, 14 May 2019 21:48:35 +0300 Subject: [PATCH] ManifestGenerator upate --- FoxTube/Classes/ManifestGenerator.cs | 62 +++++++++++++---------- FoxTube/Controls/Player/PlayerControls.cs | 4 +- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/FoxTube/Classes/ManifestGenerator.cs b/FoxTube/Classes/ManifestGenerator.cs index 6f36f2f..e3a344c 100644 --- a/FoxTube/Classes/ManifestGenerator.cs +++ b/FoxTube/Classes/ManifestGenerator.cs @@ -37,24 +37,22 @@ namespace FoxTube.Controls.Player XmlElement mpd = doc.CreateElement("MPD"); mpd.SetAttribute("mediaPresentationDuration", meta.ContentDetails.Duration); mpd.SetAttribute("minBufferTime", "PT2S"); + mpd.SetAttribute("profiles", "urn:mpeg:dash:profile:isoff-on-demand:2011"); + mpd.SetAttribute("type", "static"); XmlElement period = doc.CreateElement("Period"); - period.SetAttribute("duration", meta.ContentDetails.Duration); - period.SetAttribute("start", "PT0S"); XmlElement videoSet = doc.CreateElement("AdaptationSet"); XmlElement videoMeta = doc.CreateElement("ContentComponent"); videoMeta.SetAttribute("contentType", "video"); + videoMeta.SetAttribute("id", "1"); videoSet.AppendChild(videoMeta); - StreamInfo streamInfo = await GetInfoAsync(meta, requestedQuality, list); + StreamInfo streamInfo = await GetInfoAsync(meta, requestedQuality); XmlElement representation = doc.CreateElement("Representation"); representation.SetAttribute("bandwidth", GetBandwidth(requestedQuality.VideoQuality)); - representation.SetAttribute("height", requestedQuality.Resolution.Height.ToString()); - representation.SetAttribute("width", requestedQuality.Resolution.Width.ToString()); representation.SetAttribute("id", "1"); - representation.SetAttribute("codecs", requestedQuality.VideoEncoding.ToString()); representation.SetAttribute("mimeType", $"video/{requestedQuality.Container.GetFileExtension()}"); XmlElement baseUrl = doc.CreateElement("BaseURL"); @@ -74,6 +72,7 @@ namespace FoxTube.Controls.Player XmlElement audioSet = doc.CreateElement("AdaptationSet"); XmlElement audioMeta = doc.CreateElement("ContentComponent"); audioMeta.SetAttribute("contentType", "audio"); + audioMeta.SetAttribute("id", "2"); audioSet.AppendChild(audioMeta); XmlElement audio = doc.CreateElement("Representation"); @@ -109,36 +108,43 @@ namespace FoxTube.Controls.Player return $"ms-appdata:///roaming/{manifest.Name}".ToUri(); } - private static async Task GetInfoAsync(Video info, VideoStreamInfo requestedQuality, MediaStreamInfoSet list) + private static async Task GetInfoAsync(Video info, VideoStreamInfo requestedQuality) { - HttpClient http = new HttpClient(); - string response = HttpUtility.HtmlDecode(await http.GetStringAsync($"https://youtube.com/embed/{info.Id}?disable_polymer=true&hl=en")); - IHtmlDocument videoEmbedPageHtml = new HtmlParser().Parse(response); + try + { + HttpClient http = new HttpClient(); + string response = HttpUtility.HtmlDecode(await http.GetStringAsync($"https://youtube.com/embed/{info.Id}?disable_polymer=true&hl=en")); + IHtmlDocument videoEmbedPageHtml = new HtmlParser().Parse(response); - string playerConfigRaw = Regex.Match(videoEmbedPageHtml.Source.Text, - @"yt\.setConfig\({'PLAYER_CONFIG': (?\{[^\{\}]*(((?\{)[^\{\}]*)+((?\})[^\{\}]*)+)*(?(Open)(?!))\})") - .Groups["Json"].Value; - JToken playerConfigJson = JToken.Parse(playerConfigRaw); - string sts = playerConfigJson.SelectToken("sts").Value(); + string playerConfigRaw = Regex.Match(videoEmbedPageHtml.Source.Text, + @"yt\.setConfig\({'PLAYER_CONFIG': (?\{[^\{\}]*(((?\{)[^\{\}]*)+((?\})[^\{\}]*)+)*(?(Open)(?!))\})") + .Groups["Json"].Value; + JToken playerConfigJson = JToken.Parse(playerConfigRaw); + string sts = playerConfigJson.SelectToken("sts").Value(); - string eurl = WebUtility.UrlEncode($"https://youtube.googleapis.com/v/{info.Id}"); - string url = $"https://youtube.com/get_video_info?video_id={info.Id}&el=embedded&sts={sts}&eurl={eurl}&hl=en"; - string raw = await http.GetStringAsync(url); + string eurl = WebUtility.UrlEncode($"https://youtube.googleapis.com/v/{info.Id}"); + string url = $"https://youtube.com/get_video_info?video_id={info.Id}&el=embedded&sts={sts}&eurl={eurl}&hl=en"; + string raw = await http.GetStringAsync(url); - Dictionary videoInfoDic = SplitQuery(raw); + Dictionary videoInfoDic = SplitQuery(raw); - StreamInfo si = new StreamInfo(); + StreamInfo si = new StreamInfo(); - List> adaptiveStreamInfosUrl = videoInfoDic.GetValueOrDefault("adaptive_fmts").Split(',').Select(SplitQuery).ToList(); - Dictionary video = adaptiveStreamInfosUrl.Find(i => i["quality_label"] == requestedQuality.VideoQualityLabel && i["type"].Contains(requestedQuality.Container.GetFileExtension())); - Dictionary audio = adaptiveStreamInfosUrl.Find(i => i.ContainsKey("audio_sample_rate") && i["type"].Contains("webm")); + List> adaptiveStreamInfosUrl = videoInfoDic.GetValueOrDefault("adaptive_fmts").Split(',').Select(SplitQuery).ToList(); + Dictionary video = adaptiveStreamInfosUrl.Find(i => i["quality_label"] == requestedQuality.VideoQualityLabel && i["type"].Contains(requestedQuality.Container.GetFileExtension())); + Dictionary audio = adaptiveStreamInfosUrl.Find(i => i.ContainsKey("audio_sample_rate") && i["type"].Contains("webm")); - si.Video.IndexRange = video["index"]; - si.Audio.ChannelsCount = audio["audio_channels"]; - si.Audio.IndexRange = audio["index"]; - si.Audio.SampleRate = audio["audio_sample_rate"]; + si.Video.IndexRange = video["index"]; + si.Audio.ChannelsCount = audio["audio_channels"]; + si.Audio.IndexRange = audio["index"]; + si.Audio.SampleRate = audio["audio_sample_rate"]; - return si; + return si; + } + catch + { + return null; + } } public static Dictionary SplitQuery(string query) diff --git a/FoxTube/Controls/Player/PlayerControls.cs b/FoxTube/Controls/Player/PlayerControls.cs index 16cc593..592e812 100644 --- a/FoxTube/Controls/Player/PlayerControls.cs +++ b/FoxTube/Controls/Player/PlayerControls.cs @@ -442,8 +442,8 @@ namespace FoxTube object tag; if (MediaStreams.Muxed.Any(m => m.VideoQualityLabel == i && m.Resolution.Height <= screenHeight)) tag = MediaStreams.Muxed.Find(m => m.VideoQualityLabel == i); - else if (MediaStreams.Video.Any(m => m.VideoQualityLabel == i && m.Resolution.Height <= screenHeight && m.Container.GetFileExtension() == "webm")) - tag = MediaStreams.Video.Find(m => m.VideoQualityLabel == i && m.Container.GetFileExtension() == "webm"); + else if (MediaStreams.Video.Any(m => m.VideoQualityLabel == i && m.Resolution.Height <= screenHeight && m.Container.GetFileExtension() == "mp4")) + tag = MediaStreams.Video.Find(m => m.VideoQualityLabel == i && m.Container.GetFileExtension() == "mp4"); else continue;