/// <summary> /// Gets the metadata associated with the specified playlist. /// </summary> public async Task <Playlist> GetAsync(PlaylistId id) { var response = await PlaylistResponse.GetAsync(_httpClient, id); return(new Playlist( id, response.TryGetAuthor(), response.GetTitle(), response.TryGetDescription() ?? "", new Engagement( response.TryGetViewCount() ?? 0, response.TryGetLikeCount() ?? 0, response.TryGetDislikeCount() ?? 0 ) )); }
/// <summary> /// Enumerates videos included in the specified playlist. /// </summary> public async IAsyncEnumerable <PlaylistVideo> GetVideosAsync(PlaylistId id) { var encounteredVideoIds = new HashSet <string>(); var continuationToken = ""; while (true) { var response = await PlaylistResponse.GetAsync(_httpClient, id, continuationToken); foreach (var video in response.GetPlaylistVideos()) { var videoId = video.GetId(); // Skip already encountered videos if (!encounteredVideoIds.Add(videoId)) { continue; } // Skip deleted videos if (string.IsNullOrEmpty(video.GetChannelId())) { continue; } yield return(new PlaylistVideo( videoId, video.GetTitle(), video.GetAuthor(), video.GetChannelId(), video.GetDescription(), video.GetDuration(), video.GetViewCount(), new ThumbnailSet(videoId) )); } continuationToken = response.TryGetContinuationToken(); if (string.IsNullOrEmpty(continuationToken)) { break; } } }
/// <summary> /// Gets the metadata associated with the specified playlist. /// </summary> public async Task <Playlist> GetAsync(PlaylistId id) { var response = await PlaylistResponse.GetAsync(_httpClient, id); var thumbnails = response .GetPlaylistVideos() .FirstOrDefault()? .GetId() .Pipe(i => new ThumbnailSet(i)); return(new Playlist( id, response.TryGetTitle() ?? "", response.TryGetAuthor() ?? "", response.TryGetDescription() ?? "", response.TryGetViewCount() ?? 0, thumbnails )); }
/// <summary> /// Enumerates batches of videos included in the specified playlist. /// </summary> public async IAsyncEnumerable <Batch <PlaylistVideo> > GetVideoBatchesAsync( PlaylistId playlistId, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var encounteredIds = new HashSet <string>(StringComparer.Ordinal); var continuationToken = default(string?); do { var playlistExtractor = await _controller.GetPlaylistAsync(playlistId, continuationToken, cancellationToken); var videos = new List <PlaylistVideo>(); foreach (var videoExtractor in playlistExtractor.GetVideos()) { var videoId = videoExtractor.TryGetVideoId() ?? throw new YoutubeExplodeException("Could not extract video ID."); // Don't yield the same video twice if (!encounteredIds.Add(videoId)) { continue; } var videoTitle = videoExtractor.TryGetVideoTitle() ?? throw new YoutubeExplodeException("Could not extract video title."); var videoChannelTitle = videoExtractor.TryGetVideoAuthor() ?? throw new YoutubeExplodeException("Could not extract video author."); var videoChannelId = videoExtractor.TryGetVideoChannelId() ?? throw new YoutubeExplodeException("Could not extract video channel ID."); var duration = videoExtractor.TryGetVideoDuration(); var thumbnails = videoExtractor .GetVideoThumbnails() .Select(t => { var thumbnailUrl = t.TryGetUrl() ?? throw new YoutubeExplodeException("Could not extract thumbnail URL."); var thumbnailWidth = t.TryGetWidth() ?? throw new YoutubeExplodeException("Could not extract thumbnail width."); var thumbnailHeight = t.TryGetHeight() ?? throw new YoutubeExplodeException("Could not extract thumbnail height."); var thumbnailResolution = new Resolution(thumbnailWidth, thumbnailHeight); return(new Thumbnail(thumbnailUrl, thumbnailResolution)); }) .Concat(Thumbnail.GetDefaultSet(videoId)) .ToArray(); var video = new PlaylistVideo( videoId, videoTitle, new Author(videoChannelId, videoChannelTitle), duration, thumbnails ); videos.Add(video); } yield return(Batch.Create(videos)); continuationToken = playlistExtractor.TryGetContinuationToken(); } while (!string.IsNullOrWhiteSpace(continuationToken)); }
/// <summary> /// Enumerates videos included in the specified playlist. /// </summary> public IAsyncEnumerable <PlaylistVideo> GetVideosAsync( PlaylistId playlistId, CancellationToken cancellationToken = default) => GetVideoBatchesAsync(playlistId, cancellationToken).FlattenAsync();