youtube_explode/lib/src/videos/video_client.dart

88 lines
2.8 KiB
Dart
Raw Normal View History

2020-06-30 01:00:37 +02:00
import '../channels/channel_id.dart';
2020-06-03 23:02:21 +02:00
import '../common/common.dart';
import '../exceptions/exceptions.dart';
2020-06-03 23:02:21 +02:00
import '../reverse_engineering/responses/responses.dart';
import '../reverse_engineering/youtube_http_client.dart';
import 'closed_captions/closed_caption_client.dart';
import 'comments/comments_client.dart';
2020-06-03 23:02:21 +02:00
import 'videos.dart';
/// Queries related to YouTube videos.
class VideoClient {
final YoutubeHttpClient _httpClient;
/// Queries related to media streams of YouTube videos.
final StreamsClient streamsClient;
/// Queries related to closed captions of YouTube videos.
final ClosedCaptionClient closedCaptions;
/// Queries related to a YouTube video.
final CommentsClient commentsClient;
2020-06-03 23:02:21 +02:00
/// Initializes an instance of [VideoClient].
VideoClient(this._httpClient)
: streamsClient = StreamsClient(_httpClient),
closedCaptions = ClosedCaptionClient(_httpClient),
commentsClient = CommentsClient(_httpClient);
2020-06-03 23:02:21 +02:00
/// Gets the metadata associated with the specified video.
Future<Video> _getVideoFromWatchPage(VideoId videoId) async {
2020-06-05 20:08:04 +02:00
var videoInfoResponse =
await VideoInfoResponse.get(_httpClient, videoId.value);
2020-06-03 23:02:21 +02:00
var playerResponse = videoInfoResponse.playerResponse;
2020-06-05 20:08:04 +02:00
var watchPage = await WatchPage.get(_httpClient, videoId.value);
2020-06-03 23:02:21 +02:00
return Video(
2020-06-05 20:08:04 +02:00
videoId,
2020-06-03 23:02:21 +02:00
playerResponse.videoTitle,
playerResponse.videoAuthor,
2020-06-30 01:00:37 +02:00
ChannelId(playerResponse.videoChannelId),
2020-06-03 23:02:21 +02:00
playerResponse.videoUploadDate,
playerResponse.videoDescription,
playerResponse.videoDuration,
2020-06-05 20:08:04 +02:00
ThumbnailSet(videoId.value),
2020-06-03 23:02:21 +02:00
playerResponse.videoKeywords,
Engagement(playerResponse.videoViewCount ?? 0, watchPage.videoLikeCount,
watchPage.videoDislikeCount),
watchPage);
2020-06-03 23:02:21 +02:00
}
Future<Video> _getVideoFromFixPlaylist(VideoId id) async {
var playlistInfo = await PlaylistResponse.get(_httpClient, 'RD${id.value}');
2020-08-15 15:32:01 +02:00
var video = playlistInfo.videos
.firstWhere((e) => e.id == id.value, orElse: () => null);
if (video == null) {
throw TransientFailureException('Video not found in mix playlist');
}
return Video(
id,
video.title,
video.author,
video.channelId,
video.uploadDate,
video.description,
video.duration,
ThumbnailSet(id.value),
video.keywords,
Engagement(video.viewCount, video.likes, video.dislikes));
}
/// Get a [Video] instance from a [videoId]
2020-11-01 15:05:19 +01:00
Future<Video> get(dynamic videoId, {bool forceWatchPage = false}) async {
videoId = VideoId.fromString(videoId);
2020-09-21 17:34:03 +02:00
if (forceWatchPage) {
return _getVideoFromWatchPage(videoId);
}
try {
return await _getVideoFromFixPlaylist(videoId);
} on YoutubeExplodeException {
return _getVideoFromWatchPage(videoId);
}
}
2020-06-03 23:02:21 +02:00
}