private async Task StopRecording(DataModels.Channel channel) { var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "NjBjZDBjYzlkNTNlOGViZDc3YWYyZGE2ZDNhN2EyZjQ5YWNmODk1YTo="); var resp = await client.PostAsync("https://a.streamhoster.com/v1/papi/media/stream/" + channel.ChannelKey.Remove(channel.ChannelKey.Length - 2) + "/record", new StringContent("{\"recordMode\":\"manual_off\"}", Encoding.UTF8, "application/json")); await resp.Content.ReadAsByteArrayAsync(); }
private async Task ClearChannelStreamInfo(DataModels.Channel channel) { channel.StreamTitle = null; channel.StreamSubject = null; channel.StreamDescription = null; channel.StreamThumbnail = null; channel.StreamColor = null; channel.ArchivedVideoId = null; channel.Views = 0; await Save(channel.Id, channel); }
private Video GetVideo(DataModels.Channel channel) { Video archivedStream = new Video { Id = channel.ArchivedVideoId, Username = channel.Username, StreamID = "", StreamTitle = channel.StreamTitle, StreamSubject = channel.StreamSubject, StreamDescription = channel.StreamDescription, StreamThumbnail = channel.StreamThumbnail, ProfilePicture = channel.ProfilePicture, StreamColor = channel.StreamColor, StartTime = DateTime.UtcNow, Name = channel.Name, Views = channel.Views }; return(archivedStream); }
private async Task ArchiveVideo(StreamHosterRSSFeed response, DataModels.Channel channel) { List <Video> videos = new List <Video>(); streamHandler.TryGetValue(channel.Username, out videos); var ids = GetVideoIdsWithId(channel.ChannelKey, videos.Count, response); videos.Reverse(); //reverse list content for (int i = 0; i < videos.Count; i++) //go through the response as well as the dict and associate each stream to its object { var video = videos[i]; video.StreamID = ids[i]; await Save(video.Id, video); } channel.InitialStreamCount = 0; await Save(channel.Id, channel); streamHandler.TryRemove(channel.Username, out _); }
private async Task RunLive(DataModels.Channel channel) { var cancellationToken = new CancellationToken(); await Task.Factory.StartNew(async() => { await StartRecording(channel); while (true) { await Task.Delay(37000, cancellationToken); try { var response = await IsLive(channel.ChannelKey); if (response) { Console.WriteLine("Live"); } else { Console.WriteLine("Not Live"); await StopRecording(channel); await Task.Delay(20000, cancellationToken); await PollVideo(channel); break; } } catch (Exception ex) { log.Error(ex, "Error in RunLive Method"); } } log.Warning("Thread Finished|" + channel.Username); Console.WriteLine("Thread Finished|" + channel.Username); }, TaskCreationOptions.LongRunning); }
private async Task PollVideo(DataModels.Channel channel) //This thread handles checking if the stream is still live { var archivedVideo = GetVideo(channel); //Get video information from channel await ClearChannelStreamInfo(channel); //clear all channel info if (streamHandler.ContainsKey(channel.Username)) //check if the concurrent dict has the key with the specified username, if it does this means that a thread has already been spawned looking for this video in the rss feed { List <Video> oldvideos = new List <Video>(); List <Video> videos = new List <Video>(); streamHandler.TryGetValue(channel.Username, out videos); //add the video info to the list of videos in the concurrent dictionary streamHandler.TryGetValue(channel.Username, out oldvideos); videos.Add(archivedVideo); streamHandler.TryUpdate(channel.Username, videos, oldvideos); } else { streamHandler.TryAdd(channel.Username, new List <Video> { archivedVideo }); //create a new list and add the archived video info into the list StreamHosterRSSFeed initialResponse = await CallXML <StreamHosterRSSFeed>("https://c.streamhoster.com/feed/WxsdDM/mAe0epZsixC/iAahx7oSswv?format=mrss"); //feed contains all the archived videos and we use it to get the stream id for each video if (initialResponse != null && initialResponse.Channel.Item != null) { channel.InitialStreamCount = GetNumberOfVideosWithId(channel.ChannelKey, initialResponse); //check for initial count of the rss feed await Save(channel.Id, channel); } while (true) //looking for the initial count of the feed + how many items are in the video list. The video list is retreived by the username of the current user { try { await Task.Delay(30000); StreamHosterRSSFeed response = await CallXML <StreamHosterRSSFeed>("https://c.streamhoster.com/feed/WxsdDM/mAe0epZsixC/iAahx7oSswv?format=mrss"); if (response != null) { List <Video> videos = new List <Video>(); streamHandler.TryGetValue(channel.Username, out videos); Debug d = new Debug(); d.Id = Guid.NewGuid().ToString(); d.Timestamp = DateTime.UtcNow; d.Message = channel.Username + " | " + (GetNumberOfVideosWithId(channel.ChannelKey, response)); await Save(d.Id, d); log.Warning(channel.Username + " is still in the while loop"); log.Warning(channel.Username + " " + GetNumberOfVideosWithId(channel.ChannelKey, response) + " Initial Count: " + channel.InitialStreamCount + " Video Count:" + videos.Count); if (response.Channel.Item != null && (GetNumberOfVideosWithId(channel.ChannelKey, response) >= channel.InitialStreamCount + videos.Count)) // we keep polling until the feed is updated to the number of videos (the initial count & concurrent dict count) { Debug d1 = new Debug(); d1.Id = Guid.NewGuid().ToString(); d.Timestamp = DateTime.UtcNow; d1.Message = channel.Username + " | Videos Found | " + channel.InitialStreamCount + videos.Count; await Save(d1.Id, d1); Console.WriteLine("Videos Found"); await ArchiveVideo(response, channel); break; } } else { log.Warning("response is null in poll for " + channel.Username); Console.WriteLine("response is null in poll for " + channel.Username); } } catch (Exception e) { log.Error(e, "Error in Poll"); break; } } } }