string populateUrlsFromXml(VideoInfo video, XmlDocument streamPlaylist, bool live) { if (streamPlaylist == null) { Log.Warn("ITVPlayer: Stream playlist is null"); return(""); } XmlNode videoEntry = streamPlaylist.SelectSingleNode("//VideoEntries/Video"); if (videoEntry == null) { Log.Warn("ITVPlayer: Could not find video entry"); return(""); } XmlNode node; node = videoEntry.SelectSingleNode("./MediaFiles"); if (node == null || node.Attributes["base"] == null) { Log.Warn("ITVPlayer: Could not find base url"); return(""); } string rtmpUrl = node.Attributes["base"].Value; SortedList <string, string> options = new SortedList <string, string>(new StreamComparer()); foreach (XmlNode mediaFile in node.SelectNodes("./MediaFile")) { if (mediaFile.Attributes["delivery"] == null || mediaFile.Attributes["delivery"].Value != "Streaming") { continue; } string title = ""; if (mediaFile.Attributes["bitrate"] != null) { title = mediaFile.Attributes["bitrate"].Value; int bitrate; if (int.TryParse(title, out bitrate)) { title = string.Format("{0} kbps", bitrate / 1000); } } if (!options.ContainsKey(title)) { string url = new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = mediaFile.InnerText, SwfUrl = "http://mediaplayer.itv.com/2.18.5%2Bbuild.ad408a9c67/ITVMediaPlayer.swf", SwfVerify = true, Live = live }.ToString(); options.Add(title, url); } } if (RetrieveSubtitles) { node = videoEntry.SelectSingleNode("./ClosedCaptioningURIs"); if (node != null && Helpers.UriUtils.IsValidUri(node.InnerText)) { video.SubtitleText = SubtitleReader.TimedText2SRT(GetWebData(node.InnerText)); } } video.PlaybackOptions = new Dictionary <string, string>(); if (options.Count == 0) { return(null); } if (AutoSelectStream) { var last = options.Last(); video.PlaybackOptions.Add(last.Key, last.Value); } else { foreach (KeyValuePair <string, string> key in options) { video.PlaybackOptions.Add(key.Key, key.Value); } } return(options.Last().Value); }
public override string GetVideoUrl(VideoInfo video) { Log.Debug(@"video: {0}", video.Title); string result = string.Empty; video.PlaybackOptions = new Dictionary <string, string>(); // keep track of bitrates and URLs Dictionary <int, string> urlsDictionary = new Dictionary <int, string>(); string pid = string.Empty; // must find pid before proceeding if (video.VideoUrl.Contains(@"pid=")) { pid = HttpUtility.ParseQueryString(new Uri(video.VideoUrl).Query)["pid"]; } else { string data = GetWebData(video.VideoUrl); Match pidMatch = pidRegex.Match(data); if (pidMatch.Success) { pid = pidMatch.Groups["pid"].Value; } } if (!string.IsNullOrEmpty(pid)) { XmlDocument xml = GetWebData <XmlDocument>(string.Format(thePlatformUrlFormat, pid)); Log.Debug(@"SMIL loaded from {0}", string.Format(thePlatformUrlFormat, pid)); XmlNamespaceManager nsmRequest = new XmlNamespaceManager(xml.NameTable); nsmRequest.AddNamespace("a", @"http://www.w3.org/2005/SMIL21/Language"); XmlNode metaBase = xml.SelectSingleNode(@"//a:meta", nsmRequest); // base URL may be stored in the base attribute of <meta> tag string url = metaBase != null ? metaBase.Attributes["base"].Value : string.Empty; foreach (XmlNode node in xml.SelectNodes("//a:body/a:switch/a:video", nsmRequest)) { int bitrate = int.Parse(node.Attributes["system-bitrate"].Value); // do not bother unless bitrate is non-zero if (bitrate == 0) { continue; } if (url.StartsWith("rtmp") && !urlsDictionary.ContainsKey(bitrate / 1000)) { string playPath = node.Attributes["src"].Value; if (playPath.EndsWith(@".mp4") && !playPath.StartsWith(@"mp4:")) { // prepend with mp4: playPath = @"mp4:" + playPath; } else if (playPath.EndsWith(@".flv")) { // strip extension playPath = playPath.Replace(@".flv", string.Empty); } Log.Debug(@"bitrate: {0}, url: {1}, PlayPath: {2}", bitrate / 1000, url, playPath); urlsDictionary.Add(bitrate / 1000, new MPUrlSourceFilter.RtmpUrl(url) { PlayPath = playPath }.ToString()); } } // closed captions string subtitleText = string.Empty; if (retrieveSubtitles) { XmlNode ccUrl = xml.SelectSingleNode("//a:body/a:switch/a:ref/a:param[@name='ClosedCaptionURL']", nsmRequest); if (ccUrl != null) { subtitleText = SubtitleReader.TimedText2SRT(GetWebData(ccUrl.Attributes["value"].Value)); } } // sort the URLs ascending by bitrate foreach (var item in urlsDictionary.OrderBy(u => u.Key)) { video.PlaybackOptions.Add(string.Format("{0} kbps", item.Key), item.Value); if (!string.IsNullOrEmpty(subtitleText)) { video.SubtitleText = subtitleText; } // return last URL as the default (will be the highest bitrate) result = item.Value; } // if result is still empty then perhaps we are geo-locked if (string.IsNullOrEmpty(result)) { XmlNode geolockReference = xml.SelectSingleNode(@"//a:seq/a:ref", nsmRequest); if (geolockReference != null) { string message = geolockReference.Attributes["abstract"] != null ? geolockReference.Attributes["abstract"].Value : @"This content is not available in your location."; Log.Error(message); throw new OnlineVideosException(message, true); } } } return(result); }