public static Dictionary<string, string> GetYouTubePlaybackOptions(EpisodeInfo info) { if (!HosterFactory.ContainsName("youtube")) { Log.Warn("youtube hoster was not found"); return null; } if (info == null || string.IsNullOrEmpty(info.SeriesTitle) || string.IsNullOrEmpty(info.SeriesNumber) || (string.IsNullOrEmpty(info.EpisodeNumber) && string.IsNullOrEmpty(info.AirDate)) ) { Log.Warn("Not enough info to locate video"); return null; } string youtubeTitle = Regex.Replace(info.SeriesTitle, "[^A-z0-9]", "").ToLower(); Log.Debug("Searching for youtube video: Show: {0}, Season: {1}, {2}", youtubeTitle, info.SeriesNumber, string.IsNullOrEmpty(info.AirDate) ? "Episode: " + info.EpisodeNumber : "Air Date: " + info.AirDate); string html = WebCache.Instance.GetWebData("http://www.youtube.com/show/" + youtubeTitle); //look for season string seriesReg = string.Format(@"<a class=""yt-uix-tile-link"" href=""([^""]*)"">[\s\n]*Season {0} Episodes", info.SeriesNumber); Match m = Regex.Match(html, seriesReg); if (m.Success) { //found specified season string playlist = WebCache.Instance.GetWebData("http://www.youtube.com" + m.Groups[1].Value); string episodeReg; //look for specified episode if (string.IsNullOrEmpty(info.EpisodeNumber)) { episodeReg = string.Format(@"<a href=""(/watch[^""]*)"".*?>[\s\n]*<span.*?>.*?{0}", info.AirDate); m = Regex.Match(playlist, episodeReg); if (m.Success) return HosterFactory.GetHoster("youtube").GetPlaybackOptions("http://youtube.com" + m.Groups[1].Value); return null; } episodeReg = string.Format(@"<span class=""video-index"">{0}</span>.*?<a href=""(/watch[^""]*)""", info.EpisodeNumber); m = Regex.Match(playlist, episodeReg, RegexOptions.Singleline); if (m.Success) { if (verifyYoutubePage(m.Groups[1].Value, info.SeriesNumber, info.EpisodeNumber)) return HosterFactory.GetHoster("youtube").GetPlaybackOptions("http://youtube.com" + m.Groups[1].Value); return null; } //didn't find specified episode directly, loop through all videos and see if we get a match foreach (Match ep in Regex.Matches(playlist, @"<a href=""(/watch[^""]*)""")) { if (verifyYoutubePage(ep.Groups[1].Value, info.SeriesNumber, info.EpisodeNumber)) return HosterFactory.GetHoster("youtube").GetPlaybackOptions("http://youtube.com" + ep.Groups[1].Value); } } Log.Warn("Unable to locate 4od video on youtube"); return null; }
public static Dictionary <string, string> GetYouTubePlaybackOptions(EpisodeInfo info) { if (!HosterFactory.ContainsName("youtube")) { Log.Warn("youtube hoster was not found"); return(null); } if (info == null || string.IsNullOrEmpty(info.SeriesTitle) || string.IsNullOrEmpty(info.SeriesNumber) || (string.IsNullOrEmpty(info.EpisodeNumber) && string.IsNullOrEmpty(info.AirDate)) ) { Log.Warn("Not enough info to locate video"); return(null); } string youtubeTitle = Regex.Replace(info.SeriesTitle, "[^A-z0-9]", "").ToLower(); Log.Debug("Searching for youtube video: Show: {0}, Season: {1}, {2}", youtubeTitle, info.SeriesNumber, string.IsNullOrEmpty(info.AirDate) ? "Episode: " + info.EpisodeNumber : "Air Date: " + info.AirDate); string html = WebCache.Instance.GetWebData("http://www.youtube.com/show/" + youtubeTitle); //look for season string seriesReg = string.Format(@"<a class=""yt-uix-tile-link"" href=""([^""]*)"">[\s\n]*Season {0} Episodes", info.SeriesNumber); Match m = Regex.Match(html, seriesReg); if (m.Success) { //found specified season string playlist = WebCache.Instance.GetWebData("http://www.youtube.com" + m.Groups[1].Value); string episodeReg; //look for specified episode if (string.IsNullOrEmpty(info.EpisodeNumber)) { episodeReg = string.Format(@"<a href=""(/watch[^""]*)"".*?>[\s\n]*<span.*?>.*?{0}", info.AirDate); m = Regex.Match(playlist, episodeReg); if (m.Success) { return(HosterFactory.GetHoster("youtube").GetPlaybackOptions("http://youtube.com" + m.Groups[1].Value)); } return(null); } episodeReg = string.Format(@"<span class=""video-index"">{0}</span>.*?<a href=""(/watch[^""]*)""", info.EpisodeNumber); m = Regex.Match(playlist, episodeReg, RegexOptions.Singleline); if (m.Success) { if (verifyYoutubePage(m.Groups[1].Value, info.SeriesNumber, info.EpisodeNumber)) { return(HosterFactory.GetHoster("youtube").GetPlaybackOptions("http://youtube.com" + m.Groups[1].Value)); } return(null); } //didn't find specified episode directly, loop through all videos and see if we get a match foreach (Match ep in Regex.Matches(playlist, @"<a href=""(/watch[^""]*)""")) { if (verifyYoutubePage(ep.Groups[1].Value, info.SeriesNumber, info.EpisodeNumber)) { return(HosterFactory.GetHoster("youtube").GetPlaybackOptions("http://youtube.com" + ep.Groups[1].Value)); } } } Log.Warn("Unable to locate 4od video on youtube"); return(null); }
public override string GetVideoUrl(VideoInfo video) { string webdata = GetWebData(video.VideoUrl); //Match m = new Regex(@"playerID=(\d+).*?videoPlayer=ref:(C\d+)").Match(webdata); EpisodeInfo info = new EpisodeInfo(); Match m; if ((m = Regex.Match(webdata, @"<div class=""secondary_nav_header"".*?>.*?<h\d><span.*?>(.*?)<", RegexOptions.Singleline)).Success) info.SeriesTitle = m.Groups[1].Value; if ((m = Regex.Match(webdata, @"<h3 class=""episode_header""><span.*?>(.*?)<")).Success) { string result = m.Groups[1].Value; if ((m = Regex.Match(result, @"Series (\d+)")).Success) info.SeriesNumber = m.Groups[1].Value; if ((m = Regex.Match(result, @"Episode (\d+)")).Success) info.EpisodeNumber = m.Groups[1].Value; } if ((m = Regex.Match(webdata, @"<p>First broadcast at (.*?)</p>")).Success) { DateTime airDate; if (DateTime.TryParse(m.Groups[1].Value, out airDate)) { info.AirDate = airDate.ToString("d MMMM"); if (string.IsNullOrEmpty(info.SeriesNumber)) info.SeriesNumber = airDate.Year.ToString(); } } video.Other = info; m = new Regex(@"videoPlayer=ref:(C\d+)").Match(webdata); if (!m.Success) return String.Empty; AMFObject viewerExperience = getViewerExperience(m.Groups[1].Value, video.VideoUrl); AMFObject mediaDTO = viewerExperience.GetArray("programmedContent").GetObject("videoPlayer").GetObject("mediaDTO"); if (!string.IsNullOrEmpty(mediaDTO.GetStringProperty("drmMetadataURL"))) { video.PlaybackOptions = YouTubeShowHandler.GetYouTubePlaybackOptions(video.Other as EpisodeInfo); if (video.PlaybackOptions != null && video.PlaybackOptions.Count > 0) return video.PlaybackOptions.Last().Value; return null; } AMFArray renditions = mediaDTO.GetArray("renditions"); return FillPlaybackOptions(video, renditions); }