public async Task <List <LivestreamQueryResult> > GetTopStreams(TopStreamQuery topStreamQuery)
        {
            if (topStreamQuery == null)
            {
                throw new ArgumentNullException(nameof(topStreamQuery));
            }

            var query = new GetStreamsQuery()
            {
                First = topStreamQuery.Take
            };

            if (!string.IsNullOrWhiteSpace(topStreamQuery.GameName))
            {
                var gameId = await GetGameIdByName(topStreamQuery.GameName);

                query.GameIds.Add(gameId);
            }

            var topStreams = await twitchTvHelixClient.GetStreams(query);

            return(topStreams.Select(x =>
            {
                var channelIdentifier = new ChannelIdentifier(this, x.UserId)
                {
                    DisplayName = x.UserName
                };
                var queryResult = new LivestreamQueryResult(channelIdentifier);
                var livestreamModel = new LivestreamModel(x.UserId, channelIdentifier);
                livestreamModel.PopulateWithStreamDetails(x);

                queryResult.LivestreamModel = livestreamModel;
                return queryResult;
            }).ToList());
        }
示例#2
0
        private async Task <LivestreamQueryResult> QueryChannel(ChannelIdentifier channelIdentifier, CancellationToken cancellationToken)
        {
            var queryResult = new LivestreamQueryResult(channelIdentifier);

            try
            {
                var channel = await beamProClient.GetStreamDetails(channelIdentifier.ChannelId, cancellationToken);

                channelNameIdMap[channel.token] = channel.id; // record the mapping of the channels token/name to its underlying id
                var livestreamModel = ConvertToLivestreamModel(channel);
                queryResult.LivestreamModel = livestreamModel;
            }
            catch (Exception ex)
            {
                queryResult.FailedQueryException = new FailedQueryException(channelIdentifier, ex);
            }

            return(queryResult);
        }
示例#3
0
        public async Task <List <LivestreamQueryResult> > GetTopStreams(TopStreamQuery topStreamQuery)
        {
            if (topStreamQuery == null)
            {
                throw new ArgumentNullException(nameof(topStreamQuery));
            }
            var topStreams = await twitchTvClient.GetTopStreams(topStreamQuery);

            return(topStreams.Select(x =>
            {
                var channelIdentifier = new ChannelIdentifier(this, x.Channel.Name);
                var queryResult = new LivestreamQueryResult(channelIdentifier);
                var livestreamModel = new LivestreamModel(x.Channel?.Name, channelIdentifier);
                livestreamModel.PopulateWithStreamDetails(x);
                livestreamModel.PopulateWithChannel(x.Channel);

                queryResult.LivestreamModel = livestreamModel;
                return queryResult;
            }).ToList());
        }
示例#4
0
 private Task <List <LivestreamQueryResult> > QueryChannels(
     IReadOnlyCollection <ChannelIdentifier> identifiers,
     CancellationToken cancellationToken)
 {
     return(identifiers.ExecuteInParallel(
                query: async channelIdentifier =>
     {
         var queryResult = new LivestreamQueryResult(channelIdentifier);
         try
         {
             var livestream = await hitboxClient.GetChannelDetails(channelIdentifier.ChannelId, cancellationToken);
             queryResult.LivestreamModel = ConvertToLivestreamModel(livestream);
         }
         catch (Exception ex)
         {
             queryResult.FailedQueryException = new FailedQueryException(channelIdentifier, ex);
         }
         return queryResult;
     },
                timeout: Constants.HalfRefreshPollingTime,
                cancellationToken: cancellationToken));
 }
示例#5
0
        private async Task <List <LivestreamQueryResult> > GetOfflineStreamQueryResults(
            IEnumerable <ChannelIdentifier> offlineChannels,
            CancellationToken cancellationToken)
        {
            return(await offlineChannels.ExecuteInParallel(async channelIdentifier =>
            {
                var queryResult = new LivestreamQueryResult(channelIdentifier);
                try
                {
                    var channel = await twitchTvClient.GetChannelDetails(channelIdentifier.ChannelId, cancellationToken);
                    queryResult.LivestreamModel = new LivestreamModel(channelIdentifier.ChannelId, channelIdentifier);
                    queryResult.LivestreamModel.PopulateWithChannel(channel);
                    queryResult.LivestreamModel.Offline();
                }
                catch (Exception ex)
                {
                    queryResult.FailedQueryException = new FailedQueryException(channelIdentifier, ex);
                }

                return queryResult;
            }, Constants.HalfRefreshPollingTime, cancellationToken));
        }
        public async Task <List <LivestreamQueryResult> > QueryChannels(CancellationToken cancellationToken)
        {
            var queryResults = new List <LivestreamQueryResult>();

            if (moniteredChannels.Count == 0)
            {
                return(queryResults);
            }

            // Twitch "get streams" call only returns online streams so to determine if the stream actually exists/is still valid, we must specifically ask for channel details.
            List <Stream> onlineStreams = new List <Stream>();

            int  retryCount = 0;
            bool success    = false;

            while (!success && !cancellationToken.IsCancellationRequested && retryCount < 3)
            {
                try
                {
                    var query = new GetStreamsQuery();
                    query.UserIds.AddRange(moniteredChannels.Select(x => x.ChannelId));
                    onlineStreams = await twitchTvHelixClient.GetStreams(query, cancellationToken);

                    success = true;
                }
                catch (HttpRequestWithStatusException ex) when(ex.StatusCode == HttpStatusCode.ServiceUnavailable)
                {
                    await Task.Delay(2000, cancellationToken);

                    retryCount++;
                }
            }

            foreach (var onlineStream in onlineStreams)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(queryResults);
                }

                var channelIdentifier = moniteredChannels.First(x => x.ChannelId.IsEqualTo(onlineStream.UserId));
                var gameName          = await GetGameNameById(onlineStream.GameId);

                var livestream = new LivestreamModel(onlineStream.UserId, channelIdentifier);
                livestream.PopulateWithStreamDetails(onlineStream);
                livestream.Game = gameName;
                queryResults.Add(new LivestreamQueryResult(channelIdentifier)
                {
                    LivestreamModel = livestream
                });
            }

            var offlineStreams = moniteredChannels.Where(x => onlineStreams.All(y => y.UserId != x.ChannelId)).ToList();

            foreach (var offlineStream in offlineStreams)
            {
                var queryResult = new LivestreamQueryResult(offlineStream)
                {
                    LivestreamModel = new LivestreamModel(offlineStream.ChannelId, offlineStream)
                    {
                        DisplayName = offlineStream.DisplayName ?? offlineStream.ChannelId
                    }
                };

                queryResults.Add(queryResult);
            }

            return(queryResults);
        }