70 lines
1.9 KiB
Dart
70 lines
1.9 KiB
Dart
import '../channels/channel_id.dart';
|
|
import '../common/common.dart';
|
|
import '../reverse_engineering/pages/playlist_page.dart';
|
|
import '../reverse_engineering/youtube_http_client.dart';
|
|
import '../videos/video.dart';
|
|
import '../videos/video_id.dart';
|
|
import 'playlist.dart';
|
|
import 'playlist_id.dart';
|
|
|
|
/// Queries related to YouTube playlists.
|
|
class PlaylistClient {
|
|
final YoutubeHttpClient _httpClient;
|
|
|
|
/// Initializes an instance of [PlaylistClient]
|
|
PlaylistClient(this._httpClient);
|
|
|
|
/// Gets the metadata associated with the specified playlist.
|
|
Future<Playlist> get(dynamic id) async {
|
|
id = PlaylistId.fromString(id);
|
|
|
|
var response = await PlaylistPage.get(_httpClient, (id as PlaylistId).value);
|
|
return Playlist(
|
|
id,
|
|
response.title ?? '',
|
|
response.author ?? '',
|
|
response.description ?? '',
|
|
ThumbnailSet(id.value),
|
|
Engagement(response.viewCount ?? 0, null, null),
|
|
response.videoCount);
|
|
}
|
|
|
|
/// Enumerates videos included in the specified playlist.
|
|
Stream<Video> getVideos(dynamic id) async* {
|
|
id = PlaylistId.fromString(id);
|
|
final encounteredVideoIds = <String>{};
|
|
|
|
PlaylistPage? page = await PlaylistPage.get(_httpClient, id.value);
|
|
|
|
while (page != null) {
|
|
for (final video in page.videos) {
|
|
var videoId = video.id;
|
|
|
|
// Already added
|
|
if (!encounteredVideoIds.add(videoId)) {
|
|
continue;
|
|
}
|
|
|
|
if (video.channelId.isEmpty) {
|
|
continue;
|
|
}
|
|
|
|
yield Video(
|
|
VideoId(videoId),
|
|
video.title,
|
|
video.author,
|
|
ChannelId(video.channelId),
|
|
null,
|
|
null,
|
|
video.description,
|
|
video.duration,
|
|
ThumbnailSet(videoId),
|
|
null,
|
|
Engagement(video.viewCount, null, null),
|
|
false);
|
|
}
|
|
page = await page.nextPage(_httpClient);
|
|
}
|
|
}
|
|
}
|