Пример #1
0
        /// <summary>
        /// 放送情報の取得を開始します。
        /// </summary>
        private static void BeginGetLiveInfo(long liveId,
                                             InternalData internalData,
                                             AutoResetEvent ev)
        {
            WebUtil.RequestHttpTextAsync(
                NicoString.GetLiveUrl(liveId),
                null,
                internalData.Cookie,
                Encoding.UTF8,
                (result, text) =>
            {
                try
                {
                    // 放送情報が取得できなければエラーとします。
                    var v = LiveInfo.CreateFromHtml(
                        string.Format("lv{0}", liveId),
                        text);

                    internalData.LiveStreamInfo.LiveInfo = v;
                }
                catch (Exception ex)
                {
                    internalData.Exception = ex;
                }

                ev.Set();
            });
        }
Пример #2
0
        /// <summary>
        /// コミュニティ情報(累計来場者数など)を取得します。
        /// </summary>
        private static void SetCommunityInfo(LiveInfo live, string pageStr)
        {
            // 累計来場者数
            var m = CommunityVisitorsRegex.Match(pageStr);

            if (!m.Success)
            {
                throw new NicoLiveException(
                          "累計来場者数の取得に失敗しました。",
                          live.Id);
            }
            live.TotalVisitors = int.Parse(
                m.Groups[1].Value,
                NumberStyles.AllowThousands);

            // /レベル
            m = CommunityLevelRegex.Match(pageStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                          "コミュニティレベルの取得に失敗しました。",
                          live.Id);
            }
            live.CommunityLevel = int.Parse(
                m.Groups[1].Value,
                NumberStyles.AllowThousands);
        }
Пример #3
0
        /// <summary>
        /// コメントサーバーに接続します。
        /// </summary>
        /// <remarks>
        /// 接続失敗時には例外が返されます。
        /// </remarks>
        public void Connect(PlayerStatus playerStatus, CookieContainer cc,
                            bool currentRoomOnly, TimeSpan timeout)
        {
            lock (ConnectLock)
            {
                if (playerStatus == null)
                {
                    throw new ArgumentNullException("playerStatus");
                }

                // 例外が発生する可能性があります。
                var streamInfo = LiveUtil.GetLiveStreamInfo(playerStatus, cc);

                // 各コメントルームの情報を取得します。
                var roomInfoList = GetAllRoomInfo(
                    streamInfo.PlayerStatus,
                    streamInfo.LiveInfo.CommunityLevel);
                var currentRoomIndex = FindRoomIndex(
                    playerStatus.MS.Port, roomInfoList);
                var roomList = new List <CommentRoom>();

                // 各コメントルームに接続します。
                for (var i = 0; i < roomInfoList.Count(); ++i)
                {
                    if (currentRoomOnly && i != currentRoomIndex)
                    {
                        roomList.Add(null);
                        continue;
                    }

                    var room = new CommentRoom(this, roomInfoList[i], i);
                    // 接続に失敗した場合、例外が返ります。
                    room.Connect(cc, timeout);
                    roomList.Add(room);
                }

                Disconnect();
                lock (SyncRoot)
                {
                    this.connectedRoomCount = 0;
                    this.playerStatus       = streamInfo.PlayerStatus;
                    this.publishStatus      = streamInfo.PublishStatus;
                    this.liveInfo           = streamInfo.LiveInfo;
                    this.roomList           = roomList;
                    this.currentRoomIndex   = currentRoomIndex;
                    this.cookieContainer    = cc;
                }

                // フィールド値を設定した後に、OnConnectedRoomを呼びます。
                foreach (var room in ClonedCommentRoomList)
                {
                    OnConnectedRoom(room);
                }

                // 接続時のイベントを発生させます。
                FireConnected();
            }
        }
Пример #4
0
        private static void SetOfficialInfo(LiveInfo live, string pageStr)
        {
            // 累計来場者数
            var m = OfficialVisitorsRegex.Match(pageStr);

            if (!m.Success)
            {
                live.TotalVisitors = 0;
            }
            else
            {
                live.TotalVisitors = int.Parse(
                    m.Groups[1].Value,
                    NumberStyles.AllowThousands);
            }
        }
Пример #5
0
        /// <summary>
        /// 公式放送のコメントサーバーに接続します。
        /// </summary>
        /// <remarks>
        /// 接続失敗時には例外が返されます。
        /// </remarks>
        public void ConnectToOfficial(string filepath, CookieContainer cc, TimeSpan timeout)
        {
            lock (ConnectLock)
            {
                // 各コメントルームの情報を取得します。
                var roomInfoList = Detail.OfficialLiveInfoCreator
                                   .GetAllRoomInfoFromXml(filepath);
                var roomList = new List <CommentRoom>();

                // 各コメントルームに接続します。
                for (var i = 0; i < roomInfoList.Count(); ++i)
                {
                    var room = new CommentRoom(this, roomInfoList[i], i);

                    // 接続に失敗した場合、例外が返ります。
                    room.Connect(cc, timeout);
                    roomList.Add(room);
                }

                Disconnect();
                lock (SyncRoot)
                {
                    this.connectedRoomCount = 0;
                    this.playerStatus       = null;
                    this.publishStatus      = null;
                    this.liveInfo           = null;
                    this.roomList           = roomList;
                    this.currentRoomIndex   = -1;
                    this.cookieContainer    = cc;
                }

                // フィールド値を設定した後に、OnConnectedRoomを呼びます。
                foreach (var room in ClonedCommentRoomList)
                {
                    OnConnectedRoom(room);
                }

                // 接続時のイベントを発生させます。
                FireConnected();
            }
        }
