Exemplo n.º 1
0
        public NicoNicoDmcSession(NicoNicoGetDmc dmc) {

            GetDmc = dmc;
        }
Exemplo n.º 2
0
        //動画ページを指定
        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;
            }
        }