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);
        }