Пример #6
0
        /// <summary>
        /// 放送関連情報を同期的に取得します。
        /// </summary>
        public static LiveStreamInfo GetLiveStreamInfoSync(string liveUrl,
                                                           CookieContainer cc)
        {
            var playerStatus = PlayerStatus.Create(liveUrl, cc);
            var id           = playerStatus.Stream.Id;

            // publishstatusは放送主しか取得することが出来ません。
            PublishStatus publishStatus = null;

            if (playerStatus.Stream.IsOwner)
            {
                publishStatus = PublishStatus.Create(id, cc);
            }

            // 放送情報を取得します。
            var liveInfo = LiveInfo.Create(id, cc);

            return(new LiveStreamInfo()
            {
                PlayerStatus = playerStatus,
                PublishStatus = publishStatus,
                LiveInfo = liveInfo,
            });
        }
Пример #7
0
        /// <summary>
        /// html形式の生放送ページから生放送情報を作成します。
        /// </summary>
        public static LiveInfo CreateFromHtml(string idString, string pageStr)
        {
            var live = new LiveInfo();

            if (string.IsNullOrEmpty(pageStr))
            {
                throw new NicoLiveException(
                          "ページが空です。",
                          idString);
            }

            var m = ProviderInfoRegex.Match(pageStr);

            if (!m.Success)
            {
                throw new NicoLiveException(
                          "放送の提供元情報を取得できませんでした。",
                          idString);
            }
            var provider = NicoUtil.ParseProvider(m.Groups[1].Value);

            m = VideoInfoRegex.Match(pageStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                          "生放送情報を取得できませんでした。",
                          idString);
            }

            var infoStr = m.Groups[1].Value;

            m = IdRegex.Match(infoStr);
            if (!m.Success)
            {
                throw new NicoException(
                          "生放送IDを取得できませんでした。",
                          idString);
            }
            live.Id = m.Groups[1].Value;

            m = TitleRegex.Match(infoStr);
            if (!m.Success)
            {
                throw new NicoException(
                          "生放送タイトルを取得できませんでした。",
                          idString);
            }
            live.Title = m.Groups[1].Value
                         .Replace("\\'", "'");

            m = DescriptionRegex.Match(infoStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                          "生放送概要を取得できませんでした。",
                          idString);
            }
            live.Description = m.Groups[1].Value
                               .Replace("\\'", "'")
                               .Replace("\\r\\n", "\n");

            switch (provider.ProviderType)
            {
            case ProviderType.Community:
                SetCommunityInfo(live, pageStr);
                break;

            case ProviderType.Channel:
                SetChannelInfo(live, pageStr);
                break;

            case ProviderType.Official:
                SetOfficialInfo(live, pageStr);
                break;

            default:
                throw new NotImplementedException(
                          "実装されていない放送提供元です。");
            }

            return(live);
        }
Пример #8
0
 private static void SetOfficialInfo(LiveInfo live, string pageStr)
 {
     // 累計来場者数
     var m = OfficialVisitorsRegex.Match(pageStr);
     if (!m.Success)
     {
         live.TotalVisitors = 0;
     }
     else
     {
         live.TotalVisitors = int.Parse(
             m.Groups[1].Value,
             NumberStyles.AllowThousands);
     }
 }
Пример #9
0
        /// <summary>
        /// コミュニティ情報(累計来場者数など)を取得します。
        /// </summary>
        private static void SetCommunityInfo(LiveInfo live, string pageStr)
        {
            // 累計来場者数
            var m = CommunityVisitorsRegex.Match(pageStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                    "累計来場者数の取得に失敗しました。",
                    live.IdString);
            }
            live.TotalVisitors = int.Parse(
                m.Groups[1].Value,
                NumberStyles.AllowThousands);

            // /レベル
            m = CommunityLevelRegex.Match(pageStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                    "コミュニティレベルの取得に失敗しました。",
                    live.IdString);
            }
            live.CommunityLevel = int.Parse(
                m.Groups[1].Value,
                NumberStyles.AllowThousands);
        }
