async IAsyncEnumerable <IReadOnlyCollection <VideoItem> > PlaylistVideos(string playlistId, JToken playlistJson, ILogger log) { var index = playlistId.StartsWith("PL", StringComparison.OrdinalIgnoreCase) ? 101 : 0; var videoIds = new HashSet <string>(); do { // Get videos var newVideos = new List <VideoItem>(); foreach (var videoJson in playlistJson.SelectToken("video").NotNull()) { var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero); // Extract video info var videoId = videoJson.SelectToken("encrypted_id").Value <string>(); var videoAuthor = videoJson.SelectToken("author").Value <string>(); var videoUploadDate = epoch + TimeSpan.FromSeconds(videoJson.SelectToken("time_created").Value <long>()); var videoTitle = videoJson.SelectToken("title").Value <string>(); var videoDescription = videoJson.SelectToken("description").Value <string>(); var videoDuration = TimeSpan.FromSeconds(videoJson.SelectToken("length_seconds").Value <double>()); var videoViewCount = videoJson.SelectToken("views").Value <string>().StripNonDigit().ParseLong(); var videoLikeCount = videoJson.SelectToken("likes").Value <long>(); var videoDislikeCount = videoJson.SelectToken("dislikes").Value <long>(); // Extract video keywords var videoKeywordsJoined = videoJson.SelectToken("keywords").Value <string>(); var videoKeywords = Regex.Matches(videoKeywordsJoined, "\"[^\"]+\"|\\S+") .Select(m => m.Value) .Where(s => !s.IsNullOrWhiteSpace()) .Select(s => s.Trim('"')) .ToArray(); // Create statistics and thumbnails var videoStatistics = new Statistics(videoViewCount, videoLikeCount, videoDislikeCount); var videoThumbnails = new ThumbnailSet(videoId); // Add video to the list if it's not already there if (videoIds.Add(videoId)) { var video = new VideoItem(videoId, videoAuthor, videoUploadDate, videoTitle, videoDescription, videoThumbnails, videoDuration, videoKeywords, videoStatistics, null, null); // TODO: is channelId in the playlist? newVideos.Add(video); } } // If no distinct videos were added to the list - break if (newVideos.Count == 0) { yield break; } yield return(newVideos); // Advance index index += 100; playlistJson = await GetPlaylistJsonAsync(playlistId, index, log); } while (true); }
/// <summary> /// Initializes an instance of <see cref="Video" />. /// </summary> public VideoItem(string id, string author, DateTimeOffset uploadDate, string title, string description, ThumbnailSet thumbnails, TimeSpan duration, IReadOnlyList <string> keywords, Statistics statistics) { Id = id; Author = author; UploadDate = uploadDate; Title = title; Description = description; Thumbnails = thumbnails; Duration = duration; Keywords = keywords; Statistics = statistics; }