Tuple<Dictionary<string, string>, string> getPlaybackOptions(string videoUrl, SouthParkCountry spc) { Dictionary<string, string> res = new Dictionary<string, string>(); string data = GetWebData(videoUrl); XmlDocument doc = new XmlDocument(); doc.LoadXml(data); XmlNodeList list = doc.SelectNodes("//src"); for (int i = 0; i < list.Count; i++) { string bitrate = list[i].ParentNode.Attributes["bitrate"].Value; string videoType = list[i].ParentNode.Attributes["type"].Value.Replace(@"video/", String.Empty); string url = list[i].InnerText; string swfUrl = null; if (spc == SouthParkCountry.World) url = url.Replace(@"viacomspstrmfs.fplive.net/viacomspstrm", @"cp10740.edgefcs.net/ondemand/mtvnorigin"); /*switch (spc) { case SouthParkCountry.World: case SouthParkCountry.De: swfUrl = @"http://media.mtvnservices.com/player/prime/mediaplayerprime.1.11.3.swf"; break; }*/ string br = bitrate + "K " + videoType; if (!res.ContainsKey(br)) { MPUrlSourceFilter.RtmpUrl rtmpUrl; if (spc == SouthParkCountry.World) { rtmpUrl = new MPUrlSourceFilter.RtmpUrl(@"rtmpe://viacommtvstrmfs.fplive.net:1935/viacommtvstrm"); int p = url.IndexOf("gsp.comedystor"); if (p >= 0) rtmpUrl.PlayPath = "mp4:" + url.Substring(p); } else rtmpUrl = new MPUrlSourceFilter.RtmpUrl(url) { SwfVerify = swfUrl != null, SwfUrl = swfUrl }; res.Add(br, rtmpUrl.ToString()); } } string subtitleText = null; if (enableSubtitles) { XmlNode sub = doc.SelectSingleNode("//transcript/typographic[@format='vtt' and @src]"); if (sub != null) { string url = sub.Attributes["src"].Value; if (!String.IsNullOrEmpty(url)) subtitleText = Helpers.SubtitleUtils.Webvtt2SRT(GetWebData(url)); } } return new Tuple<Dictionary<string, string>, string>(res, subtitleText); }
public override String GetVideoUrl(VideoInfo video) { string webData = HttpUtility.UrlDecode(GetWebData(video.VideoUrl)); string url = string.Empty; //TODO: Fix flashdrm Videos if (webData.Contains("flashdrm_url")) { url = Regex.Match(webData, @"flashdrm_url"":""(?<Value>[^""]+)""").Groups["Value"].Value; url = HttpUtility.UrlDecode(url); while(url.Contains("\\/")) url = url.Replace("\\/", "/"); url = url.Replace("rtmpte", "rtmpe"); url = url.Replace(".net", ".net:1935"); url = new MPUrlSourceFilter.RtmpUrl(url) { SwfUrl = "http://www.prosieben.de/static/videoplayer/swf/HybridPlayer.swf", SwfVerify = true }.ToString(); } else { string jsonData = Regex.Match(webData, @"SIMVideoPlayer.extract\(""json"",\s*""(?<json>.*?)""\s*\);", RegexOptions.Singleline).Groups["json"].Value; var json = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(Regex.Unescape(jsonData)); // try http mp4 file from id string clipId = json["categoryList"][0]["clipList"][0].Value<string>("id"); if (!string.IsNullOrEmpty(clipId)) { string link = WebCache.Instance.GetRedirectedUrl("http://www.prosieben.de/dynamic/h264/h264map/?ClipID=" + clipId); if (!string.IsNullOrEmpty(link)) { if (!link.Contains("not_available")) { url = link; } } } if (string.IsNullOrEmpty(url)) { var dl = json.Descendants().Where(j => j.Type == Newtonsoft.Json.Linq.JTokenType.Property && ((Newtonsoft.Json.Linq.JProperty)j).Name == "downloadFilename"); foreach (var prop in dl) { string filename = (prop as Newtonsoft.Json.Linq.JProperty).Value.ToString(); string geo = (prop.Parent as Newtonsoft.Json.Linq.JObject).Value<string>("geoblocking"); string geoblock = string.Empty; if (string.IsNullOrEmpty(geo)) geoblock = "geo_d_at_ch/"; else if (geo.Contains("ww")) geoblock = "geo_worldwide/"; else if (geo.Contains("de_at_ch")) geoblock = "geo_d_at_ch/"; else geoblock = "geo_d/"; if (webData.Contains("flashSuffix") || filename.Contains(".mp4")) { url = rtmpBase + geoblock + /*"mp4:" +*/ filename; if (!url.EndsWith(".mp4")) url = url + ".mp4"; } else url = rtmpBase + geoblock + filename; } } } return url; }
public override String GetVideoUrl(VideoInfo video) { video.PlaybackOptions = new Dictionary<string, string>(); var json = GetWebData<JObject>(video.VideoUrl); foreach (var quality in json["videoJsonPlayer"]["VSR"]) { string qualityName = string.Format("{0} | {1} | {2}", quality.First.Value<string>("versionShortLibelle").PadRight(3), quality.First.Value<string>("mediaType").PadRight(4), quality.First.Value<string>("quality")); if (quality.First.Value<string>("mediaType") == "rtmp") { if (!video.PlaybackOptions.ContainsKey(qualityName)) { string host = quality.First.Value<string>("streamer"); string file = quality.First.Value<string>("url"); string playbackUrl = new MPUrlSourceFilter.RtmpUrl(host) { TcUrl = host, PlayPath = "mp4:" + file }.ToString(); video.PlaybackOptions.Add(qualityName, playbackUrl); } } else if (quality.First.Value<string>("mediaType") == "mp4") { string file = quality.First.Value<string>("url"); video.PlaybackOptions.Add(qualityName, file); } } return video.PlaybackOptions.FirstOrDefault(q => q.Key.Contains(videoQuality.ToString())).Value; }
public override string GetVideoUrl(VideoInfo video) { string result = ""; string webData = GetWebData(loadTokenUrl); if (!string.IsNullOrEmpty(webData)) { Match loadTokenMatch = loadTokenRegex.Match(webData); if (loadTokenMatch.Success) { string token = HttpUtility.UrlDecode(loadTokenMatch.Groups["token"].Value); // scientific way to figure out which host the video is hosted on string host = video.VideoUrl.StartsWith("D_") ? "cp107996" : "cp107997"; string url = string.Format(rtmpUrlFormat, host, token); MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(url) { PlayPath = string.Format(playPathFormat, video.VideoUrl), SwfVerify = true, SwfUrl = swfUrl }; Log.Debug(@"rtmp url: {0} playpath: {1}", url, rtmpUrl.PlayPath); result = rtmpUrl.ToString(); } } return result; }
public override String GetVideoUrl(VideoInfo video) { video.PlaybackOptions = new Dictionary <string, string>(); var json = GetWebData <JObject>(video.VideoUrl); foreach (var quality in json["videoJsonPlayer"]["VSR"]) { string qualityName = string.Format("{0} | {1} | {2}", quality.First.Value <string>("versionShortLibelle").PadRight(3), quality.First.Value <string>("mediaType").PadRight(4), quality.First.Value <string>("quality")); if (quality.First.Value <string>("mediaType") == "rtmp") { if (!video.PlaybackOptions.ContainsKey(qualityName)) { string host = quality.First.Value <string>("streamer"); string file = quality.First.Value <string>("url"); string playbackUrl = new MPUrlSourceFilter.RtmpUrl(host) { TcUrl = host, PlayPath = "mp4:" + file }.ToString(); video.PlaybackOptions.Add(qualityName, playbackUrl); } } else if (quality.First.Value <string>("mediaType") == "mp4") { string file = quality.First.Value <string>("url"); video.PlaybackOptions.Add(qualityName, file); } } return(video.PlaybackOptions.FirstOrDefault(q => q.Key.Contains(videoQuality.ToString())).Value); }
public override string GetVideoUrl(VideoInfo video) { string resultUrl = ""; string webData = GetWebData(video.VideoUrl); string id = Regex.Match(webData, @"var\splaylist_cur_med\s=\s(?<id>[^;]*);").Groups["id"].Value; string playerInfo = GetWebData("http://www.nrj12.fr/player/newplayer?media=" + id); if (Regex.Match(playerInfo, @"<item\sid=""video""\stype=""String""\svalue=""(?<m0>[^""]*)""/>").Success) { string url = Regex.Match(playerInfo, @"<item\sid=""video""\stype=""String""\svalue=""(?<m0>[^""]*)""/>").Groups["m0"].Value; resultUrl = new MPUrlSourceFilter.RtmpUrl("rtmp://stream2.nrj.yacast.net:1935/nrj", "stream2.nrj.yacast.net", 443) { App = "nrj", PlayPath = "flv:" + url.Replace(".flv", "") }.ToString(); } if (Regex.Match(playerInfo, @"name=""movie"" value=""(?<m0>[^""]*)""").Success) { string url = Regex.Match(playerInfo, @"name=""movie"" value=""(?<m0>[^""]*)""").Groups["m0"].Value; string dailyData = GetWebData(url.Replace("/swf/", "/")); resultUrl = GetSubString(dailyData, @"""video"", """, @""""); //Regex.Match(dailyData, @"so\.addVariable\(""video"",\s""(?<m0>[^""]*)""\)").Groups["m0"].Value; Log.Info("Result URL : " + resultUrl); } return(resultUrl); }
public override string GetVideoUrl(VideoInfo video) { string result = string.Empty; string data = GetWebData(string.Format(@"{0}{1}", baseUrl, tokenUrl)); if (!string.IsNullOrEmpty(data)) { Match tokenMatch = tokenRegex.Match(data); if (tokenMatch.Success) { data = GetWebData(video.VideoUrl); string token = HttpUtility.UrlDecode(tokenMatch.Groups["token"].Value); string url = string.Format(rtmpUrlFormat, token); if (!string.IsNullOrEmpty(data)) { Match filenameMatch = filenameRegex.Match(data); if (filenameMatch.Success) { string playPath = string.Format(playPathFormat, filenameMatch.Groups["filename"].Value); result = new MPUrlSourceFilter.RtmpUrl(url) { PlayPath = playPath }.ToString(); } } } } return(result); }
public string CreateRTMPUrl(string url) { Log.Debug(@"Video URL (before): {0}", url); string result = url; // must specify referer as 3rd argument (or we will get 403 Forbidden from cls.ctvdigital.net) string webData = GetWebData(url, referer: baseUrl); if (!string.IsNullOrEmpty(webData)) { Match urlMatch = clipUrlRegex.Match(webData); if (urlMatch.Success) { string rtmpFromScraper = urlMatch.Groups["url"].Value; Log.Debug("RTMP URL found: {0}", rtmpFromScraper); Match m = rtmpUrlRegex.Match(rtmpFromScraper); if (m.Success) { string rtmpUrl = String.Format(@"rtmpe://{0}/ondemand?{1}", m.Groups["host"], m.Groups["params"]); string file = m.Groups["file"].Value; string playPath = file.Contains(@"secure") ? file.Replace(".flv", string.Empty) // replace trailing .flv : String.Format(@"mp4:{0}", file); // prepend mp4: Log.Debug(@"RTMP URL partial: {0} playPath: {1}", rtmpUrl, playPath); result = new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = playPath, SwfUrl = swfUrl, SwfVerify = true }.ToString(); Log.Debug(@"RTMP URL(MPUrlSourceFilter after): {0}", result); } else { m = rtmpUrlSecondaryRegex.Match(rtmpFromScraper); if (m.Success) { string rtmpUrl = String.Format(@"rtmpe://{0}/{1}?{2}", m.Groups["host"], m.Groups["app"], m.Groups["params"]); string playPath = String.Format(@"mp4:{0}?{1}", m.Groups["file"], m.Groups["params"]); result = new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = playPath, SwfUrl = swfUrl, SwfVerify = true }.ToString(); Log.Debug(@"RTMP URL Secondary Option (after): {0}", result); } else { Log.Error(@"Unknown RTMP URL: {0}", rtmpFromScraper); } } } } return(result); }
public override string GetVideoUrl(VideoInfo video) { JObject data = GetWebData <JObject>(video.VideoUrl); string playstr; if (data["streams"]["medium"].Type != JTokenType.Null) { playstr = data["streams"]["medium"].Value <string>(); if (playstr.ToLower().StartsWith("rtmp")) { int mp4IndexFlash = playstr.ToLower().IndexOf("mp4:"); int mp4Index = mp4IndexFlash >= 0 ? mp4IndexFlash : playstr.ToLower().IndexOf("flv:"); if (mp4Index > 0) { playstr = new MPUrlSourceFilter.RtmpUrl(playstr.Substring(0, mp4Index)) { PlayPath = playstr.Substring(mp4Index), SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } else { playstr = new MPUrlSourceFilter.RtmpUrl(playstr) { SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } } else if (playstr.ToLower().EndsWith(".f4m")) { playstr += "?hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } else if (playstr.ToLower().Contains(".f4m?")) { playstr += "&hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } } else { playstr = data["streams"]["hls"].Value <string>(); video.PlaybackOptions = new Dictionary <string, string>(); foreach (KeyValuePair <string, string> pair in HlsPlaylistParser.GetPlaybackOptions(GetWebData(playstr), playstr, (x, y) => y.Bandwidth.CompareTo(x.Bandwidth), (x) => x.Width + "x" + x.Height + " (" + x.Bandwidth / 1000 + " Kbps)")) { MPUrlSourceFilter.HttpUrl httpUrl = new MPUrlSourceFilter.HttpUrl(pair.Value); httpUrl.Referer = video.VideoUrl; httpUrl.UserAgent = "Mozilla/5.0 (Windows NT 6.1)"; video.PlaybackOptions.Add(pair.Key, httpUrl.ToString()); } playstr = video.PlaybackOptions.First().Value; } if (!string.IsNullOrEmpty(video.SubtitleUrl) && string.IsNullOrEmpty(video.SubtitleText)) { video.SubtitleText = GetSubtitle(video.SubtitleUrl); } return(playstr); }
public override string GetVideoUrl(VideoInfo video) { JObject data = GetWebData <JObject>(video.VideoUrl); string playstr; if (data["streams"]["medium"].Type != JTokenType.Null) { playstr = data["streams"]["medium"].Value <string>(); if (playstr.ToLower().StartsWith("rtmp")) { int mp4IndexFlash = playstr.ToLower().IndexOf("mp4:"); int mp4Index = mp4IndexFlash >= 0 ? mp4IndexFlash : playstr.ToLower().IndexOf("flv:"); if (mp4Index > 0) { playstr = new MPUrlSourceFilter.RtmpUrl(playstr.Substring(0, mp4Index)) { PlayPath = playstr.Substring(mp4Index), SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } else { playstr = new MPUrlSourceFilter.RtmpUrl(playstr) { SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } } else if (playstr.ToLower().EndsWith(".f4m")) { playstr += "?hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } else if (playstr.ToLower().Contains(".f4m?")) { playstr += "&hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } } else { playstr = data["streams"]["hls"].Value <string>(); video.PlaybackOptions = new Dictionary <string, string>(); OnlineVideos.Sites.Utils.MyHlsPlaylistParser parser = new OnlineVideos.Sites.Utils.MyHlsPlaylistParser(GetWebData(playstr), playstr); foreach (OnlineVideos.Sites.Utils.MyHlsStreamInfo streamInfo in parser.StreamInfos) { video.PlaybackOptions.Add(streamInfo.Width + "x" + streamInfo.Height + " (" + streamInfo.Bandwidth / 1000 + " kbps)", streamInfo.Url); } playstr = video.PlaybackOptions.First().Value; } if (!string.IsNullOrEmpty(video.SubtitleUrl) && string.IsNullOrEmpty(video.SubtitleText)) { video.SubtitleText = GetSubtitle(video.SubtitleUrl); } return(playstr); }
public override string GetVideoUrl(VideoInfo video) { if (video.VideoUrl.Contains("+")) { string aUrl = ""; video.PlaybackOptions = new Dictionary <string, string>(); string[] qualities = video.VideoUrl.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (string quality in qualities) { string[] q_l = quality.Split('+'); if (aUrl == "") { aUrl = q_l[1]; } q_l[1] = q_l[1].Replace("rtmp://", ""); string filetype = q_l[1].Substring(q_l[1].Length - 3, 3); q_l[1] = q_l[1].Replace("bonanza/bonanza", "bonanza/" + filetype + ":bonanza"); string[] paths = q_l[1].Split(':'); string playpath = string.Empty; if (paths[0].Substring(paths[0].Length - 3, 3) == "mp4") { playpath = "mp4:" + paths[1].Substring(0, paths[1].Length - 4); } else { playpath = "flv:" + paths[1].Substring(0, paths[1].Length - 4); } string vUrl = new MPUrlSourceFilter.RtmpUrl("rtmp://" + q_l[1]) { PlayPath = playpath }.ToString(); //vUrl = "rtmp://vod-bonanza.gss.dr.dk/bonanza/mp4:bonanza/12-04-2008/1901_720x540x1400K.mp4"; video.PlaybackOptions.Add(q_l[0], vUrl); } return(aUrl); } else if ((string)video.Other.ToString() == "drlive") { string link = loadLiveAsset(video.VideoUrl); return(link); } else if ((string)video.Other == "drnu") { Tuple <string, string> link = loadAsset(video.VideoUrl); video.SubtitleText = link.Item2; return(link.Item1); } else { return(base.GetVideoUrl(video)); } }
MPUrlSourceFilter.RtmpUrl getRTMPUrl(string naviXRTMPUrl) { MatchCollection matches = new Regex(@"\s+(tcUrl|app|playpath|swfUrl|pageUrl|swfVfy|live|timeout)\s*=\s*([^\s]*)", RegexOptions.IgnoreCase).Matches(naviXRTMPUrl); if (matches.Count < 1) { return(new MPUrlSourceFilter.RtmpUrl(naviXRTMPUrl)); } MPUrlSourceFilter.RtmpUrl url = new MPUrlSourceFilter.RtmpUrl(naviXRTMPUrl.Substring(0, matches[0].Index)); foreach (Match m in matches) { string val = m.Groups[2].Value; switch (m.Groups[1].Value.ToLower()) { case "tcurl": url.TcUrl = val; break; case "app": url.App = val; break; case "playpath": url.PlayPath = val; break; case "swfurl": url.SwfUrl = val; break; case "pageurl": url.PageUrl = val; break; case "swfvfy": if (val == "1" || val.ToLower() == "true") { url.SwfVerify = true; } break; case "live": if (val == "1" || val.ToLower() == "true") { url.Live = true; } break; } } return(url); }
public static string createRtmpUrl(string url) { string result = url; // cannot use GetWebData to figure out VideoUrl as the URL responds with // HTTP/1.1 302 Found // with a Location header containing the rtmp:// URL HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.AllowAutoRedirect = false; Log.Debug(@"Making manual HttpWebRequest for {0}", url); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.Redirect) { // retrieve the RTMP URL from the Location header string rtmpUrlFromHeader = response.GetResponseHeader("Location"); Log.Debug(@"RTMP URL from header: {0}", rtmpUrlFromHeader); // split on <break> string[] pathParts = rtmpUrlFromHeader.Split(new string[] { "<break>" }, StringSplitOptions.None); string host = pathParts[0]; string playPath = pathParts[1]; if (host.StartsWith("{switch:none}{manifest:none}")) { // Handle URLs of form {switch:none}{manifest:none}rtmp://cp209208.edgefcs.net/ondemand/?auth=daFbRa0aldEcad_bsd7cXawd5dId3bkdjdw-btCbTQ-c0-oknqnHronA&aifp=v0001&slist=287/267/<break>287/267/Arctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.mp4{manifest:f4m}http://mobilehls-vh.akamaihd.net/z/prodVideo/entertainment/287%2F267%2FArctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.csmil/manifest.f4m?hdnea=st=1399855948~exp=1399856278~acl=/z/*~id={nonce}~hmac=UNRECOGNIZED_TOKEN_TYPE{manifest:m3u}http://mobilehls-vh.akamaihd.net/i/prodVideo/entertainment/287%2F267%2FArctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.csmil/master.m3u8?hdnea=st=1399855948~exp=1399856278~acl=/i/*~id={nonce}~hmac=UNRECOGNIZED_TOKEN_TYPE{manifest}{switch:http}http://progressive.cbc.ca/prodVideo/entertainment/287/267/Arctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.mp4?hdnea=st=1399855948~exp=1399856278~acl=/*~hmac=UNRECOGNIZED_TOKEN_TYPE{switch} host = pathParts[0].Substring(28); playPath = pathParts[1].Substring(0, pathParts[1].IndexOf("{manifest")); } if (playPath.EndsWith(@".mp4") && !playPath.StartsWith(@"mp4:")) { // prepend with mp4: playPath = @"mp4:" + playPath; } else if (playPath.EndsWith(@".flv")) { // strip extension playPath = playPath.Substring(0, playPath.Length - 4); } Log.Debug(@"Host: {0}, PlayPath: {1}", host, playPath); result = new MPUrlSourceFilter.RtmpUrl(host) { PlayPath = playPath }.ToString(); } return(result); }
protected string FillPlaybackOptions(VideoInfo video, AMFArray renditions) { video.PlaybackOptions = new Dictionary <string, string>(); foreach (AMFObject rendition in renditions.OrderBy(u => u.GetIntProperty("encodingRate"))) { string nm = String.Format("{0}x{1} {2}K", rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"), rendition.GetIntProperty("encodingRate") / 1024); string url = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL")); if (url.StartsWith("rtmp")) { //tested with ztele string auth = String.Empty; if (url.Contains('?')) { auth = '?' + url.Split('?')[1]; } string[] parts = url.Split('&'); string rtmp = parts[0] + auth; string playpath = parts[1].Split('?')[0] + auth; url = new MPUrlSourceFilter.RtmpUrl(rtmp) { PlayPath = playpath }.ToString(); } video.PlaybackOptions.Add(nm, url); } if (video.PlaybackOptions.Count == 0) { return(""); // if no match, return empty url -> error } else if (video.PlaybackOptions.Count == 1) { string resultUrl = video.PlaybackOptions.Last().Value; video.PlaybackOptions = null; // only one url found, PlaybackOptions not needed return(resultUrl); } else { return(video.PlaybackOptions.Last().Value); } }
private string FillPlaybackOptions(VideoInfo video, AMFArray renditions) { SortedList <string, string> options = new SortedList <string, string>(new StreamComparer()); for (int i = 0; i < renditions.Count; i++) { AMFObject rendition = renditions.GetObject(i); int encodingRate = rendition.GetIntProperty("encodingRate"); string nm = String.Format("{0}x{1} | {2} kbps", rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"), encodingRate / 1000); string url = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL")); if (url.StartsWith("rtmp")) { string auth = String.Empty; if (url.Contains('?')) { auth = '?' + url.Split('?')[1]; } string[] parts = url.Split('&'); string rtmp = parts[0] + auth; string playpath = parts[1].Split('?')[0] + auth; url = new MPUrlSourceFilter.RtmpUrl(rtmp) { PlayPath = playpath, SwfUrl = "http://admin.brightcove.com/viewer/us20111207.0737/connection/ExternalConnection_2.swf", SwfVerify = true }.ToString(); } if (!options.ContainsKey(nm)) { options.Add(nm, url); } } video.PlaybackOptions = new Dictionary <string, string>(); foreach (KeyValuePair <string, string> key in options) { video.PlaybackOptions.Add(key.Key, key.Value); } return(StreamComparer.GetBestPlaybackUrl(video.PlaybackOptions, StreamQualityPref, AutoSelectStream)); }
public override string GetVideoUrl(VideoInfo video) { if (video.VideoUrl.Contains("+")) { string aUrl = ""; video.PlaybackOptions = new Dictionary<string, string>(); string[] qualities = video.VideoUrl.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (string quality in qualities) { string[] q_l = quality.Split('+'); if (aUrl == "") aUrl = q_l[1]; q_l[1] = q_l[1].Replace("rtmp://", ""); string filetype = q_l[1].Substring(q_l[1].Length - 3, 3); q_l[1] = q_l[1].Replace("bonanza/bonanza", "bonanza/" + filetype + ":bonanza"); string[] paths = q_l[1].Split(':'); string playpath = string.Empty; if (paths[0].Substring(paths[0].Length - 3, 3) == "mp4") { playpath = "mp4:" + paths[1].Substring(0, paths[1].Length - 4); } else { playpath = "flv:" + paths[1].Substring(0, paths[1].Length - 4); } string vUrl = new MPUrlSourceFilter.RtmpUrl("rtmp://" + q_l[1]) { PlayPath = playpath }.ToString(); video.PlaybackOptions.Add(q_l[0], vUrl); } return aUrl; } else if ((string)video.Other.ToString() == "drlive") { string link = loadLiveAsset(video.VideoUrl); return link; } else if ((string)video.Other == "drnu") { Tuple<string, string> link = loadAsset(video.VideoUrl); video.SubtitleText = link.Item2; return link.Item1; } else { return base.GetVideoUrl(video); } }
public override string GetPlaylistItemVideoUrl(VideoInfo clonedVideoInfo, string chosenPlaybackOption, bool inPlaylist) { string result = string.Empty; XmlDocument xml = GetWebData <XmlDocument>(clonedVideoInfo.VideoUrl); if (xml != null) { foreach (XmlNode rendition in xml.SelectNodes(@"//video/item/rendition")) { int bitrate = int.Parse(rendition.Attributes["bitrate"].Value); XmlNode src = rendition.SelectSingleNode(@"./src"); if (string.Format("{0} kbps", bitrate).Equals(chosenPlaybackOption)) { result = new MPUrlSourceFilter.RtmpUrl(src.InnerText).ToString(); } } } return(result); }
public override string GetVideoUrl(VideoInfo video) { NaviXMediaItem item = video.Other as NaviXMediaItem; if (item == null) { return(video.VideoUrl); } string urlStr = item.URL; if (item.Type == "video" && !string.IsNullOrEmpty(item.Processor)) { NaviXProcessor proc = new NaviXProcessor(item.Processor, item.URL, item.Version, nxId); if (proc.Process()) { urlStr = proc.Data; } else { string message = string.IsNullOrEmpty(proc.LastError) ? "Error retrieving url" : proc.LastError; throw new OnlineVideosException("Navi-X says: " + message); } } if (urlStr != null && urlStr.ToLower().StartsWith("rtmp")) { MPUrlSourceFilter.RtmpUrl url = getRTMPUrl(urlStr); return(url.ToString()); } if (item.Player == "default") { Settings.Player = PlayerType.Internal; } else { Settings.Player = PlayerType.Auto; } return(urlStr); }
public override string GetVideoUrl(VideoInfo video) { string resultUrl = ""; string webData = GetWebData(video.VideoUrl); string id = Regex.Match(webData, @"var\splaylist_cur_med\s=\s(?<id>[^;]*);").Groups["id"].Value; string playerInfo = GetWebData("http://www.nrj12.fr/player/newplayer?media=" + id); if (Regex.Match(playerInfo, @"<item\sid=""video""\stype=""String""\svalue=""(?<m0>[^""]*)""/>").Success) { string url = Regex.Match(playerInfo, @"<item\sid=""video""\stype=""String""\svalue=""(?<m0>[^""]*)""/>").Groups["m0"].Value; resultUrl = new MPUrlSourceFilter.RtmpUrl("rtmp://stream2.nrj.yacast.net:1935/nrj", "stream2.nrj.yacast.net", 443) { App = "nrj", PlayPath = "flv:" + url.Replace(".flv", "") }.ToString(); } if (Regex.Match(playerInfo, @"name=""movie"" value=""(?<m0>[^""]*)""").Success) { string url = Regex.Match(playerInfo, @"name=""movie"" value=""(?<m0>[^""]*)""").Groups["m0"].Value; string dailyData = GetWebData(url.Replace("/swf/", "/")); resultUrl = GetSubString(dailyData, @"""video"", """, @""""); //Regex.Match(dailyData, @"so\.addVariable\(""video"",\s""(?<m0>[^""]*)""\)").Groups["m0"].Value; Log.Info("Result URL : " + resultUrl); } return resultUrl; }
public override string GetVideoUrl(VideoInfo video) { JObject data = GetWebData <JObject>(video.VideoUrl); string playstr = data["streams"]["medium"].Value <string>(); if (playstr.ToLower().StartsWith("rtmp")) { int mp4IndexFlash = playstr.ToLower().IndexOf("mp4:"); int mp4Index = mp4IndexFlash >= 0 ? mp4IndexFlash : playstr.ToLower().IndexOf("flv:"); if (mp4Index > 0) { playstr = new MPUrlSourceFilter.RtmpUrl(playstr.Substring(0, mp4Index)) { PlayPath = playstr.Substring(mp4Index), SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } else { playstr = new MPUrlSourceFilter.RtmpUrl(playstr) { SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } } else if (playstr.ToLower().EndsWith(".f4m")) { playstr += "?hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } if (!string.IsNullOrEmpty(video.SubtitleUrl)) { video.SubtitleText = GetSubtitle(video.SubtitleUrl); video.SubtitleUrl = ""; } return(playstr); }
private string FillPlaybackOptions(VideoInfo video, AMFArray renditions) { SortedList<string, string> options = new SortedList<string, string>(new StreamComparer()); for (int i = 0; i < renditions.Count; i++) { AMFObject rendition = renditions.GetObject(i); int encodingRate = rendition.GetIntProperty("encodingRate"); string nm = String.Format("{0}x{1} | {2} kbps", rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"), encodingRate / 1000); string url = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL")); if (url.StartsWith("rtmp")) { string auth = String.Empty; if (url.Contains('?')) auth = '?' + url.Split('?')[1]; string[] parts = url.Split('&'); string rtmp = parts[0] + auth; string playpath = parts[1].Split('?')[0] + auth; url = new MPUrlSourceFilter.RtmpUrl(rtmp) { PlayPath = playpath, SwfUrl = "http://admin.brightcove.com/viewer/us20111207.0737/connection/ExternalConnection_2.swf", SwfVerify = true }.ToString(); } if (!options.ContainsKey(nm)) options.Add(nm, url); } video.PlaybackOptions = new Dictionary<string, string>(); foreach (KeyValuePair<string, string> key in options) video.PlaybackOptions.Add(key.Key, key.Value); return StreamComparer.GetBestPlaybackUrl(video.PlaybackOptions, StreamQualityPref, AutoSelectStream); }
public override string GetPlaylistItemVideoUrl(VideoInfo clonedVideoInfo, string chosenPlaybackOption, bool inPlaylist) { string result = string.Empty; XmlDocument xml = GetWebData<XmlDocument>(clonedVideoInfo.VideoUrl); if (xml != null) { foreach (XmlNode rendition in xml.SelectNodes(@"//video/item/rendition")) { int bitrate = int.Parse(rendition.Attributes["bitrate"].Value); XmlNode src = rendition.SelectSingleNode(@"./src"); if (string.Format("{0} kbps", bitrate).Equals(chosenPlaybackOption)) { result = new MPUrlSourceFilter.RtmpUrl(src.InnerText).ToString(); } } } return result; }
public override string GetVideoUrl(VideoInfo video) { String baseWebData = GetWebData(video.VideoUrl, forceUTF8: true); String episodeJS = GetWebData(PrimaUtil.episodeUrlJS, referer: video.VideoUrl, forceUTF8: true); baseWebData = HttpUtility.HtmlDecode(baseWebData); video.PlaybackOptions = new Dictionary<string, string>(); String baseRtmpUrl = String.Empty; String lqFileName = String.Empty; String hqFileName = String.Empty; String auth = String.Empty; String zone = String.Empty; Match match = Regex.Match(baseWebData, PrimaUtil.episodeLqFileNameFormat); if (match.Success) { lqFileName = match.Groups["lqFileName"].Value; } match = Regex.Match(baseWebData, PrimaUtil.episodeHqFileNameFormat); if (match.Success) { hqFileName = match.Groups["hqFileName"].Value; } match = Regex.Match(baseWebData, PrimaUtil.episodeZone); if (match.Success) { zone = match.Groups["zone"].Value; } int startIndex = episodeJS.IndexOf(PrimaUtil.episodeBaseUrlStart); if (startIndex >= 0) { int endIndex = episodeJS.IndexOf(PrimaUtil.episodeBaseUrlEnd, startIndex + PrimaUtil.episodeBaseUrlStart.Length); if (endIndex >= 0) { baseRtmpUrl = "rtmp" + episodeJS.Substring(startIndex + PrimaUtil.episodeBaseUrlStart.Length, endIndex - startIndex - PrimaUtil.episodeBaseUrlStart.Length).Replace("iprima_token", ""); } } startIndex = episodeJS.IndexOf(PrimaUtil.episodeAuthSectionStart); if (startIndex >= 0) { int endIndex = episodeJS.IndexOf(PrimaUtil.episodeAuthSectionEnd, startIndex + PrimaUtil.episodeAuthSectionStart.Length); if (endIndex >= 0) { String authSection = episodeJS.Substring(startIndex, endIndex - startIndex); while (true) { startIndex = authSection.IndexOf(PrimaUtil.episodeAuthStart); if (startIndex >= 0) { endIndex = authSection.IndexOf(PrimaUtil.episodeAuthEnd, startIndex + PrimaUtil.episodeAuthStart.Length); if (endIndex >= 0) { auth = authSection.Substring(startIndex + PrimaUtil.episodeAuthStart.Length, endIndex - startIndex - PrimaUtil.episodeAuthStart.Length); authSection = authSection.Substring(startIndex + PrimaUtil.episodeAuthStart.Length + auth.Length); } else { break; } } else { break; } } } } if ((!String.IsNullOrEmpty(auth)) && (!(String.IsNullOrEmpty(lqFileName) || String.IsNullOrEmpty(hqFileName) || String.IsNullOrEmpty(baseRtmpUrl)))) { String app = String.Format("iprima_token{0}?auth={1}", zone == "0" ? "" : "_" + zone, auth); String tcUrl = String.Format("{0}{1}", baseRtmpUrl, app); if (!String.IsNullOrEmpty(lqFileName)) { String playPath = "mp4:" + lqFileName; OnlineVideos.MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(baseRtmpUrl) { App = app, TcUrl = tcUrl, PlayPath = playPath, SwfUrl = String.Format("http://embed.livebox.cz/iprimaplay/flash/LiveboxPlayer.swf?nocache={0}", (UInt64)((DateTime.Now - new DateTime(1970, 1, 1)).TotalMilliseconds)), PageUrl = video.VideoUrl }; video.PlaybackOptions.Add("Low quality", rtmpUrl.ToString()); } if (!String.IsNullOrEmpty(hqFileName)) { String playPath = "mp4:" + hqFileName; OnlineVideos.MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(baseRtmpUrl) { App = app, TcUrl = tcUrl, PlayPath = playPath, SwfUrl = String.Format("http://embed.livebox.cz/iprimaplay/flash/LiveboxPlayer.swf?nocache={0}", (UInt64)((DateTime.Now - new DateTime(1970, 1, 1)).TotalMilliseconds)), PageUrl = video.VideoUrl }; video.PlaybackOptions.Add("High quality", rtmpUrl.ToString()); } } else { Match flashVarsStart = Regex.Match(baseWebData, PrimaUtil.flashVarsStartRegex); if (flashVarsStart.Success) { int end = baseWebData.IndexOf(PrimaUtil.flashVarsEnd, flashVarsStart.Index); if (end > 0) { baseWebData = baseWebData.Substring(flashVarsStart.Index, end - flashVarsStart.Index); Match idMatch = Regex.Match(baseWebData, PrimaUtil.idRegex); Match cdnLqMatch = Regex.Match(baseWebData, PrimaUtil.cdnLqRegex); Match cdnHqMatch = Regex.Match(baseWebData, PrimaUtil.cdnHqRegex); String id = (idMatch.Success) ? idMatch.Groups["id"].Value : String.Empty; String cdnLq = (cdnLqMatch.Success) ? cdnLqMatch.Groups["cdnLQ"].Value : String.Empty; String cdnHq = (cdnHqMatch.Success) ? cdnHqMatch.Groups["cdnHQ"].Value : String.Empty; if ((!String.IsNullOrEmpty(cdnLq)) && (!String.IsNullOrEmpty(cdnHq))) { // we got low and high quality String lowQualityUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnLq)); String highQualityUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnHq)); video.PlaybackOptions = new Dictionary<string, string>(); video.PlaybackOptions.Add("Low quality", lowQualityUrl); video.PlaybackOptions.Add("High quality", highQualityUrl); } else if (!String.IsNullOrEmpty(cdnLq)) { video.VideoUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnLq)); } else if (!String.IsNullOrEmpty(cdnHq)) { video.VideoUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnHq)); } } } } if (video.PlaybackOptions != null && video.PlaybackOptions.Count > 0) { var enumer = video.PlaybackOptions.GetEnumerator(); enumer.MoveNext(); return enumer.Current.Value; } return video.VideoUrl; }
string getCatchupUrls(VideoInfo video) { WebProxy proxyObj = getProxy(); Match m = videoPidRegex.Match(GetWebData(video.VideoUrl, proxy: proxyObj)); if (!m.Success) { Log.Warn("BBCiPlayer: Failed to parse vpid from '{0}'", video.VideoUrl); return null; } string vpid = m.Groups[1].Value; XmlDocument doc = new XmlDocument(); doc.LoadXml(GetWebData(MEDIA_SELECTOR_URL + vpid, proxy: proxyObj)); //uk only XmlNamespaceManager nsmRequest = new XmlNamespaceManager(doc.NameTable); nsmRequest.AddNamespace("ns1", "http://bbc.co.uk/2008/mp/mediaselection"); if (RetrieveSubtitles) { XmlNode captionNode = doc.SelectSingleNode("//ns1:media[@kind='captions']", nsmRequest); if (captionNode != null) { XmlNode captionConnection = captionNode.SelectSingleNode("ns1:connection", nsmRequest); if (captionConnection != null && captionConnection.Attributes["href"] != null) { string sub = GetWebData(captionConnection.Attributes["href"].Value); video.SubtitleText = OnlineVideos.Sites.Utils.SubtitleReader.TimedText2SRT(sub); } } } SortedList<string, string> sortedPlaybackOptions = new SortedList<string, string>(new StreamComparer()); foreach (XmlElement mediaElem in doc.SelectNodes("//ns1:media[@kind='video']", nsmRequest)) { string info = ""; string resultUrl = ""; foreach (XmlElement connectionElem in mediaElem.SelectNodes("ns1:connection", nsmRequest)) { string supplier = connectionElem.Attributes["supplier"].Value; //"kind" if (Array.BinarySearch<string>(new string[] { "akamai", "level3", "limelight" }, supplier) >= 0) { // rtmp if (connectionElem.Attributes["protocol"] == null || connectionElem.Attributes["protocol"].Value != "rtmp") continue; string server = connectionElem.Attributes["server"].Value; string identifier = connectionElem.Attributes["identifier"].Value; string auth = connectionElem.Attributes["authString"].Value; string application = connectionElem.GetAttribute("application"); if (string.IsNullOrEmpty(application)) application = "ondemand"; string SWFPlayer = "http://www.bbc.co.uk/emp/releases/iplayer/revisions/617463_618125_4/617463_618125_4_emp.swf"; // "http://www.bbc.co.uk/emp/10player.swf"; info = string.Format("{0}x{1} | {2} kbps | {3}", mediaElem.GetAttribute("width"), mediaElem.GetAttribute("height"), mediaElem.GetAttribute("bitrate"), supplier); resultUrl = ""; if (supplier == "limelight") { resultUrl = new MPUrlSourceFilter.RtmpUrl(string.Format("rtmp://{0}:1935/{1}", server, application + "?" + auth), server, 1935) { App = application + "?" + auth, PlayPath = identifier, SwfUrl = SWFPlayer, SwfVerify = true, }.ToString(); } else if (supplier == "level3") { resultUrl = new MPUrlSourceFilter.RtmpUrl(string.Format("rtmp://{0}:1935/{1}", server, application + "?" + auth), server, 1935) { App = application + "?" + auth, PlayPath = identifier, SwfUrl = SWFPlayer, SwfVerify = true, Token = auth, }.ToString(); } else if (supplier == "akamai") { resultUrl = new MPUrlSourceFilter.RtmpUrl(string.Format("rtmp://{0}:1935/{1}?{2}", server, application, auth)) { PlayPath = identifier + "?" + auth, SwfUrl = SWFPlayer, SwfVerify = true, }.ToString(); } } if (resultUrl != "") sortedPlaybackOptions.Add(info, resultUrl); } } video.PlaybackOptions = new Dictionary<string, string>(); if (sortedPlaybackOptions.Count > 0) { if (AutoSelectStream) { var last = sortedPlaybackOptions.Last(); video.PlaybackOptions.Add(last.Key, last.Value); return last.Value; } else { foreach (var option in sortedPlaybackOptions) video.PlaybackOptions.Add(option.Key, option.Value); return sortedPlaybackOptions.Last().Value; } } //Fallback to HLS streams string url = getHLSVideoUrls(video, vpid, proxyObj); if (!string.IsNullOrEmpty(url)) return url; var errorNodes = doc.SelectNodes("//ns1:error", nsmRequest); if (errorNodes.Count > 0) throw new OnlineVideosException(string.Format("BBC says: {0}", ((XmlElement)errorNodes[0]).GetAttribute("id"))); return null; }
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); }
protected string FillPlaybackOptions(VideoInfo video, AMFArray renditions) { video.PlaybackOptions = new Dictionary<string, string>(); foreach (AMFObject rendition in renditions.OrderBy(u => u.GetIntProperty("encodingRate"))) { string nm = String.Format("{0}x{1} {2}K", rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"), rendition.GetIntProperty("encodingRate") / 1024); string url = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL")); if (url.StartsWith("rtmp")) { //tested with ztele string auth = String.Empty; if (url.Contains('?')) auth = '?' + url.Split('?')[1]; string[] parts = url.Split('&'); string rtmp = parts[0] + auth; string playpath = parts[1].Split('?')[0] + auth; url = new MPUrlSourceFilter.RtmpUrl(rtmp) { PlayPath = playpath }.ToString(); } video.PlaybackOptions.Add(nm, url); } if (video.PlaybackOptions.Count == 0) return "";// if no match, return empty url -> error else if (video.PlaybackOptions.Count == 1) { string resultUrl = video.PlaybackOptions.Last().Value; video.PlaybackOptions = null;// only one url found, PlaybackOptions not needed return resultUrl; } else { return video.PlaybackOptions.Last().Value; } }
protected new string FillPlaybackOptions(VideoInfo video, AMFArray renditions, Match m) { video.PlaybackOptions = new Dictionary<string, string>(); foreach (AMFObject rendition in renditions.OrderBy(u => u.GetIntProperty("encodingRate"))) { string nm = String.Format("{0}x{1} {2}K", rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"), rendition.GetIntProperty("encodingRate") / 1024); string url = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL")); //"rtmp://brightcove.fcod.llnwd.net/a500/e1/uds/rtmp/ondemand/&mp4:102076681001/102076681001_986209826001_26930-20110610-122117.mp4&1368558000000&0aa762d184c16de09a21fe533394c3ea" if (url.StartsWith("rtmp")) { //tested with ztele string auth = String.Empty; if (url.Contains('?')) auth = '?' + url.Split('?')[1]; string[] parts = url.Split('&'); string rtmp = parts[0] + auth; //"rtmp://brightcove.fcod.llnwd.net/a500/e1/uds/rtmp/ondemand/" string playpath = parts[1].Split('?')[0] + auth; //"mp4:102076681001/102076681001_986209826001_26930-20110610-122117.mp4" if (url.IndexOf("edgefcs.net") != -1) { /*rtmpdump --rtmp "rtmp://cp150446.edgefcs.net/ondemand/&mp4:102076681001/102076681001_1506435728001_66034-20120314-120404.mp4?__nn__=1497926354001&slist=102076681001/&auth=daEbVc2bZd2bpcZdcbxbVdld6cEdWcpb4dC-brKM2q-bWG-rnBBssvx_ABAo_DDCB_GuD&aifp=bcosuds" --app="ondemand?__nn__=1497926354001&slist=102076681001/&auth=daEbVc2bZd2bpcZdcbxbVdld6cEdWcpb4dC-brKM2q-bWG-rnBBssvx_ABAo_DDCB_GuD&aifp=bcosuds&videoId=1506302142001&lineUpId=&pubId=102076681001&playerId=2202962695001" --swfUrl="http://admin.brightcove.com/viewer/us20121213.1025/federatedVideoUI/BrightcovePlayer.swf?uid=1355746343102" --playpath="mp4:102076681001/102076681001_1506435728001_66034-20120314-120404.mp4?__nn__=1497926354001&slist=102076681001/&auth=daEbVc2bZd2bpcZdcbxbVdld6cEdWcpb4dC-brKM2q-bWG-rnBBssvx_ABAo_DDCB_GuD&aifp=bcosuds&videoId=1506302142001" --pageUrl="http://www.eitb.tv/es/#/video/1506302142001" -o "Aduriz-La_cocina_de_las_palabras_-_Aduriz-Hitzen_sukaldea-.mp4"*/ url = new MPUrlSourceFilter.RtmpUrl(rtmp) { PlayPath = playpath }.ToString(); } else { /* rtmpdump --rtmp "rtmp://brightcove.fcod.llnwd.net/a500/e1/uds/rtmp/ondemand/&mp4:102076681001/102076681001_986252687001_26930-20110610-122117.mp4&1368558000000&0aa762d184c16de09a21fe533394c3ea" --app="a500/e1/uds/rtmp/ondemand?videoId=986121629001&lineUpId=&pubId=102076681001&playerId=2202962695001" --swfUrl="http://admin.brightcove.com/viewer/us20121218.1107/federatedVideoUI/BrightcovePlayer.swf?uid=1355158765470" --playpath="mp4:102076681001/102076681001_986252687001_26930-20110610-122117.mp4?videoId=986121629001&lineUpId=&pubId=102076681001&playerId=2202962695001" --pageUrl="http://www.eitb.tv/es/#/video/986121629001" -C "B:0" -C "S:mp4:102076681001/102076681001_986252687001_26930-20110610-122117.mp4&1368558000000&0aa762d184c16de09a21fe533394c3ea" -o "Sukalde_maisuak_-_Aduriz-Hitzen_sukaldea-.mp4" */ string cadena = url.Substring(url.IndexOf(".net/") + 5); cadena = cadena.Remove(cadena.IndexOf("/&")); cadena += "?videoId=" + video.VideoUrl.Substring(video.VideoUrl.LastIndexOf("/") + 1) + "&lineUpId=&pubId=" + array4 + "&playerId=" + m.Groups["experienceId"].Value; RtmpUrl rtmpUrl = new RtmpUrl(rtmp) { PlayPath = playpath, //App = "a500/e1/uds/rtmp/ondemand?videoId=986121629001&lineUpId=&pubId=102076681001&playerId=2202962695001" App = cadena }; RtmpBooleanArbitraryData p1 = new RtmpBooleanArbitraryData(false); RtmpStringArbitraryData p2 = new RtmpStringArbitraryData(parts[1]+"&"+parts[2]+"&"+parts[3]); rtmpUrl.ArbitraryData.Add(p1); rtmpUrl.ArbitraryData.Add(p2); url = rtmpUrl.ToString(); } } video.PlaybackOptions.Add(nm, url); } if (video.PlaybackOptions.Count == 0) return "";// if no match, return empty url -> error else if (video.PlaybackOptions.Count == 1) { string resultUrl = video.PlaybackOptions.Last().Value; video.PlaybackOptions = null;// only one url found, PlaybackOptions not needed return resultUrl; } else { return video.PlaybackOptions.Last().Value; } }
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://www.itv.com/mediaplayer/ITVMediaPlayer.swf?v=12.18.4", SwfVerify = true, Live = live }.ToString(); options.Add(title, url); } } video.PlaybackOptions = new Dictionary<string, string>(); foreach (KeyValuePair<string, string> key in options) video.PlaybackOptions.Add(key.Key, key.Value); if (RetrieveSubtitles) { node = videoEntry.SelectSingleNode("./ClosedCaptioningURIs"); if (node != null && Helpers.UriUtils.IsValidUri(node.InnerText)) video.SubtitleText = OnlineVideos.Sites.Utils.SubtitleReader.TimedText2SRT(GetWebData(node.InnerText)); } return StreamComparer.GetBestPlaybackUrl(video.PlaybackOptions, StreamQualityPref, AutoSelectStream); }
Tuple <Dictionary <string, string>, string> getPlaybackOptions(string videoUrl, SouthParkCountry spc) { Dictionary <string, string> res = new Dictionary <string, string>(); string data = GetWebData(videoUrl); XmlDocument doc = new XmlDocument(); doc.LoadXml(data); XmlNodeList list = doc.SelectNodes("//src"); for (int i = 0; i < list.Count; i++) { string bitrate = list[i].ParentNode.Attributes["bitrate"].Value; string videoType = list[i].ParentNode.Attributes["type"].Value.Replace(@"video/", String.Empty); string url = list[i].InnerText; string swfUrl = null; if (spc == SouthParkCountry.World) { url = url.Replace(@"viacomspstrmfs.fplive.net/viacomspstrm", @"cp10740.edgefcs.net/ondemand/mtvnorigin"); } /*switch (spc) * { * case SouthParkCountry.World: * case SouthParkCountry.De: * swfUrl = @"http://media.mtvnservices.com/player/prime/mediaplayerprime.1.11.3.swf"; break; * }*/ string br = bitrate + "K " + videoType; if (!res.ContainsKey(br)) { MPUrlSourceFilter.RtmpUrl rtmpUrl; if (spc == SouthParkCountry.World) { rtmpUrl = new MPUrlSourceFilter.RtmpUrl(@"rtmpe://viacommtvstrmfs.fplive.net:1935/viacommtvstrm"); int p = url.IndexOf("gsp.comedystor"); if (p >= 0) { rtmpUrl.PlayPath = "mp4:" + url.Substring(p); } } else { rtmpUrl = new MPUrlSourceFilter.RtmpUrl(url) { SwfVerify = swfUrl != null, SwfUrl = swfUrl } }; res.Add(br, rtmpUrl.ToString()); } } string subtitleText = null; if (enableSubtitles) { XmlNode sub = doc.SelectSingleNode("//transcript/typographic[@format='vtt' and @src]"); if (sub != null) { string url = sub.Attributes["src"].Value; if (!String.IsNullOrEmpty(url)) { subtitleText = Helpers.SubtitleUtils.Webvtt2SRT(GetWebData(url)); } } } return(new Tuple <Dictionary <string, string>, string>(res, subtitleText)); }
public override string GetVideoUrl(VideoInfo video) { String baseWebData = GetWebData(video.VideoUrl, forceUTF8: true); String episodeJS = GetWebData(PrimaUtil.episodeUrlJS, referer: video.VideoUrl, forceUTF8: true); baseWebData = HttpUtility.HtmlDecode(baseWebData); video.PlaybackOptions = new Dictionary <string, string>(); String baseRtmpUrl = String.Empty; String lqFileName = String.Empty; String hqFileName = String.Empty; String auth = String.Empty; String zone = String.Empty; Match match = Regex.Match(baseWebData, PrimaUtil.episodeLqFileNameFormat); if (match.Success) { lqFileName = match.Groups["lqFileName"].Value; } match = Regex.Match(baseWebData, PrimaUtil.episodeHqFileNameFormat); if (match.Success) { hqFileName = match.Groups["hqFileName"].Value; } match = Regex.Match(baseWebData, PrimaUtil.episodeZone); if (match.Success) { zone = match.Groups["zone"].Value; } int startIndex = episodeJS.IndexOf(PrimaUtil.episodeBaseUrlStart); if (startIndex >= 0) { int endIndex = episodeJS.IndexOf(PrimaUtil.episodeBaseUrlEnd, startIndex + PrimaUtil.episodeBaseUrlStart.Length); if (endIndex >= 0) { baseRtmpUrl = "rtmp" + episodeJS.Substring(startIndex + PrimaUtil.episodeBaseUrlStart.Length, endIndex - startIndex - PrimaUtil.episodeBaseUrlStart.Length).Replace("iprima_token", ""); } } startIndex = episodeJS.IndexOf(PrimaUtil.episodeAuthSectionStart); if (startIndex >= 0) { int endIndex = episodeJS.IndexOf(PrimaUtil.episodeAuthSectionEnd, startIndex + PrimaUtil.episodeAuthSectionStart.Length); if (endIndex >= 0) { String authSection = episodeJS.Substring(startIndex, endIndex - startIndex); while (true) { startIndex = authSection.IndexOf(PrimaUtil.episodeAuthStart); if (startIndex >= 0) { endIndex = authSection.IndexOf(PrimaUtil.episodeAuthEnd, startIndex + PrimaUtil.episodeAuthStart.Length); if (endIndex >= 0) { auth = authSection.Substring(startIndex + PrimaUtil.episodeAuthStart.Length, endIndex - startIndex - PrimaUtil.episodeAuthStart.Length); authSection = authSection.Substring(startIndex + PrimaUtil.episodeAuthStart.Length + auth.Length); } else { break; } } else { break; } } } } if ((!String.IsNullOrEmpty(auth)) && (!(String.IsNullOrEmpty(lqFileName) || String.IsNullOrEmpty(hqFileName) || String.IsNullOrEmpty(baseRtmpUrl)))) { String app = String.Format("iprima_token{0}?auth={1}", zone == "0" ? "" : "_" + zone, auth); String tcUrl = String.Format("{0}{1}", baseRtmpUrl, app); if (!String.IsNullOrEmpty(lqFileName)) { String playPath = "mp4:" + lqFileName; OnlineVideos.MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(baseRtmpUrl) { App = app, TcUrl = tcUrl, PlayPath = playPath, SwfUrl = String.Format("http://embed.livebox.cz/iprimaplay/flash/LiveboxPlayer.swf?nocache={0}", (UInt64)((DateTime.Now - new DateTime(1970, 1, 1)).TotalMilliseconds)), PageUrl = video.VideoUrl }; video.PlaybackOptions.Add("Low quality", rtmpUrl.ToString()); } if (!String.IsNullOrEmpty(hqFileName)) { String playPath = "mp4:" + hqFileName; OnlineVideos.MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(baseRtmpUrl) { App = app, TcUrl = tcUrl, PlayPath = playPath, SwfUrl = String.Format("http://embed.livebox.cz/iprimaplay/flash/LiveboxPlayer.swf?nocache={0}", (UInt64)((DateTime.Now - new DateTime(1970, 1, 1)).TotalMilliseconds)), PageUrl = video.VideoUrl }; video.PlaybackOptions.Add("High quality", rtmpUrl.ToString()); } } else { Match flashVarsStart = Regex.Match(baseWebData, PrimaUtil.flashVarsStartRegex); if (flashVarsStart.Success) { int end = baseWebData.IndexOf(PrimaUtil.flashVarsEnd, flashVarsStart.Index); if (end > 0) { baseWebData = baseWebData.Substring(flashVarsStart.Index, end - flashVarsStart.Index); Match idMatch = Regex.Match(baseWebData, PrimaUtil.idRegex); Match cdnLqMatch = Regex.Match(baseWebData, PrimaUtil.cdnLqRegex); Match cdnHqMatch = Regex.Match(baseWebData, PrimaUtil.cdnHqRegex); String id = (idMatch.Success) ? idMatch.Groups["id"].Value : String.Empty; String cdnLq = (cdnLqMatch.Success) ? cdnLqMatch.Groups["cdnLQ"].Value : String.Empty; String cdnHq = (cdnHqMatch.Success) ? cdnHqMatch.Groups["cdnHQ"].Value : String.Empty; if ((!String.IsNullOrEmpty(cdnLq)) && (!String.IsNullOrEmpty(cdnHq))) { // we got low and high quality String lowQualityUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnLq)); String highQualityUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnHq)); video.PlaybackOptions = new Dictionary <string, string>(); video.PlaybackOptions.Add("Low quality", lowQualityUrl); video.PlaybackOptions.Add("High quality", highQualityUrl); } else if (!String.IsNullOrEmpty(cdnLq)) { video.VideoUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnLq)); } else if (!String.IsNullOrEmpty(cdnHq)) { video.VideoUrl = WebCache.Instance.GetRedirectedUrl(String.Format(PrimaUtil.videoUrlFormat, cdnHq)); } } } } if (video.PlaybackOptions != null && video.PlaybackOptions.Count > 0) { var enumer = video.PlaybackOptions.GetEnumerator(); enumer.MoveNext(); return(enumer.Current.Value); } return(video.VideoUrl); }
/// <summary> /// The default streaming from laola1.tv /// /// The stream starts correctly, but fails after some time for an unknown reason. /// </summary> /// <param name="video">Video object</param> /// <param name="playkey1">Playkey1 for this video</param> /// <param name="playkey2">Playkey2 for this video</param> /// <returns>Url for streaming</returns> private string GetDefaultStreamingUrl(VideoInfo video, string data) { Match c = regEx_GetPlaykeys.Match(data); if (c.Success) { String playkey1 = c.Groups["playkey1"].Value; String playkey2 = c.Groups["playkey2"].Value; String flashPlayer = c.Groups["flashplayer"].Value + ".swf"; String flashVersion = c.Groups["flashversion"].Value; String playData = GetWebData(String.Format(PLAYDATA_URL, playkey1, playkey2)); Match c2 = regEx_GetVideoInfo.Match(playData); bool videoQualityFound = false; while (c2.Success) { String server = c2.Groups["server"].Value; String path = c2.Groups["path"].Value; String streamQuality = c2.Groups["quality"].Value.Trim(); if (String.Compare(streamQuality, videoQuality.ToString(), true) == 0) { videoQualityFound = false; String accessData = GetWebData(String.Format(ACCESSDATA_URL_LIVE, playkey1, streamQuality)); Match c3 = regEx_GetAuthLive.Match(accessData); String servertype = c2.Groups["servertype"].Value; ; String auth = null; String aifp = null; String stream = null; String url = null; if (c3.Success) { auth = c3.Groups["auth"].Value; auth = auth.Replace("amp;", ""); aifp = c3.Groups["aifp"].Value; stream = c3.Groups["stream"].Value; url = c3.Groups["url"].Value; c3 = c3.NextMatch(); } else { Log.Warn("Couldn't parse " + accessData); } String ip = null; String identData = GetWebData(String.Format(IDENT_URL, server)); Match c4 = regEx_GetIp.Match(identData); if (c4.Success) { ip = c4.Groups["ip"].Value; c4 = c4.NextMatch(); } else { Log.Warn("Couldn't parse " + identData); } String rtmpUrl = String.Format("rtmp://{0}:1935/{1}?_fcs_vhost={2}/{3}?auth={4}&p=1&e={5}&u=&t=livevideo&l=&a=&aifp={6}", ip, servertype, url, stream, auth, playkey1, aifp); MPUrlSourceFilter.RtmpUrl resultUrl = new MPUrlSourceFilter.RtmpUrl(rtmpUrl); //resultUrl.FlashVersion = flashVersion; resultUrl.Live = true; resultUrl.PageUrl = video.VideoUrl; resultUrl.SwfUrl = flashPlayer; //TODO: I need the mp4, otherwise the stream isn't found, check if there are other formats than mp4 on laola1.tv resultUrl.PlayPath = "mp4:" + stream; //Log.Info("Playback Url: " + playpath); return resultUrl.ToString(); } c2 = c2.NextMatch(); } if (!videoQualityFound) { //this shouldn't happen, maybe the site has added/removed video qualities Log.Warn("Couldn't find the video stream with quality " + videoQuality.ToString()); } } return null; }
/// <summary> /// Get playback url for archived video items (VOD) /// </summary> /// <param name="video">Video object</param> /// <returns>Playback url</returns> private string getVideoArchiveUrl(VideoInfo video) { String data = GetWebData(video.VideoUrl); Match c = regEx_GetPlaykeys.Match(data); while (c.Success) { String playkey1 = c.Groups["playkey1"].Value; String playkey2 = c.Groups["playkey2"].Value; String flashplayer = c.Groups["flashplayer"].Value + ".swf"; String flashVersion = c.Groups["flashversion"].Value; String playData = GetWebData(String.Format(PLAYDATA_URL, playkey1, playkey2)); Match c2 = regEx_GetVideoInfo.Match(playData); bool videoQualityFound = false; while (c2.Success) { String server = c2.Groups["server"].Value; String path = c2.Groups["path"].Value; String streamQuality = c2.Groups["quality"].Value.Trim(); if (String.Compare(streamQuality, videoQuality.ToString(), true) == 0) { videoQualityFound = true; String accessData = GetWebData(String.Format(ACCESSDATA_URL_ARCHIVE, playkey1, streamQuality)); Match c3 = regEx_GetAuthArchive.Match(accessData); String servertype = c2.Groups["servertype"].Value; ; String auth = null; String aifp = null; String stream = null; if (c3.Success) { auth = c3.Groups["auth"].Value; auth = auth.Replace("amp;", ""); auth = auth.Replace("e=", "e=" + playkey1); aifp = c3.Groups["aifp"].Value; stream = c3.Groups["stream"].Value; c3 = c3.NextMatch(); } else { Log.Warn("Couldn't parse " + accessData); } String ip = null; String identData = GetWebData(String.Format(IDENT_URL, server)); Match c4 = regEx_GetIp.Match(identData); if (c4.Success) { ip = c4.Groups["ip"].Value; c4 = c4.NextMatch(); } String url = String.Format("rtmp://{0}:1935/{1}?_fcs_vhost={2}&auth={3}&aifp={4}&slist={5}", ip, servertype, server, auth, aifp, stream); MPUrlSourceFilter.RtmpUrl resultUrl = new MPUrlSourceFilter.RtmpUrl(url); resultUrl.FlashVersion = flashVersion; resultUrl.Live = false; resultUrl.PageUrl = video.VideoUrl; resultUrl.SwfUrl = flashplayer; if (stream.EndsWith(".mp4")) { //for videos where the returned stream ends with .mp4, the laola1.tv server wants a play command like //play('mp4:77154/flash/2011/volleyball/CEV_CL/111215_innsbruck_macerata_cut_high.mp4') resultUrl.PlayPath = "mp4:" + stream; } else { resultUrl.PlayPath = stream; } return resultUrl.ToString(); } c2 = c2.NextMatch(); } if (!videoQualityFound) { //this shouldn't happen, maybe the site has added/removed video qualities Log.Warn("Couldn't find the video stream with quality " + videoQuality.ToString()); } } //something has gone wrong -> return null return null; }
public override String GetVideoUrl(VideoInfo video) { string rtmpUrl = @"rtmp://abcondemandfs.fplive.net:1935/abcondemand"; string result = video.VideoUrl; // look for thumbnail Match episodeMatch = thumbnailRegex.Match(result); if (episodeMatch.Success) { string episode = episodeMatch.Groups["episode"].Value; Log.Debug(@"episode found: {0}", episode); bool hasLowResolution = video.VideoUrl.Contains(@"extreme-makeover-home-edition"); // convert thumbnail URL to the playPath (episode has to be lower-case) string playPath = String.Format( hasLowResolution ? @"mp4:/abcvideo/video_fep/mov/{0}_576x432_700.mov" : @"mp4:/abcvideo/video_fep/mov/{0}_768x432_700.mov", episode.ToLower()); Log.Debug(@"playPath: {0}", playPath); result = new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = playPath }.ToString(); Log.Debug(@"Resulting MPUrl: {0}", result); } else { // start with empty result result = string.Empty; // find the conviva content Log.Warn(@"Could not extract RTMP Url from Thumbnail Url: {0}. Reverting to conviva content", result); video.PlaybackOptions = new Dictionary <string, string>(); // keep track of bitrates and URLs Dictionary <int, string> urlsDictionary = new Dictionary <int, string>(); // find the conviva content // split on / string[] parts = ((string)video.Other).Split('/'); string convivaId = parts[parts.Length - 2]; // 2nd last part string convivaUrl = String.Format(@"http://cdn.abc.go.com/vp2/ws/s/contents/2003/utils/video/mov/13/9024/{0}/432?v=06000007_3", convivaId); string webData = GetWebData(convivaUrl); XmlDocument xml = new XmlDocument(); xml.LoadXml(webData); foreach (XmlNode node in xml.SelectNodes("//videos/video")) { string playPath = node.Attributes["src"].Value; // do not bother unless src is non-empty if (string.IsNullOrEmpty(playPath)) { continue; } Log.Debug(@"Found video playPath: {0}", playPath); int bitrate = int.Parse(node.Attributes["bitrate"].Value); urlsDictionary.Add(bitrate, new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = playPath }.ToString()); } // 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); // return last URL as the default (will be the highest bitrate) result = item.Value; } } return(result); }
public static string createRtmpUrl(string url) { string result = url; // cannot use GetWebData to figure out VideoUrl as the URL responds with // HTTP/1.1 302 Found // with a Location header containing the rtmp:// URL HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.AllowAutoRedirect = false; Log.Debug(@"Making manual HttpWebRequest for {0}", url); HttpWebResponse response = (HttpWebResponse) request.GetResponse(); if (response.StatusCode == HttpStatusCode.Redirect) { // retrieve the RTMP URL from the Location header string rtmpUrlFromHeader = response.GetResponseHeader("Location"); Log.Debug(@"RTMP URL from header: {0}", rtmpUrlFromHeader); // split on <break> string[] pathParts = rtmpUrlFromHeader.Split(new string[] { "<break>" }, StringSplitOptions.None); string host = pathParts[0]; string playPath = pathParts[1]; if (host.StartsWith("{switch:none}{manifest:none}")) { // Handle URLs of form {switch:none}{manifest:none}rtmp://cp209208.edgefcs.net/ondemand/?auth=daFbRa0aldEcad_bsd7cXawd5dId3bkdjdw-btCbTQ-c0-oknqnHronA&aifp=v0001&slist=287/267/<break>287/267/Arctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.mp4{manifest:f4m}http://mobilehls-vh.akamaihd.net/z/prodVideo/entertainment/287%2F267%2FArctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.csmil/manifest.f4m?hdnea=st=1399855948~exp=1399856278~acl=/z/*~id={nonce}~hmac=UNRECOGNIZED_TOKEN_TYPE{manifest:m3u}http://mobilehls-vh.akamaihd.net/i/prodVideo/entertainment/287%2F267%2FArctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.csmil/master.m3u8?hdnea=st=1399855948~exp=1399856278~acl=/i/*~id={nonce}~hmac=UNRECOGNIZED_TOKEN_TYPE{manifest}{switch:http}http://progressive.cbc.ca/prodVideo/entertainment/287/267/Arctic_Air_S03E12_09_00_00_2014-04-08_640x360_1200kbps.mp4?hdnea=st=1399855948~exp=1399856278~acl=/*~hmac=UNRECOGNIZED_TOKEN_TYPE{switch} host = pathParts[0].Substring(28); playPath = pathParts[1].Substring(0, pathParts[1].IndexOf("{manifest")); } if (playPath.EndsWith(@".mp4") && !playPath.StartsWith(@"mp4:")) { // prepend with mp4: playPath = @"mp4:" + playPath; } else if (playPath.EndsWith(@".flv")) { // strip extension playPath = playPath.Substring(0, playPath.Length - 4); } Log.Debug(@"Host: {0}, PlayPath: {1}", host, playPath); result = new MPUrlSourceFilter.RtmpUrl(host) { PlayPath = playPath }.ToString(); } return result; }
public override String GetVideoUrl(VideoInfo video) { video.PlaybackOptions = new Dictionary <string, string>(); var doc = GetWebData <HtmlDocument>(video.VideoUrl); var vpDiv = doc.DocumentNode.Descendants("div").FirstOrDefault(s => !string.IsNullOrEmpty(s.GetAttributeValue("arte_vp_url_oembed", ""))); if (vpDiv == null) { throw new OnlineVideosException("Video nicht verfügbar!"); } var json = GetWebData <JObject>(vpDiv.GetAttributeValue("arte_vp_url_oembed", "")); HtmlDocument iframe = new HtmlAgilityPack.HtmlDocument(); iframe.LoadHtml(json["html"].ToString()); json = GetWebData <JObject>(HttpUtility.ParseQueryString(new Uri(iframe.DocumentNode.FirstChild.GetAttributeValue("src", "")).Query)["json_url"]); foreach (var quality in json["videoJsonPlayer"]["VSR"]) { string qualityName = string.Format("{0} | {1} | {2} ({3}x{4} - {5} kbps)", (quality.First.Value <string>("versionShortLibelle") ?? "").PadRight(3), quality.First.Value <string>("mediaType").PadRight(4), quality.First.Value <string>("quality"), quality.First.Value <string>("width"), quality.First.Value <string>("height"), quality.First.Value <string>("bitrate")); if (quality.First.Value <string>("mediaType") == "rtmp") { if (!video.PlaybackOptions.ContainsKey(qualityName)) { string host = quality.First.Value <string>("streamer"); string file = quality.First.Value <string>("url"); string playbackUrl = new MPUrlSourceFilter.RtmpUrl(host) { TcUrl = host, PlayPath = "mp4:" + file }.ToString(); video.PlaybackOptions.Add(qualityName, playbackUrl); } } else if (quality.First.Value <string>("mediaType") == "mp4") { string file = quality.First.Value <string>("url"); video.PlaybackOptions.Add(qualityName, file); } /*else if (quality.First.Value<string>("mediaType") == "hls") * { * string file = quality.First.Value<string>("url"); * video.PlaybackOptions.Add(qualityName, file); * // todo -> resolve m3u8 * }*/ } var bestOption = video.PlaybackOptions.FirstOrDefault(q => q.Key.Contains(videoQuality.ToString())).Value; if (string.IsNullOrEmpty(bestOption)) { return(video.PlaybackOptions.FirstOrDefault().Value); } return(bestOption); }
/// <summary> /// Get playback url for archived video items (VOD) /// </summary> /// <param name="video">Video object</param> /// <returns>Playback url</returns> private string getVideoArchiveUrl(VideoInfo video) { String data = GetWebData(video.VideoUrl); Match c = regEx_GetPlaykeys.Match(data); while (c.Success) { String playkey1 = c.Groups["playkey1"].Value; String playkey2 = c.Groups["playkey2"].Value; String flashplayer = c.Groups["flashplayer"].Value + ".swf"; String flashVersion = c.Groups["flashversion"].Value; String playData = GetWebData(String.Format(PLAYDATA_URL, playkey1, playkey2)); Match c2 = regEx_GetVideoInfo.Match(playData); bool videoQualityFound = false; while (c2.Success) { String server = c2.Groups["server"].Value; String path = c2.Groups["path"].Value; String streamQuality = c2.Groups["quality"].Value.Trim(); if (String.Compare(streamQuality, videoQuality.ToString(), true) == 0) { videoQualityFound = true; String accessData = GetWebData(String.Format(ACCESSDATA_URL_ARCHIVE, playkey1, streamQuality)); Match c3 = regEx_GetAuthArchive.Match(accessData); String servertype = c2.Groups["servertype"].Value;; String auth = null; String aifp = null; String stream = null; if (c3.Success) { auth = c3.Groups["auth"].Value; auth = auth.Replace("amp;", ""); auth = auth.Replace("e=", "e=" + playkey1); aifp = c3.Groups["aifp"].Value; stream = c3.Groups["stream"].Value; c3 = c3.NextMatch(); } else { Log.Warn("Couldn't parse " + accessData); } String ip = null; String identData = GetWebData(String.Format(IDENT_URL, server)); Match c4 = regEx_GetIp.Match(identData); if (c4.Success) { ip = c4.Groups["ip"].Value; c4 = c4.NextMatch(); } String url = String.Format("rtmp://{0}:1935/{1}?_fcs_vhost={2}&auth={3}&aifp={4}&slist={5}", ip, servertype, server, auth, aifp, stream); MPUrlSourceFilter.RtmpUrl resultUrl = new MPUrlSourceFilter.RtmpUrl(url); resultUrl.FlashVersion = flashVersion; resultUrl.Live = false; resultUrl.PageUrl = video.VideoUrl; resultUrl.SwfUrl = flashplayer; if (stream.EndsWith(".mp4")) { //for videos where the returned stream ends with .mp4, the laola1.tv server wants a play command like //play('mp4:77154/flash/2011/volleyball/CEV_CL/111215_innsbruck_macerata_cut_high.mp4') resultUrl.PlayPath = "mp4:" + stream; } else { resultUrl.PlayPath = stream; } return(resultUrl.ToString()); } c2 = c2.NextMatch(); } if (!videoQualityFound) { //this shouldn't happen, maybe the site has added/removed video qualities Log.Warn("Couldn't find the video stream with quality " + videoQuality.ToString()); } } //something has gone wrong -> return null return(null); }
MPUrlSourceFilter.RtmpUrl getRTMPUrl(string naviXRTMPUrl) { MatchCollection matches = new Regex(@"\s+(tcUrl|app|playpath|swfUrl|pageUrl|swfVfy|live|timeout)\s*=\s*([^\s]*)", RegexOptions.IgnoreCase).Matches(naviXRTMPUrl); if (matches.Count < 1) return new MPUrlSourceFilter.RtmpUrl(naviXRTMPUrl); MPUrlSourceFilter.RtmpUrl url = new MPUrlSourceFilter.RtmpUrl(naviXRTMPUrl.Substring(0, matches[0].Index)); foreach (Match m in matches) { string val = m.Groups[2].Value; switch (m.Groups[1].Value.ToLower()) { case "tcurl": url.TcUrl = val; break; case "app": url.App = val; break; case "playpath": url.PlayPath = val; break; case "swfurl": url.SwfUrl = val; break; case "pageurl": url.PageUrl = val; break; case "swfvfy": if (val == "1" || val.ToLower() == "true") url.SwfVerify = true; break; case "live": if (val == "1" || val.ToLower() == "true") url.Live = true; break; } } return url; }
protected new string FillPlaybackOptions(VideoInfo video, AMFArray renditions, Match m) { video.PlaybackOptions = new Dictionary <string, string>(); foreach (AMFObject rendition in renditions.OrderBy(u => u.GetIntProperty("encodingRate"))) { string nm = String.Format("{0}x{1} {2}K", rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"), rendition.GetIntProperty("encodingRate") / 1024); string url = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL")); //"rtmp://brightcove.fcod.llnwd.net/a500/e1/uds/rtmp/ondemand/&mp4:102076681001/102076681001_986209826001_26930-20110610-122117.mp4&1368558000000&0aa762d184c16de09a21fe533394c3ea" if (url.StartsWith("rtmp")) { //tested with ztele string auth = String.Empty; if (url.Contains('?')) { auth = '?' + url.Split('?')[1]; } string[] parts = url.Split('&'); string rtmp = parts[0] + auth; //"rtmp://brightcove.fcod.llnwd.net/a500/e1/uds/rtmp/ondemand/" string playpath = parts[1].Split('?')[0] + auth; //"mp4:102076681001/102076681001_986209826001_26930-20110610-122117.mp4" if (url.IndexOf("edgefcs.net") != -1) { /*rtmpdump --rtmp "rtmp://cp150446.edgefcs.net/ondemand/&mp4:102076681001/102076681001_1506435728001_66034-20120314-120404.mp4?__nn__=1497926354001&slist=102076681001/&auth=daEbVc2bZd2bpcZdcbxbVdld6cEdWcpb4dC-brKM2q-bWG-rnBBssvx_ABAo_DDCB_GuD&aifp=bcosuds" --app="ondemand?__nn__=1497926354001&slist=102076681001/&auth=daEbVc2bZd2bpcZdcbxbVdld6cEdWcpb4dC-brKM2q-bWG-rnBBssvx_ABAo_DDCB_GuD&aifp=bcosuds&videoId=1506302142001&lineUpId=&pubId=102076681001&playerId=2202962695001" --swfUrl="http://admin.brightcove.com/viewer/us20121213.1025/federatedVideoUI/BrightcovePlayer.swf?uid=1355746343102" --playpath="mp4:102076681001/102076681001_1506435728001_66034-20120314-120404.mp4?__nn__=1497926354001&slist=102076681001/&auth=daEbVc2bZd2bpcZdcbxbVdld6cEdWcpb4dC-brKM2q-bWG-rnBBssvx_ABAo_DDCB_GuD&aifp=bcosuds&videoId=1506302142001" --pageUrl="http://www.eitb.tv/es/#/video/1506302142001" -o "Aduriz-La_cocina_de_las_palabras_-_Aduriz-Hitzen_sukaldea-.mp4"*/ url = new MPUrlSourceFilter.RtmpUrl(rtmp) { PlayPath = playpath }.ToString(); } else { /* * rtmpdump --rtmp "rtmp://brightcove.fcod.llnwd.net/a500/e1/uds/rtmp/ondemand/&mp4:102076681001/102076681001_986252687001_26930-20110610-122117.mp4&1368558000000&0aa762d184c16de09a21fe533394c3ea" --app="a500/e1/uds/rtmp/ondemand?videoId=986121629001&lineUpId=&pubId=102076681001&playerId=2202962695001" --swfUrl="http://admin.brightcove.com/viewer/us20121218.1107/federatedVideoUI/BrightcovePlayer.swf?uid=1355158765470" --playpath="mp4:102076681001/102076681001_986252687001_26930-20110610-122117.mp4?videoId=986121629001&lineUpId=&pubId=102076681001&playerId=2202962695001" --pageUrl="http://www.eitb.tv/es/#/video/986121629001" -C "B:0" -C "S:mp4:102076681001/102076681001_986252687001_26930-20110610-122117.mp4&1368558000000&0aa762d184c16de09a21fe533394c3ea" -o "Sukalde_maisuak_-_Aduriz-Hitzen_sukaldea-.mp4" */ string cadena = url.Substring(url.IndexOf(".net/") + 5); cadena = cadena.Remove(cadena.IndexOf("/&")); cadena += "?videoId=" + video.VideoUrl.Substring(video.VideoUrl.LastIndexOf("/") + 1) + "&lineUpId=&pubId=" + array4 + "&playerId=" + m.Groups["experienceId"].Value; RtmpUrl rtmpUrl = new RtmpUrl(rtmp) { PlayPath = playpath, //App = "a500/e1/uds/rtmp/ondemand?videoId=986121629001&lineUpId=&pubId=102076681001&playerId=2202962695001" App = cadena }; RtmpBooleanArbitraryData p1 = new RtmpBooleanArbitraryData(false); RtmpStringArbitraryData p2 = new RtmpStringArbitraryData(parts[1] + "&" + parts[2] + "&" + parts[3]); rtmpUrl.ArbitraryData.Add(p1); rtmpUrl.ArbitraryData.Add(p2); url = rtmpUrl.ToString(); } } video.PlaybackOptions.Add(nm, url); } if (video.PlaybackOptions.Count == 0) { return(""); // if no match, return empty url -> error } else if (video.PlaybackOptions.Count == 1) { string resultUrl = video.PlaybackOptions.Last().Value; video.PlaybackOptions = null; // only one url found, PlaybackOptions not needed return(resultUrl); } else { return(video.PlaybackOptions.Last().Value); } }
public override string GetVideoUrl(VideoInfo video) { JObject data = GetWebData<JObject>(video.VideoUrl); string playstr = data["streams"]["medium"].Value<string>(); if (playstr.ToLower().StartsWith("rtmp")) { int mp4IndexFlash = playstr.ToLower().IndexOf("mp4:"); int mp4Index = mp4IndexFlash >= 0 ? mp4IndexFlash : playstr.ToLower().IndexOf("flv:"); if (mp4Index > 0) { playstr = new MPUrlSourceFilter.RtmpUrl(playstr.Substring(0, mp4Index)) { PlayPath = playstr.Substring(mp4Index), SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } else { playstr = new MPUrlSourceFilter.RtmpUrl(playstr) { SwfUrl = redirectedSwfUrl, SwfVerify = true }.ToString(); } } else if (playstr.ToLower().EndsWith(".f4m")) { playstr += "?hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } else if (playstr.ToLower().Contains(".f4m?")) { playstr += "&hdcore=3.3.0" + "&g=" + OnlineVideos.Sites.Utils.HelperUtils.GetRandomChars(12); } if (!string.IsNullOrEmpty(video.SubtitleUrl) && string.IsNullOrEmpty(video.SubtitleText)) { video.SubtitleText = GetSubtitle(video.SubtitleUrl); } return playstr; }
/// <summary> /// The default streaming from laola1.tv /// /// The stream starts correctly, but fails after some time for an unknown reason. /// </summary> /// <param name="video">Video object</param> /// <param name="playkey1">Playkey1 for this video</param> /// <param name="playkey2">Playkey2 for this video</param> /// <returns>Url for streaming</returns> private string GetDefaultStreamingUrl(VideoInfo video, string data) { Match c = regEx_GetPlaykeys.Match(data); if (c.Success) { String playkey1 = c.Groups["playkey1"].Value; String playkey2 = c.Groups["playkey2"].Value; String flashPlayer = c.Groups["flashplayer"].Value + ".swf"; String flashVersion = c.Groups["flashversion"].Value; String playData = GetWebData(String.Format(PLAYDATA_URL, playkey1, playkey2)); Match c2 = regEx_GetVideoInfo.Match(playData); bool videoQualityFound = false; while (c2.Success) { String server = c2.Groups["server"].Value; String path = c2.Groups["path"].Value; String streamQuality = c2.Groups["quality"].Value.Trim(); if (String.Compare(streamQuality, videoQuality.ToString(), true) == 0) { videoQualityFound = false; String accessData = GetWebData(String.Format(ACCESSDATA_URL_LIVE, playkey1, streamQuality)); Match c3 = regEx_GetAuthLive.Match(accessData); String servertype = c2.Groups["servertype"].Value;; String auth = null; String aifp = null; String stream = null; String url = null; if (c3.Success) { auth = c3.Groups["auth"].Value; auth = auth.Replace("amp;", ""); aifp = c3.Groups["aifp"].Value; stream = c3.Groups["stream"].Value; url = c3.Groups["url"].Value; c3 = c3.NextMatch(); } else { Log.Warn("Couldn't parse " + accessData); } String ip = null; String identData = GetWebData(String.Format(IDENT_URL, server)); Match c4 = regEx_GetIp.Match(identData); if (c4.Success) { ip = c4.Groups["ip"].Value; c4 = c4.NextMatch(); } else { Log.Warn("Couldn't parse " + identData); } String rtmpUrl = String.Format("rtmp://{0}:1935/{1}?_fcs_vhost={2}/{3}?auth={4}&p=1&e={5}&u=&t=livevideo&l=&a=&aifp={6}", ip, servertype, url, stream, auth, playkey1, aifp); MPUrlSourceFilter.RtmpUrl resultUrl = new MPUrlSourceFilter.RtmpUrl(rtmpUrl); //resultUrl.FlashVersion = flashVersion; resultUrl.Live = true; resultUrl.PageUrl = video.VideoUrl; resultUrl.SwfUrl = flashPlayer; //TODO: I need the mp4, otherwise the stream isn't found, check if there are other formats than mp4 on laola1.tv resultUrl.PlayPath = "mp4:" + stream; //Log.Info("Playback Url: " + playpath); return(resultUrl.ToString()); } c2 = c2.NextMatch(); } if (!videoQualityFound) { //this shouldn't happen, maybe the site has added/removed video qualities Log.Warn("Couldn't find the video stream with quality " + videoQuality.ToString()); } } return(null); }
public override String GetVideoUrl(VideoInfo video) { if (video.VideoUrl.StartsWith("http://daserste_live-lh.akamaihd.net")) return video.VideoUrl; else { var baseDoc = GetWebData<HtmlDocument>(video.VideoUrl); var mediaDiv = baseDoc.DocumentNode.Descendants("div").FirstOrDefault(div => div.GetAttributeValue("data-ctrl-player", "") != ""); if (mediaDiv != null) { var configUrl = new Uri(new Uri(video.VideoUrl), JObject.Parse(HttpUtility.HtmlDecode(mediaDiv.GetAttributeValue("data-ctrl-player", ""))).Value<string>("mcUrl")).AbsoluteUri; var mediaJson = GetWebData<JObject>(configUrl); video.PlaybackOptions = new Dictionary<string, string>(); foreach (var media in mediaJson["_mediaArray"].SelectMany(m => m["_mediaStreamArray"])) { var quali = ((JValue)media["_quality"]).Type == JTokenType.Integer ? ((VideoQuality)media.Value<int>("_quality")).ToString() : "HD"; if (!media.Value<bool>("flashUrl")) { var url = media["_stream"] is JArray ? media["_stream"][0].Value<string>() : media.Value<string>("_stream"); if (!url.EndsWith(".smil")) { if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) { if (url.EndsWith("f4m")) url += "?g=" + Helpers.StringUtils.GetRandomLetters(12) + "&hdcore=3.3.0"; video.PlaybackOptions[quali] = url; } } } else { if (mediaJson.Value<bool>("_isLive")) { var server = media.Value<string>("_server"); var stream = media.Value<string>("_stream"); string url = ""; if (string.IsNullOrEmpty(stream)) { string guessedStream = server.Substring(server.LastIndexOf('/') + 1); url = new MPUrlSourceFilter.RtmpUrl(server) { Live = true, LiveStream = true, Subscribe = guessedStream, PageUrl = video.VideoUrl }.ToString(); } else if (stream.Contains('?')) { var tcUrl = server.TrimEnd('/') + stream.Substring(stream.IndexOf('?')); var app = new Uri(server).AbsolutePath.Trim('/') + stream.Substring(stream.IndexOf('?')); var playPath = stream; url = new MPUrlSourceFilter.RtmpUrl(tcUrl) { App = app, PlayPath = playPath, Live = true, PageUrl = video.VideoUrl, Subscribe = playPath }.ToString(); } else { url = new MPUrlSourceFilter.RtmpUrl(server + "/" + stream) { Live = true, LiveStream = true, Subscribe = stream, PageUrl = video.VideoUrl }.ToString(); } if (!video.PlaybackOptions.ContainsKey(quali)) video.PlaybackOptions[quali] = url; } } } } } return video.PlaybackOptions.Select(p => p.Value).LastOrDefault(); }
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>(); XmlDocument xml = GetWebData <XmlDocument>(video.VideoUrl); Log.Debug(@"SMIL loaded"); XmlNamespaceManager nsmRequest = new XmlNamespaceManager(xml.NameTable); nsmRequest.AddNamespace("a", @"http://www.w3.org/2001/SMIL20/Language"); XmlNode metaBase = xml.SelectSingleNode(@"//a:meta", nsmRequest); string metaBaseValue = metaBase.Attributes["base"].Value; // base URL may be stored in the base attribute of <meta> tag string baseRtmp = metaBaseValue.StartsWith("rtmp") ? metaBaseValue : String.Empty; foreach (XmlNode node in xml.SelectNodes("//a:switch/a:video", nsmRequest)) { int bitrate = int.Parse(node.Attributes["system-bitrate"].Value); // skip bitrate is zero if (bitrate == 0) { continue; } string url = node.Attributes["src"].Value; // skip if advertisement if (url.StartsWith("pfadx")) { continue; } if (!string.IsNullOrEmpty(baseRtmp)) { // prefix url with base (from <meta> tag) and artifical <break> url = baseRtmp + @"<break>" + url; } Log.Debug(@"bitrate: {0}, url: {1}", bitrate / 1000, url); if (url.StartsWith("rtmp")) { Match rtmpUrlMatch = rtmpUrlRegex.Match(url); if (rtmpUrlMatch.Success && !urlsDictionary.ContainsKey(bitrate / 1000)) { string host = rtmpUrlMatch.Groups["host"].Value; string playPath = rtmpUrlMatch.Groups["playPath"].Value; if (playPath.EndsWith(@".mp4") && !playPath.StartsWith(@"mp4:")) { // prepend with mp4: playPath = @"mp4:" + playPath; } else if (playPath.EndsWith(@".flv")) { // strip extension playPath = playPath.Substring(0, playPath.Length - 4); } Log.Debug(@"Host: {0}, PlayPath: {1}", host, playPath); MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(host) { PlayPath = playPath }; if (!string.IsNullOrEmpty(swfUrl)) { rtmpUrl.SwfUrl = swfUrl; rtmpUrl.SwfVerify = true; } urlsDictionary.Add(bitrate / 1000, rtmpUrl.ToString()); } } } // 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); // 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:ref", nsmRequest); if (geolockReference != null) { Log.Error(@"You are not in a geographic region that has access to this content."); result = string.Format(@"{0}{1}", metaBaseValue, geolockReference.Attributes["src"].Value); } } return(result); }
public override string GetVideoUrl(VideoInfo video) { string result = string.Empty; string data = GetWebData(string.Format(@"{0}{1}", baseUrl, tokenUrl)); if (!string.IsNullOrEmpty(data)) { Match tokenMatch = tokenRegex.Match(data); if (tokenMatch.Success) { data = GetWebData(video.VideoUrl); string token = HttpUtility.UrlDecode(tokenMatch.Groups["token"].Value); string url = string.Format(rtmpUrlFormat, token); if (!string.IsNullOrEmpty(data)) { Match filenameMatch = filenameRegex.Match(data); if (filenameMatch.Success) { string playPath = string.Format(playPathFormat, filenameMatch.Groups["filename"].Value); result = new MPUrlSourceFilter.RtmpUrl(url) { PlayPath = playPath }.ToString(); } } } } return result; }
public override String GetVideoUrl(VideoInfo video) { video.PlaybackOptions = new Dictionary<string, string>(); var doc = GetWebData<HtmlDocument>(video.VideoUrl); var vpDiv = doc.DocumentNode.Descendants("div").FirstOrDefault(s => !string.IsNullOrEmpty(s.GetAttributeValue("arte_vp_url", ""))); if (vpDiv == null) throw new OnlineVideosException("Video nicht verfügbar!"); var jsonUrl = vpDiv.GetAttributeValue("arte_vp_url", ""); var json = GetWebData<JObject>(jsonUrl); foreach (var quality in json["videoJsonPlayer"]["VSR"]) { string qualityName = string.Format("{0} | {1} | {2}", (quality.First.Value<string>("versionShortLibelle") ?? "").PadRight(3), quality.First.Value<string>("mediaType").PadRight(4), quality.First.Value<string>("quality")); if (quality.First.Value<string>("mediaType") == "rtmp") { if (!video.PlaybackOptions.ContainsKey(qualityName)) { string host = quality.First.Value<string>("streamer"); string file = quality.First.Value<string>("url"); string playbackUrl = new MPUrlSourceFilter.RtmpUrl(host) { TcUrl = host, PlayPath = "mp4:" + file }.ToString(); video.PlaybackOptions.Add(qualityName, playbackUrl); } } else if (quality.First.Value<string>("mediaType") == "mp4") { string file = quality.First.Value<string>("url"); video.PlaybackOptions.Add(qualityName, file); } /*else if (quality.First.Value<string>("mediaType") == "hls") { string file = quality.First.Value<string>("url"); video.PlaybackOptions.Add(qualityName, file); // todo -> resolve m3u8 }*/ } var bestOption = video.PlaybackOptions.FirstOrDefault(q => q.Key.Contains(videoQuality.ToString())).Value; if (string.IsNullOrEmpty(bestOption)) return video.PlaybackOptions.FirstOrDefault().Value; return bestOption; }
public override String GetVideoUrl(VideoInfo video) { string webData = HttpUtility.UrlDecode(GetWebData(video.VideoUrl)); string url = string.Empty; //TODO: Fix flashdrm Videos if (webData.Contains("flashdrm_url")) { url = Regex.Match(webData, @"flashdrm_url"":""(?<Value>[^""]+)""").Groups["Value"].Value; url = HttpUtility.UrlDecode(url); while (url.Contains("\\/")) { url = url.Replace("\\/", "/"); } url = url.Replace("rtmpte", "rtmpe"); url = url.Replace(".net", ".net:1935"); url = new MPUrlSourceFilter.RtmpUrl(url) { SwfUrl = "http://www.prosieben.de/static/videoplayer/swf/HybridPlayer.swf", SwfVerify = true }.ToString(); } else { string jsonData = Regex.Match(webData, @"SIMVideoPlayer.extract\(""json"",\s*""(?<json>.*?)""\s*\);", RegexOptions.Singleline).Groups["json"].Value; var json = JsonConvert.DeserializeObject <JObject>(Regex.Unescape(jsonData)); // try http mp4 file from id string clipId = json["categoryList"][0]["clipList"][0].Value <string>("id"); if (!string.IsNullOrEmpty(clipId)) { string link = WebCache.Instance.GetRedirectedUrl("http://www.prosieben.de/dynamic/h264/h264map/?ClipID=" + clipId); if (!string.IsNullOrEmpty(link)) { if (!link.Contains("not_available")) { url = link; } } } if (string.IsNullOrEmpty(url)) { var dl = json.Descendants().Where(j => j.Type == JTokenType.Property && ((JProperty)j).Name == "downloadFilename"); foreach (var prop in dl) { string filename = (prop as JProperty).Value.ToString(); string geo = (prop.Parent as JObject).Value <string>("geoblocking"); string geoblock = string.Empty; if (string.IsNullOrEmpty(geo)) { geoblock = "geo_d_at_ch/"; } else if (geo.Contains("ww")) { geoblock = "geo_worldwide/"; } else if (geo.Contains("de_at_ch")) { geoblock = "geo_d_at_ch/"; } else { geoblock = "geo_d/"; } if (webData.Contains("flashSuffix") || filename.Contains(".mp4")) { url = rtmpBase + geoblock + /*"mp4:" +*/ filename; if (!url.EndsWith(".mp4")) { url = url + ".mp4"; } } else { url = rtmpBase + geoblock + filename; } } } } return(url); }
public override List <String> GetMultipleVideoUrls(VideoInfo video, bool inPlaylist = false) { JObject data = GetWebData <JObject>(video.GetOtherAsString()); video.PlaybackOptions.Clear(); JArray episodes = (JArray)data["episodes"]; JToken episode = episodes.FirstOrDefault(e => e["id"].ToString() == video.VideoUrl); IEnumerable <JToken> hlsStreams = episode["streams"].Where(s => s["format"].Value <string>().ToLower() == "ipad" && !s["drmProtected"].Value <bool>()); if (hlsStreams == null || hlsStreams.Count() == 0) { hlsStreams = episode["streams"].Where(s => s["format"].Value <string>().ToLower() == "iphone" && !s["drmProtected"].Value <bool>()); } if (hlsStreams != null && hlsStreams.Count() > 0) { try { string url = hlsStreams.First()["source"].Value <string>(); string m3u8 = GetWebData(url); Regex rgx = new Regex(@"WIDTH=(?<bitrate>\d+)[^c]*(?<url>[^\.]*\.m3u8)"); foreach (Match m in rgx.Matches(m3u8)) { video.PlaybackOptions.Add(m.Groups["bitrate"].Value.ToString(), Regex.Replace(url, @"([^/]*?.m3u8)", delegate(Match match) { return(m.Groups["url"].Value); })); } video.PlaybackOptions = video.PlaybackOptions.OrderByDescending(p => int.Parse(p.Key)).ToDictionary(kvp => ((int.Parse(kvp.Key) / 1000) + " kbps (HLS)"), kvp => kvp.Value); } catch { } } IEnumerable <JToken> streams = episode["streams"].Where(s => s["format"].Value <string>().ToLower() == "flash" && !s["drmProtected"].Value <bool>()); string streamBaseUrl = (string)episode["streamBaseUrl"]; Dictionary <string, string> rtmpD = new Dictionary <string, string>(); if (streamBaseUrl != null && streams != null && streams.Count() > 0) { foreach (JToken stream in streams) { MPUrlSourceFilter.RtmpUrl url = new MPUrlSourceFilter.RtmpUrl(streamBaseUrl) { SwfUrl = swfPlayer, SwfVerify = true, PlayPath = (string)stream["source"] }; rtmpD.Add(((int)stream["bitrate"] / 1000).ToString(), url.ToString()); } rtmpD = rtmpD.OrderByDescending(p => int.Parse(p.Key)).ToDictionary(kvp => (kvp.Key + " kbps (RTMP)"), kvp => kvp.Value); video.PlaybackOptions = video.PlaybackOptions.Concat(rtmpD).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); if (retrieveSubtitles && (bool)episode["hasSubtitle"]) { string subData = GetWebData(string.Format("{0}/subtitles/{1}", apiBaseUrl, episode["id"].ToString())); JArray subtitleJson = (JArray)JsonConvert.DeserializeObject(subData); video.SubtitleText = formatSubtitle(subtitleJson); } } string firsturl = video.PlaybackOptions.First().Value; if (inPlaylist) { video.PlaybackOptions.Clear(); } return(new List <string>() { firsturl }); }
public override String GetVideoUrl(VideoInfo video) { var baseDoc = WebCache.Instance.ReadAsHtmlDocument(video.VideoUrl); var mediaDiv = baseDoc.DocumentNode.Descendants("div").FirstOrDefault(div => div.GetAttributeValue("data-ctrl-player", "") != ""); string bestVideoQualityUrl = string.Empty; if (mediaDiv != null) { var configUrl = new Uri(new Uri(video.VideoUrl), JObject.Parse(HttpUtility.HtmlDecode(mediaDiv.GetAttributeValue("data-ctrl-player", ""))).Value <string>("mcUrl")).AbsoluteUri; var mediaJson = WebCache.Instance.ReadAs <JsonResponse>(configUrl); var playbackOptions = new HashSet <KeyValuePair <string, string> >(KeyValuePairComparer.KeyOrdinalIgnoreCase); int qualityNumber; foreach (var media in mediaJson.MediaArray.SelectMany(m => m.MediaStreamArray).Select(streamArray => new { Quality = int.TryParse(streamArray.Quality, out qualityNumber) ? ((VideoQuality)qualityNumber).ToString() : "HD", Url = streamArray.Stream is JArray ? ((JArray)streamArray.Stream).Values <string>().OrderByDescending(item => item, StringComparer.OrdinalIgnoreCase).First() : streamArray.Stream as string, Server = streamArray.Server }).Distinct()) { string url = media.Url; if (url.EndsWith(".smil")) { url = GetStreamUrlFromSmil(url); } if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute)) { if (Uri.IsWellFormedUriString(url, UriKind.Relative)) { var absoluteUri = new Uri(new Uri(video.VideoUrl), url); url = absoluteUri.ToString(); } if (url.Contains("master.m3u8")) { var newUrl = WebCache.Instance.GetRedirectedUrl(url); var m3u8Data = WebCache.Instance.ReadAsString(newUrl); var m3u8PlaybackOptions = HlsPlaylistParser.GetPlaybackOptions(m3u8Data, newUrl); playbackOptions.UnionWith(m3u8PlaybackOptions); bestVideoQualityUrl = m3u8PlaybackOptions.FirstOrDefault().Value; //Default, if m3u8 playlist cannot be collected, e.g. geoblocking } else { if (url.EndsWith("f4m")) { url += "?g=" + StringUtils.GetRandomLetters(12) + "&hdcore=3.8.0"; } playbackOptions.Add(new KeyValuePair <string, string>(media.Quality, url)); } } else if (mediaJson.IsLive) { url = string.Empty; if (string.IsNullOrEmpty(media.Url)) { string guessedStream = media.Server.Substring(media.Server.LastIndexOf('/') + 1); url = new MPUrlSourceFilter.RtmpUrl(media.Server) { Live = true, LiveStream = true, Subscribe = guessedStream, PageUrl = video.VideoUrl }.ToString(); } else if (media.Url.Contains('?')) { var tcUrl = media.Server.TrimEnd('/') + media.Url.Substring(media.Url.IndexOf('?')); var app = new Uri(media.Server).AbsolutePath.Trim('/') + media.Url.Substring(media.Url.IndexOf('?')); var playPath = media.Url; url = new MPUrlSourceFilter.RtmpUrl(tcUrl) { App = app, PlayPath = playPath, Live = true, PageUrl = video.VideoUrl, Subscribe = playPath }.ToString(); } else { url = new MPUrlSourceFilter.RtmpUrl(media.Server + "/" + media.Url) { Live = true, LiveStream = true, Subscribe = media.Url, PageUrl = video.VideoUrl }.ToString(); } playbackOptions.Add(new KeyValuePair <string, string>(media.Quality, url)); } } video.PlaybackOptions = playbackOptions.ToDictionary(e => e.Key, e => e.Value); } return(!string.IsNullOrWhiteSpace(bestVideoQualityUrl) ? bestVideoQualityUrl : video.PlaybackOptions.LastOrDefault().Value); }
public override List<String> GetMultipleVideoUrls(VideoInfo video, bool inPlaylist = false) { JObject data = GetWebData<JObject>(video.GetOtherAsString()); video.PlaybackOptions.Clear(); JArray episodes = (JArray)data["episodes"]; JToken episode = episodes.FirstOrDefault(e => e["id"].ToString() == video.VideoUrl); IEnumerable<JToken> hlsStreams = episode["streams"].Where(s => s["format"].Value<string>().ToLower() == "ipad" && !s["drmProtected"].Value<bool>()); if (hlsStreams == null || hlsStreams.Count() == 0) hlsStreams = episode["streams"].Where(s => s["format"].Value<string>().ToLower() == "iphone" && !s["drmProtected"].Value<bool>()); if (hlsStreams != null && hlsStreams.Count() > 0) { try { string url = hlsStreams.First()["source"].Value<string>(); string m3u8 = GetWebData(url); Regex rgx = new Regex(@"WIDTH=(?<bitrate>\d+)[^c]*(?<url>[^\.]*\.m3u8)"); foreach (Match m in rgx.Matches(m3u8)) { video.PlaybackOptions.Add(m.Groups["bitrate"].Value.ToString(), Regex.Replace(url, @"([^/]*?.m3u8)", delegate(Match match) { return m.Groups["url"].Value; })); } video.PlaybackOptions = video.PlaybackOptions.OrderByDescending(p => int.Parse(p.Key)).ToDictionary(kvp => ((int.Parse(kvp.Key) /1000) + " kbps (HLS)"), kvp => kvp.Value); } catch { } } IEnumerable<JToken> streams = episode["streams"].Where(s => s["format"].Value<string>().ToLower() == "flash" && !s["drmProtected"].Value<bool>()); string streamBaseUrl = (string)episode["streamBaseUrl"]; Dictionary<string, string> rtmpD = new Dictionary<string, string>(); if (streamBaseUrl != null && streams != null && streams.Count() > 0) { foreach (JToken stream in streams) { MPUrlSourceFilter.RtmpUrl url = new MPUrlSourceFilter.RtmpUrl(streamBaseUrl) { SwfUrl = swfPlayer, SwfVerify = true, PlayPath = (string)stream["source"] }; rtmpD.Add(((int)stream["bitrate"] / 1000).ToString(), url.ToString()); } rtmpD = rtmpD.OrderByDescending(p => int.Parse(p.Key)).ToDictionary(kvp => (kvp.Key + " kbps (RTMP)"), kvp => kvp.Value); video.PlaybackOptions = video.PlaybackOptions.Concat(rtmpD).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); if (retrieveSubtitles && (bool)episode["hasSubtitle"]) { string subData = GetWebData(string.Format("{0}/subtitles/{1}", apiBaseUrl, episode["id"].ToString())); JArray subtitleJson = (JArray)JsonConvert.DeserializeObject(subData); video.SubtitleText = formatSubtitle(subtitleJson); } } string firsturl = video.PlaybackOptions.First().Value; if (inPlaylist) video.PlaybackOptions.Clear(); return new List<string>() { firsturl }; }
public override String GetVideoUrl(VideoInfo video) { var cache = new List <string>(); var baseDoc = GetWebData <HtmlDocument>(video.VideoUrl); var mediaDiv = baseDoc.DocumentNode.Descendants("div").FirstOrDefault(div => div.GetAttributeValue("data-ctrl-player", "") != ""); if (mediaDiv != null) { var configUrl = new Uri(new Uri(video.VideoUrl), JObject.Parse(HttpUtility.HtmlDecode(mediaDiv.GetAttributeValue("data-ctrl-player", ""))).Value <string>("mcUrl")).AbsoluteUri; var mediaString = GetWebData <string>(configUrl); var mediaJson = JsonConvert.DeserializeObject <JsonResponse>(mediaString); var playbackOptionsByUrl = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); int qualityNumber; foreach (var media in mediaJson.MediaArray.SelectMany(m => m.MediaStreamArray).Select(streamArray => new { Quality = int.TryParse(streamArray.Quality, out qualityNumber) ? ((VideoQuality)qualityNumber).ToString() : "HD", Url = streamArray.Stream is JArray ? ((JArray)streamArray.Stream).Values <string>().OrderByDescending(item => item, StringComparer.OrdinalIgnoreCase).First() : streamArray.Stream as string, Server = streamArray.Server }).Distinct()) { string url = media.Url; cache.Add(url); if (url.EndsWith(".smil")) { url = GetStreamUrlFromSmil(url); } if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute)) { if (Uri.IsWellFormedUriString(url, UriKind.Relative)) { var absoluteUri = new Uri(new Uri(video.VideoUrl), url); url = absoluteUri.ToString(); } if (url.Contains("master.m3u8")) { var m3u8Data = GetWebData(url); foreach (Match match in Regex.Matches(m3u8Data, m3u8Regex2)) { playbackOptionsByUrl[match.Groups["url"].Value] = string.Format("HLS - {0} - {1} kbps", match.Groups["resolution"].Value, int.Parse(match.Groups["bitrate"].Value) / 1000); cache.Add(match.Groups["url"].Value); } foreach (Match match in Regex.Matches(m3u8Data, m3u8Regex1)) { playbackOptionsByUrl[match.Groups["url"].Value] = string.Format("HLS - {0} - {1} kbps", match.Groups["codecs"].Value, int.Parse(match.Groups["bitrate"].Value) / 1000); cache.Add(match.Groups["url"].Value); } } else if (url.EndsWith("f4m")) { url += "?g=" + Helpers.StringUtils.GetRandomLetters(12) + "&hdcore=3.8.0"; playbackOptionsByUrl[url] = media.Quality; } else { playbackOptionsByUrl[url] = media.Quality; } } else if (mediaJson.IsLive) { url = string.Empty; if (string.IsNullOrEmpty(media.Url)) { string guessedStream = media.Server.Substring(media.Server.LastIndexOf('/') + 1); url = new MPUrlSourceFilter.RtmpUrl(media.Server) { Live = true, LiveStream = true, Subscribe = guessedStream, PageUrl = video.VideoUrl }.ToString(); } else if (media.Url.Contains('?')) { var tcUrl = media.Server.TrimEnd('/') + media.Url.Substring(media.Url.IndexOf('?')); var app = new Uri(media.Server).AbsolutePath.Trim('/') + media.Url.Substring(media.Url.IndexOf('?')); var playPath = media.Url; url = new MPUrlSourceFilter.RtmpUrl(tcUrl) { App = app, PlayPath = playPath, Live = true, PageUrl = video.VideoUrl, Subscribe = playPath }.ToString(); } else { url = new MPUrlSourceFilter.RtmpUrl(media.Server + "/" + media.Url) { Live = true, LiveStream = true, Subscribe = media.Url, PageUrl = video.VideoUrl }.ToString(); } playbackOptionsByUrl[url] = media.Quality; } } video.PlaybackOptions = new Dictionary <string, string>(); foreach (var lookup in playbackOptionsByUrl.ToLookup(kvp => kvp.Value)) { var i = 0; foreach (var optionByUrl in lookup) { video.PlaybackOptions.Add(string.Format("{0} - {1}", optionByUrl.Value, i++), optionByUrl.Key); } } } string qualitytoMatch = videoQuality.ToString(); string firstUrl = video.PlaybackOptions.FirstOrDefault(p => p.Key.Contains(qualitytoMatch)).Value; return(!string.IsNullOrEmpty(firstUrl) ? firstUrl : video.PlaybackOptions.Select(kvp => kvp.Value).LastOrDefault()); }
public override String GetVideoUrl(VideoInfo video) { var baseDoc = GetWebData <HtmlDocument>(video.VideoUrl); var mediaDiv = baseDoc.DocumentNode.Descendants("div").FirstOrDefault(div => div.GetAttributeValue("data-ctrl-player", "") != ""); if (mediaDiv != null) { var configUrl = new Uri(new Uri(video.VideoUrl), JObject.Parse(HttpUtility.HtmlDecode(mediaDiv.GetAttributeValue("data-ctrl-player", ""))).Value <string>("mcUrl")).AbsoluteUri; var mediaJson = GetWebData <JObject>(configUrl); video.PlaybackOptions = new Dictionary <string, string>(); foreach (var media in mediaJson["_mediaArray"].SelectMany(m => m["_mediaStreamArray"])) { var quali = ((JValue)media["_quality"]).Type == JTokenType.Integer ? ((VideoQuality)media.Value <int>("_quality")).ToString() : "HD"; var url = media["_stream"] is JArray ? media["_stream"][0].Value <string>() : media.Value <string>("_stream"); if (url.EndsWith(".smil")) { url = GetStreamUrlFromSmil(url); } if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) { if (url.EndsWith("f4m")) { url += "?g=" + Helpers.StringUtils.GetRandomLetters(12) + "&hdcore=3.8.0"; } video.PlaybackOptions[quali] = url; } else if (mediaJson.Value <bool>("_isLive")) { var server = media.Value <string>("_server"); var stream = media.Value <string>("_stream"); url = ""; if (string.IsNullOrEmpty(stream)) { string guessedStream = server.Substring(server.LastIndexOf('/') + 1); url = new MPUrlSourceFilter.RtmpUrl(server) { Live = true, LiveStream = true, Subscribe = guessedStream, PageUrl = video.VideoUrl }.ToString(); } else if (stream.Contains('?')) { var tcUrl = server.TrimEnd('/') + stream.Substring(stream.IndexOf('?')); var app = new Uri(server).AbsolutePath.Trim('/') + stream.Substring(stream.IndexOf('?')); var playPath = stream; url = new MPUrlSourceFilter.RtmpUrl(tcUrl) { App = app, PlayPath = playPath, Live = true, PageUrl = video.VideoUrl, Subscribe = playPath }.ToString(); } else { url = new MPUrlSourceFilter.RtmpUrl(server + "/" + stream) { Live = true, LiveStream = true, Subscribe = stream, PageUrl = video.VideoUrl }.ToString(); } if (!video.PlaybackOptions.ContainsKey(quali)) { video.PlaybackOptions[quali] = url; } } } } return(video.PlaybackOptions.Select(p => p.Value).LastOrDefault()); }
string getCatchupUrls(VideoInfo video) { WebProxy proxyObj = getProxy(); Match m = videoPidRegex.Match(GetWebData(video.VideoUrl, proxy: proxyObj)); if (!m.Success) { Log.Warn("BBCiPlayer: Failed to parse vpid from '{0}'", video.VideoUrl); return(null); } string vpid = m.Groups[1].Value; XmlDocument doc = new XmlDocument(); doc.LoadXml(GetWebData(MEDIA_SELECTOR_URL + vpid, proxy: proxyObj)); //uk only XmlNamespaceManager nsmRequest = new XmlNamespaceManager(doc.NameTable); nsmRequest.AddNamespace("ns1", "http://bbc.co.uk/2008/mp/mediaselection"); if (RetrieveSubtitles) { XmlNode captionNode = doc.SelectSingleNode("//ns1:media[@kind='captions']", nsmRequest); if (captionNode != null) { XmlNode captionConnection = captionNode.SelectSingleNode("ns1:connection", nsmRequest); if (captionConnection != null && captionConnection.Attributes["href"] != null) { string sub = GetWebData(captionConnection.Attributes["href"].Value); video.SubtitleText = OnlineVideos.Sites.Utils.SubtitleReader.TimedText2SRT(sub); } } } SortedList <string, string> sortedPlaybackOptions = new SortedList <string, string>(new StreamComparer()); foreach (XmlElement mediaElem in doc.SelectNodes("//ns1:media[@kind='video']", nsmRequest)) { string info = ""; string resultUrl = ""; foreach (XmlElement connectionElem in mediaElem.SelectNodes("ns1:connection", nsmRequest)) { string supplier = connectionElem.Attributes["supplier"].Value; //"kind" if (Array.BinarySearch <string>(new string[] { "akamai", "level3", "limelight" }, supplier) >= 0) { // rtmp if (connectionElem.Attributes["protocol"] == null || connectionElem.Attributes["protocol"].Value != "rtmp") { continue; } string server = connectionElem.Attributes["server"].Value; string identifier = connectionElem.Attributes["identifier"].Value; string auth = connectionElem.Attributes["authString"].Value; string application = connectionElem.GetAttribute("application"); if (string.IsNullOrEmpty(application)) { application = "ondemand"; } string SWFPlayer = "http://www.bbc.co.uk/emp/releases/iplayer/revisions/617463_618125_4/617463_618125_4_emp.swf"; // "http://www.bbc.co.uk/emp/10player.swf"; info = string.Format("{0}x{1} | {2} kbps | {3}", mediaElem.GetAttribute("width"), mediaElem.GetAttribute("height"), mediaElem.GetAttribute("bitrate"), supplier); resultUrl = ""; if (supplier == "limelight") { resultUrl = new MPUrlSourceFilter.RtmpUrl(string.Format("rtmp://{0}:1935/{1}", server, application + "?" + auth), server, 1935) { App = application + "?" + auth, PlayPath = identifier, SwfUrl = SWFPlayer, SwfVerify = true, }.ToString(); } else if (supplier == "level3") { resultUrl = new MPUrlSourceFilter.RtmpUrl(string.Format("rtmp://{0}:1935/{1}", server, application + "?" + auth), server, 1935) { App = application + "?" + auth, PlayPath = identifier, SwfUrl = SWFPlayer, SwfVerify = true, Token = auth, }.ToString(); } else if (supplier == "akamai") { resultUrl = new MPUrlSourceFilter.RtmpUrl(string.Format("rtmp://{0}:1935/{1}?{2}", server, application, auth)) { PlayPath = identifier + "?" + auth, SwfUrl = SWFPlayer, SwfVerify = true, }.ToString(); } } if (resultUrl != "") { sortedPlaybackOptions.Add(info, resultUrl); } } } video.PlaybackOptions = new Dictionary <string, string>(); if (sortedPlaybackOptions.Count > 0) { if (AutoSelectStream) { var last = sortedPlaybackOptions.Last(); video.PlaybackOptions.Add(last.Key, last.Value); return(last.Value); } else { foreach (var option in sortedPlaybackOptions) { video.PlaybackOptions.Add(option.Key, option.Value); } return(sortedPlaybackOptions.Last().Value); } } //Fallback to HLS streams string url = getHLSVideoUrls(video, vpid, proxyObj); if (!string.IsNullOrEmpty(url)) { return(url); } var errorNodes = doc.SelectNodes("//ns1:error", nsmRequest); if (errorNodes.Count > 0) { throw new OnlineVideosException(string.Format("BBC says: {0}", ((XmlElement)errorNodes[0]).GetAttribute("id"))); } return(null); }
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>(); XmlDocument xml = GetWebData<XmlDocument>(video.VideoUrl); Log.Debug(@"SMIL loaded"); XmlNamespaceManager nsmRequest = new XmlNamespaceManager(xml.NameTable); nsmRequest.AddNamespace("a", @"http://www.w3.org/2001/SMIL20/Language"); XmlNode metaBase = xml.SelectSingleNode(@"//a:meta", nsmRequest); string metaBaseValue = metaBase.Attributes["base"].Value; // base URL may be stored in the base attribute of <meta> tag string baseRtmp = metaBaseValue.StartsWith("rtmp") ? metaBaseValue : String.Empty; foreach (XmlNode node in xml.SelectNodes("//a:switch/a:video", nsmRequest)) { int bitrate = int.Parse(node.Attributes["system-bitrate"].Value); // skip bitrate is zero if (bitrate == 0) continue; string url = node.Attributes["src"].Value; // skip if advertisement if (url.StartsWith("pfadx")) continue; if (!string.IsNullOrEmpty(baseRtmp)) { // prefix url with base (from <meta> tag) and artifical <break> url = baseRtmp + @"<break>" + url; } Log.Debug(@"bitrate: {0}, url: {1}", bitrate / 1000, url); if (url.StartsWith("rtmp")) { Match rtmpUrlMatch = rtmpUrlRegex.Match(url); if (rtmpUrlMatch.Success && !urlsDictionary.ContainsKey(bitrate / 1000)) { string host = rtmpUrlMatch.Groups["host"].Value; string playPath = rtmpUrlMatch.Groups["playPath"].Value; if (playPath.EndsWith(@".mp4") && !playPath.StartsWith(@"mp4:")) { // prepend with mp4: playPath = @"mp4:" + playPath; } else if (playPath.EndsWith(@".flv")) { // strip extension playPath = playPath.Substring(0, playPath.Length - 4); } Log.Debug(@"Host: {0}, PlayPath: {1}", host, playPath); MPUrlSourceFilter.RtmpUrl rtmpUrl = new MPUrlSourceFilter.RtmpUrl(host) { PlayPath = playPath }; if (!string.IsNullOrEmpty(swfUrl)) { rtmpUrl.SwfUrl = swfUrl; rtmpUrl.SwfVerify = true; } urlsDictionary.Add(bitrate / 1000, rtmpUrl.ToString()); } } } // 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); // 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:ref", nsmRequest); if (geolockReference != null) { Log.Error(@"You are not in a geographic region that has access to this content."); result = string.Format(@"{0}{1}", metaBaseValue, geolockReference.Attributes["src"].Value); } } return result; }
public string CreateRTMPUrl(string url) { Log.Debug(@"Video URL (before): {0}", url); string result = url; // must specify referer as 3rd argument (or we will get 403 Forbidden from cls.ctvdigital.net) string webData = GetWebData(url, referer: baseUrl); if (!string.IsNullOrEmpty(webData)) { Match urlMatch = clipUrlRegex.Match(webData); if (urlMatch.Success) { string rtmpFromScraper = urlMatch.Groups["url"].Value; Log.Debug("RTMP URL found: {0}", rtmpFromScraper); Match m = rtmpUrlRegex.Match(rtmpFromScraper); if (m.Success) { string rtmpUrl = String.Format(@"rtmpe://{0}/ondemand?{1}", m.Groups["host"], m.Groups["params"]); string file = m.Groups["file"].Value; string playPath = file.Contains(@"secure") ? file.Replace(".flv", string.Empty) // replace trailing .flv : String.Format(@"mp4:{0}", file); // prepend mp4: Log.Debug(@"RTMP URL partial: {0} playPath: {1}", rtmpUrl, playPath); result = new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = playPath, SwfUrl = swfUrl, SwfVerify = true }.ToString(); Log.Debug(@"RTMP URL(MPUrlSourceFilter after): {0}", result); } else { m = rtmpUrlSecondaryRegex.Match(rtmpFromScraper); if (m.Success) { string rtmpUrl = String.Format(@"rtmpe://{0}/{1}?{2}", m.Groups["host"], m.Groups["app"], m.Groups["params"]); string playPath = String.Format(@"mp4:{0}?{1}", m.Groups["file"], m.Groups["params"]); result = new MPUrlSourceFilter.RtmpUrl(rtmpUrl) { PlayPath = playPath, SwfUrl = swfUrl, SwfVerify = true }.ToString(); Log.Debug(@"RTMP URL Secondary Option (after): {0}", result); } else { Log.Error(@"Unknown RTMP URL: {0}", rtmpFromScraper); } } } } return result; }