Пример #10
0
        /// <summary>
        /// html形式の生放送ページから生放送情報を作成します。
        /// </summary>
        public static LiveInfo CreateFromHtml(string idString, string pageStr)
        {
            var live = new LiveInfo();

            if (string.IsNullOrEmpty(pageStr))
            {
                throw new NicoLiveException(
                    "ページが空です。",
                    idString);
            }

            var m = ProviderInfoRegex.Match(pageStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                    "放送の提供元情報を取得できませんでした。",
                    idString);
            }
            var provider = LiveUtil.ParseProvider(m.Groups[1].Value);

            m = VideoInfoRegex.Match(pageStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                    "生放送情報を取得できませんでした。",
                    idString);
            }

            var infoStr = m.Groups[1].Value;

            m = IdRegex.Match(infoStr);
            if (!m.Success)
            {
                throw new NicoException(
                    "生放送IDを取得できませんでした。",
                    idString);
            }
            live.Id = int.Parse(m.Groups[1].Value);

            m = TitleRegex.Match(infoStr);
            if (!m.Success)
            {
                throw new NicoException(
                    "生放送タイトルを取得できませんでした。",
                    idString);
            }
            live.Title = m.Groups[1].Value
                .Replace("\\'", "'");

            m = DescriptionRegex.Match(infoStr);
            if (!m.Success)
            {
                throw new NicoLiveException(
                    "生放送概要を取得できませんでした。",
                    idString);
            }
            live.Description = m.Groups[1].Value
                .Replace("\\'", "'")
                .Replace("\\r\\n", "\n");

            switch (provider.ProviderType)
            {
                case ProviderType.Community:
                    SetCommunityInfo(live, pageStr);
                    break;
                case ProviderType.Official:
                    SetOfficialInfo(live, pageStr);
                    break;
                default:
                    throw new NotImplementedException(
                        "実装されていない放送提供元です。");
            }

            return live;
        }
Пример #11
0
        /// <summary>
        /// 公式放送のコメントサーバーに接続します。
        /// </summary>
        /// <remarks>
        /// 接続失敗時には例外が返されます。
        /// </remarks>
        public void ConnectToOfficial(string filepath, CookieContainer cc, TimeSpan timeout)
        {
            lock (ConnectLock)
            {
                // 各コメントルームの情報を取得します。
                var roomInfoList = Detail.OfficialLiveInfoCreator
                    .GetAllRoomInfoFromXml(filepath);
                var roomList = new List<CommentRoom>();

                // 各コメントルームに接続します。
                for (var i = 0; i < roomInfoList.Count(); ++i)
                {
                    var room = new CommentRoom(this, roomInfoList[i], i);

                    // 接続に失敗した場合、例外が返ります。
                    room.Connect(cc, timeout);
                    roomList.Add(room);
                }

                Disconnect();
                lock (SyncRoot)
                {
                    this.connectedRoomCount = 0;
                    this.playerStatus = null;
                    this.publishStatus = null;
                    this.liveInfo = null;
                    this.roomList = roomList;
                    this.currentRoomIndex = -1;
                    this.cookieContainer = cc;
                }

                // フィールド値を設定した後に、OnConnectedRoomを呼びます。
                foreach (var room in ClonedCommentRoomList)
                {
                    OnConnectedRoom(room);
                }

                // 接続時のイベントを発生させます。
                FireConnected();
            }
        }
Пример #12
0
        /// <summary>
        /// コメントサーバーに接続します。
        /// </summary>
        /// <remarks>
        /// 接続失敗時には例外が返されます。
        /// </remarks>
        public void Connect(PlayerStatus playerStatus, CookieContainer cc,
                            bool currentRoomOnly, TimeSpan timeout)
        {
            lock (ConnectLock)
            {
                if (playerStatus == null)
                {
                    throw new ArgumentNullException("playerStatus");
                }

                // 例外が発生する可能性があります。
                var streamInfo = LiveUtil.GetLiveStreamInfo(playerStatus, cc);
                
                // 各コメントルームの情報を取得します。
                var roomInfoList = GetAllRoomInfo(
                    streamInfo.PlayerStatus,
                    streamInfo.LiveInfo.CommunityLevel);
                var currentRoomIndex = FindRoomIndex(
                    playerStatus.MS.Port, roomInfoList);
                var roomList = new List<CommentRoom>();

                // 各コメントルームに接続します。
                for (var i = 0; i < roomInfoList.Count(); ++i)
                {
                    if (currentRoomOnly && i != currentRoomIndex)
                    {
                        roomList.Add(null);
                        continue;
                    }

                    var room = new CommentRoom(this, roomInfoList[i], i);
                    // 接続に失敗した場合、例外が返ります。
                    room.Connect(cc, timeout);
                    roomList.Add(room);
                }

                Disconnect();
                lock (SyncRoot)
                {
                    this.connectedRoomCount = 0;
                    this.playerStatus = streamInfo.PlayerStatus;
                    this.publishStatus = streamInfo.PublishStatus;
                    this.liveInfo = streamInfo.LiveInfo;
                    this.roomList = roomList;
                    this.currentRoomIndex = currentRoomIndex;
                    this.cookieContainer = cc;
                }

                // フィールド値を設定した後に、OnConnectedRoomを呼びます。
                foreach (var room in ClonedCommentRoomList)
                {
                    OnConnectedRoom(room);
                }

                // 接続時のイベントを発生させます。
                FireConnected();
            }
        }