//動画ページを指定 public static WatchApiData GetWatchApiData(string videoPage) { //動画ページのhtml取得 var response = NicoNicoWrapperMain.GetSession().GetResponseAsync(videoPage).Result; //チャンネル、公式動画 if(response.StatusCode == HttpStatusCode.MovedPermanently) { response = NicoNicoWrapperMain.GetSession().GetResponseAsync(response.Headers.Location.OriginalString).Result; } //削除された動画 if(response.StatusCode == HttpStatusCode.NotFound) { return null; } //混雑中 if(response.StatusCode == HttpStatusCode.ServiceUnavailable) { return null; } string html = response.Content.ReadAsStringAsync().Result; HtmlDocument doc = new HtmlDocument(); doc.LoadHtml2(html); //htmlからAPIデータだけを綺麗に抜き出す すごい var container = doc.DocumentNode.QuerySelector("#watchAPIDataContainer"); if(container == null) { return null; } var data = container.InnerHtml; //html特殊文字をデコードする data = HttpUtility.HtmlDecode(data); //jsonとしてAPIデータを展開していく var json = DynamicJson.Parse(data); //GetFlvの結果 string flv = json.flashvars.flvInfo; //2重にエンコードされてるので二回 flv = HttpUtility.UrlDecode(flv); flv = HttpUtility.UrlDecode(flv); WatchApiData ret = new WatchApiData(); //&で繋がれているので剥がす var getFlv = flv.Split(new char[] { '&' }).ToDictionary(source => source.Substring(0, source.IndexOf('=')), source => Uri.UnescapeDataString(source.Substring(source.IndexOf('=') + 1))); ret.GetFlv = new NicoNicoGetFlvData(getFlv); //動画情報 var videoDetail = json.videoDetail; //---情報を詰める--- ret.Cmsid = videoDetail.id; ret.MovieType = json.flashvars.movie_type; ret.Title = HttpUtility.HtmlDecode(videoDetail.title); //html特殊文字をデコード ret.Thumbnail = videoDetail.thumbnail; ret.Description = videoDetail.description; ret.PostedAt = videoDetail.postedAt; ret.Length = (int) videoDetail.length; ret.ViewCounter = (int) videoDetail.viewCount; ret.CommentCounter = (int) videoDetail.commentCount; ret.MylistCounter = (int) videoDetail.mylistCount; ret.YesterdayRank = videoDetail.yesterday_rank == null ? "圏外" : videoDetail.yesterday_rank + "位"; ret.HighestRank = videoDetail.highest_rank == null ? "圏外" : videoDetail.highest_rank + "位"; ret.Token = json.flashvars.csrfToken; if(json.uploaderInfo()) { //投稿者情報 var uploaderInfo = json.uploaderInfo; ret.UploaderId = uploaderInfo.id; ret.UploaderIconUrl = uploaderInfo.icon_url; ret.UploaderName = uploaderInfo.nickname; ret.UploaderIsFavorited = uploaderInfo.is_favorited; } else if(json.channelInfo()) { //投稿者情報 var channelInfo = json.channelInfo; ret.UploaderId = channelInfo.id; ret.UploaderIconUrl = channelInfo.icon_url; ret.UploaderName = channelInfo.name; ret.UploaderIsFavorited = channelInfo.is_favorited == 1 ? true : false; ret.IsChannelVideo = true; } ret.Description = HyperLinkParser.Parse(ret.Description); ret.TagList = new ObservableCollection<VideoTagViewModel>(); foreach(var tag in videoDetail.tagList) { NicoNicoTag entry = new NicoNicoTag() { Id = tag.id, Tag = tag.tag, Dic = tag.dic(), Lck = tag.lck == "1" ? true : false, Cat = tag.cat() }; ret.TagList.Add(new VideoTagViewModel(entry)); } //------ //有料動画 if(ret.GetFlv.VideoUrl == null || ret.GetFlv.VideoUrl.Count() == 0) { ret.IsPaidVideo = true; return ret; } //念のためCookieを設定 var cookie = response.Headers.GetValues("Set-Cookie"); foreach(string s in cookie) { foreach(string ss in s.Split(';')) { App.SetCookie(new Uri("http://nicovideo.jp/"), ss); } } return ret; }
public VideoTagViewModel(NicoNicoTag tag, VideoViewModel vm) { Tag = tag; Owner = vm; }
//動画ページを指定 public async Task<WatchApiData> GetWatchApiDataAsync() { try { //動画ページのhtml取得 var response = await NicoNicoWrapperMain.Session.GetResponseAsync(VideoPage); //チャンネル、公式動画 if(response.StatusCode == HttpStatusCode.MovedPermanently) { response = await NicoNicoWrapperMain.Session.GetResponseAsync(response.Headers.Location.OriginalString); } //削除された動画 if(response.StatusCode == HttpStatusCode.NotFound) { return null; } //混雑中 if(response.StatusCode == HttpStatusCode.ServiceUnavailable) { return null; } string html = await response.Content.ReadAsStringAsync(); var doc = new HtmlDocument(); doc.LoadHtml2(html); //htmlからAPIデータだけを綺麗に抜き出す すごい var container = doc.DocumentNode.QuerySelector("#watchAPIDataContainer"); if(container == null) { return null; } var data = container.InnerHtml; //html特殊文字をデコードする data = HttpUtility.HtmlDecode(data); //jsonとしてAPIデータを展開していく var json = DynamicJson.Parse(data); //GetFlvの結果 string flv = json.flashvars.flvInfo; //2重にエンコードされてるので二回 flv = HttpUtility.UrlDecode(flv); flv = HttpUtility.UrlDecode(flv); var ret = new WatchApiData(); //&で繋がれているので剥がす var getFlv = flv.Split(new char[] { '&' }).ToDictionary(source => source.Substring(0, source.IndexOf('=')), source => Uri.UnescapeDataString(source.Substring(source.IndexOf('=') + 1))); ret.GetFlv = new NicoNicoGetFlv(getFlv); //動画情報 var videoDetail = json.videoDetail; //---情報を詰める--- ret.Cmsid = videoDetail.id; ret.MovieType = json.flashvars.movie_type; ret.Title = HttpUtility.HtmlDecode(videoDetail.title); //html特殊文字をデコード ret.Thumbnail = videoDetail.thumbnail; ret.Description = videoDetail.description; ret.PostedAt = videoDetail.postedAt; ret.Length = (int)videoDetail.length; ret.ViewCounter = (int)videoDetail.viewCount; ret.CommentCounter = (int)videoDetail.commentCount; ret.MylistCounter = (int)videoDetail.mylistCount; ret.YesterdayRank = videoDetail.yesterday_rank == null ? "圏外" : videoDetail.yesterday_rank + "位"; ret.HighestRank = videoDetail.highest_rank == null ? "圏外" : videoDetail.highest_rank + "位"; ret.IsOfficial = videoDetail.is_official; ret.Token = json.flashvars.csrfToken; ret.IsDmc = json.flashvars.isDmc == 0 ? false : true; ret.HasOwnerThread = json.flashvars.has_owner_thread(); if(ret.IsDmc) { var dmc = DynamicJson.Parse(HttpUtility.UrlDecode(json.flashvars.dmcInfo)); var dmcInfo = new NicoNicoGetDmc(); var sessionApi = dmc.session_api; dmcInfo.ApiUrl = ((string[])sessionApi.api_urls).First(); dmcInfo.Audios = new List<string>(); foreach(var audio in sessionApi.audios) { dmcInfo.Audios.Add(audio); } dmcInfo.AuthType = sessionApi.auth_types.http; dmcInfo.ContentId = sessionApi.content_id; dmcInfo.ContentKeyTimeout = (int) sessionApi.content_key_timeout; dmcInfo.HeartbeatLifeTime = (int) sessionApi.heartbeat_lifetime; dmcInfo.Movies = new List<string>(); foreach(var movie in sessionApi.movies) { dmcInfo.Movies.Add(movie); } dmcInfo.PlayerId = sessionApi.player_id; dmcInfo.Priority = sessionApi.priority; dmcInfo.Protocols = new List<string>(); foreach(var protocol in sessionApi.protocols) { dmcInfo.Protocols.Add(protocol); } dmcInfo.RecipeId = sessionApi.recipe_id; dmcInfo.ServiceUserId = sessionApi.service_user_id; dmcInfo.Signature = sessionApi.signature; dmcInfo.Token = sessionApi.token; dmcInfo.Videos = new List<string>(); foreach(var video in sessionApi.videos) { dmcInfo.Videos.Add(video); } var thread = dmc.thread; dmcInfo.MessageServerUrl = thread.server_url; dmcInfo.PostKeyAvailable = thread.postkey_available; dmcInfo.ThreadId = thread.thread_id.ToString(); dmcInfo.ThreadKeyRequired = thread.thread_key_required; ret.DmcInfo = dmcInfo; } if(json.uploaderInfo()) { //投稿者情報 var uploaderInfo = json.uploaderInfo; ret.UploaderId = uploaderInfo.id; ret.UploaderIconUrl = uploaderInfo.icon_url; ret.UploaderName = uploaderInfo.nickname; //投稿者をお気に入り登録しているか調べる var a = await NicoNicoWrapperMain.Session.GetAsync(string.Format(UploaderInfoApi, ret.UploaderId)); ret.UploaderIsFavorited = DynamicJson.Parse(a).data.following; } else if(json.channelInfo()) { //投稿者情報 var channelInfo = json.channelInfo; ret.UploaderId = channelInfo.id; ret.UploaderIconUrl = channelInfo.icon_url; ret.UploaderName = channelInfo.name; ret.UploaderIsFavorited = channelInfo.is_favorited == 1; ret.IsChannelVideo = true; } ret.Description = HyperLinkReplacer.Replace(ret.Description); ret.TagList = new ObservableCollection<VideoTagViewModel>(); foreach(var tag in videoDetail.tagList) { var entry = new NicoNicoTag() { Id = tag.id, Tag = HttpUtility.HtmlDecode(tag.tag), Dic = tag.dic(), Lck = tag.lck == "1" ? true : false, Cat = tag.cat() }; entry.Url = "http://dic.nicovideo.jp/a/" + entry.Tag; ret.TagList.Add(new VideoTagViewModel(entry, Owner)); } //------ //有料動画 if(ret.GetFlv.VideoUrl == null || ret.GetFlv.VideoUrl.Count() == 0) { ret.IsPaidVideo = true; return ret; } //念のためCookieを設定 var cookie = response.Headers.GetValues("Set-Cookie"); foreach(string s in cookie) { foreach(string ss in s.Split(';')) { App.SetCookie(new Uri("http://nicovideo.jp/"), ss); } } return ret; } catch(Exception e) when (e is RequestFailed || e is RequestTimeout) { return null; } }
//動画ページを指定 public static WatchApiData GetWatchApiData(string videoPage) { //動画ページのhtml取得 var response = NicoNicoWrapperMain.GetSession().GetResponseAsync(videoPage).Result; //チャンネル、公式動画 if (response.StatusCode == HttpStatusCode.MovedPermanently) { response = NicoNicoWrapperMain.GetSession().GetResponseAsync(response.Headers.Location.OriginalString).Result; } //削除された動画 if (response.StatusCode == HttpStatusCode.NotFound) { return(null); } //混雑中 if (response.StatusCode == HttpStatusCode.ServiceUnavailable) { return(null); } string html = response.Content.ReadAsStringAsync().Result; HtmlDocument doc = new HtmlDocument(); doc.LoadHtml2(html); //htmlからAPIデータだけを綺麗に抜き出す すごい var container = doc.DocumentNode.QuerySelector("#watchAPIDataContainer"); if (container == null) { return(null); } var data = container.InnerHtml; //html特殊文字をデコードする data = HttpUtility.HtmlDecode(data); //jsonとしてAPIデータを展開していく var json = DynamicJson.Parse(data); //GetFlvの結果 string flv = json.flashvars.flvInfo; //2重にエンコードされてるので二回 flv = HttpUtility.UrlDecode(flv); flv = HttpUtility.UrlDecode(flv); WatchApiData ret = new WatchApiData(); //&で繋がれているので剥がす var getFlv = flv.Split(new char[] { '&' }).ToDictionary(source => source.Substring(0, source.IndexOf('=')), source => Uri.UnescapeDataString(source.Substring(source.IndexOf('=') + 1))); ret.GetFlv = new NicoNicoGetFlvData(getFlv); //動画情報 var videoDetail = json.videoDetail; //---情報を詰める--- ret.Cmsid = videoDetail.id; ret.MovieType = json.flashvars.movie_type; ret.Title = HttpUtility.HtmlDecode(videoDetail.title); //html特殊文字をデコード ret.Thumbnail = videoDetail.thumbnail; ret.Description = videoDetail.description; ret.PostedAt = videoDetail.postedAt; ret.Length = (int)videoDetail.length; ret.ViewCounter = (int)videoDetail.viewCount; ret.CommentCounter = (int)videoDetail.commentCount; ret.MylistCounter = (int)videoDetail.mylistCount; ret.YesterdayRank = videoDetail.yesterday_rank == null ? "圏外" : videoDetail.yesterday_rank + "位"; ret.HighestRank = videoDetail.highest_rank == null ? "圏外" : videoDetail.highest_rank + "位"; ret.Token = json.flashvars.csrfToken; if (json.uploaderInfo()) { //投稿者情報 var uploaderInfo = json.uploaderInfo; ret.UploaderId = uploaderInfo.id; ret.UploaderIconUrl = uploaderInfo.icon_url; ret.UploaderName = uploaderInfo.nickname; ret.UploaderIsFavorited = uploaderInfo.is_favorited; } else if (json.channelInfo()) { //投稿者情報 var channelInfo = json.channelInfo; ret.UploaderId = channelInfo.id; ret.UploaderIconUrl = channelInfo.icon_url; ret.UploaderName = channelInfo.name; ret.UploaderIsFavorited = channelInfo.is_favorited == 1 ? true : false; ret.IsChannelVideo = true; } ret.Description = HyperLinkParser.Parse(ret.Description); ret.TagList = new ObservableCollection <VideoTagViewModel>(); foreach (var tag in videoDetail.tagList) { NicoNicoTag entry = new NicoNicoTag() { Id = tag.id, Tag = tag.tag, Dic = tag.dic(), Lck = tag.lck == "1" ? true : false, Cat = tag.cat() }; ret.TagList.Add(new VideoTagViewModel(entry)); } //------ //有料動画 if (ret.GetFlv.VideoUrl == null || ret.GetFlv.VideoUrl.Count() == 0) { ret.IsPaidVideo = true; return(ret); } //念のためCookieを設定 var cookie = response.Headers.GetValues("Set-Cookie"); foreach (string s in cookie) { foreach (string ss in s.Split(';')) { App.SetCookie(new Uri("http://nicovideo.jp/"), ss); } } return(ret); }
public VideoTagViewModel(NicoNicoTag tag) { Tag = tag; }