Implement json serialization for streams. #94

This commit is contained in:
Mattia 2021-11-12 21:04:53 +01:00
parent f1c1d465c0
commit 37fbb3fdea
52 changed files with 852 additions and 578 deletions

View File

@ -3,10 +3,9 @@ import 'package:youtube_explode_dart/youtube_explode_dart.dart';
Future<void> main() async {
var yt = YoutubeExplode();
var video =
await yt.videos.get('https://www.youtube.com/watch?v=AI7ULzgf8RU');
var streamInfo = await yt.videos.streamsClient.getManifest('fRh_vgS2dFE');
print('Title: ${video.title}');
print(streamInfo);
// Close the YoutubeExplode's http client.
yt.close();

View File

@ -182,26 +182,18 @@ class _$_Channel extends _Channel {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Channel &&
(identical(other.id, id) ||
const DeepCollectionEquality().equals(other.id, id)) &&
(identical(other.title, title) ||
const DeepCollectionEquality().equals(other.title, title)) &&
(identical(other.logoUrl, logoUrl) ||
const DeepCollectionEquality()
.equals(other.logoUrl, logoUrl)) &&
(other.runtimeType == runtimeType &&
other is _Channel &&
(identical(other.id, id) || other.id == id) &&
(identical(other.title, title) || other.title == title) &&
(identical(other.logoUrl, logoUrl) || other.logoUrl == logoUrl) &&
(identical(other.subscribersCount, subscribersCount) ||
const DeepCollectionEquality()
.equals(other.subscribersCount, subscribersCount)));
other.subscribersCount == subscribersCount));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(id) ^
const DeepCollectionEquality().hash(title) ^
const DeepCollectionEquality().hash(logoUrl) ^
const DeepCollectionEquality().hash(subscribersCount);
Object.hash(runtimeType, id, title, logoUrl, subscribersCount);
@JsonKey(ignore: true)
@override
@ -218,19 +210,19 @@ abstract class _Channel extends Channel {
@override
/// Channel ID.
ChannelId get id => throw _privateConstructorUsedError;
ChannelId get id;
@override
/// Channel title.
String get title => throw _privateConstructorUsedError;
String get title;
@override
/// URL of the channel's logo image.
String get logoUrl => throw _privateConstructorUsedError;
String get logoUrl;
@override
/// The (approximate) channel subscriber's count.
int? get subscribersCount => throw _privateConstructorUsedError;
int? get subscribersCount;
@override
@JsonKey(ignore: true)
_$ChannelCopyWith<_Channel> get copyWith =>

View File

@ -249,39 +249,32 @@ class _$_ChannelAbout implements _ChannelAbout {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ChannelAbout &&
(other.runtimeType == runtimeType &&
other is _ChannelAbout &&
(identical(other.description, description) ||
const DeepCollectionEquality()
.equals(other.description, description)) &&
other.description == description) &&
(identical(other.viewCount, viewCount) ||
const DeepCollectionEquality()
.equals(other.viewCount, viewCount)) &&
other.viewCount == viewCount) &&
(identical(other.joinDate, joinDate) ||
const DeepCollectionEquality()
.equals(other.joinDate, joinDate)) &&
(identical(other.title, title) ||
const DeepCollectionEquality().equals(other.title, title)) &&
(identical(other.thumbnails, thumbnails) ||
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails)) &&
(identical(other.country, country) ||
const DeepCollectionEquality()
.equals(other.country, country)) &&
(identical(other.channelLinks, channelLinks) ||
const DeepCollectionEquality()
.equals(other.channelLinks, channelLinks)));
other.joinDate == joinDate) &&
(identical(other.title, title) || other.title == title) &&
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails) &&
(identical(other.country, country) || other.country == country) &&
const DeepCollectionEquality()
.equals(other.channelLinks, channelLinks));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(description) ^
const DeepCollectionEquality().hash(viewCount) ^
const DeepCollectionEquality().hash(joinDate) ^
const DeepCollectionEquality().hash(title) ^
const DeepCollectionEquality().hash(thumbnails) ^
const DeepCollectionEquality().hash(country) ^
const DeepCollectionEquality().hash(channelLinks);
int get hashCode => Object.hash(
runtimeType,
description,
viewCount,
joinDate,
title,
const DeepCollectionEquality().hash(thumbnails),
country,
const DeepCollectionEquality().hash(channelLinks));
@JsonKey(ignore: true)
@override
@ -302,32 +295,32 @@ abstract class _ChannelAbout implements ChannelAbout {
@override
/// Full channel description.
String get description => throw _privateConstructorUsedError;
String get description;
@override
/// Channel view count.
int get viewCount => throw _privateConstructorUsedError;
int get viewCount;
@override
/// Channel join date.
/// Formatted as: Gen 01, 2000
String get joinDate => throw _privateConstructorUsedError;
String get joinDate;
@override
/// Channel title.
String get title => throw _privateConstructorUsedError;
String get title;
@override
/// Channel thumbnails.
List<Thumbnail> get thumbnails => throw _privateConstructorUsedError;
List<Thumbnail> get thumbnails;
@override
/// Channel country.
String get country => throw _privateConstructorUsedError;
String get country;
@override
/// Channel links.
List<ChannelLink> get channelLinks => throw _privateConstructorUsedError;
List<ChannelLink> get channelLinks;
@override
@JsonKey(ignore: true)
_$ChannelAboutCopyWith<_ChannelAbout> get copyWith =>

View File

@ -109,14 +109,13 @@ class _$_ChannelId extends _ChannelId {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ChannelId &&
(identical(other.value, value) ||
const DeepCollectionEquality().equals(other.value, value)));
(other.runtimeType == runtimeType &&
other is _ChannelId &&
(identical(other.value, value) || other.value == value));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(value);
int get hashCode => Object.hash(runtimeType, value);
@JsonKey(ignore: true)
@override
@ -131,7 +130,7 @@ abstract class _ChannelId extends ChannelId {
@override
/// ID as a string.
String get value => throw _privateConstructorUsedError;
String get value;
@override
@JsonKey(ignore: true)
_$ChannelIdCopyWith<_ChannelId> get copyWith =>

View File

@ -155,21 +155,15 @@ class _$_ChannelLink implements _ChannelLink {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ChannelLink &&
(identical(other.title, title) ||
const DeepCollectionEquality().equals(other.title, title)) &&
(identical(other.url, url) ||
const DeepCollectionEquality().equals(other.url, url)) &&
(identical(other.icon, icon) ||
const DeepCollectionEquality().equals(other.icon, icon)));
(other.runtimeType == runtimeType &&
other is _ChannelLink &&
(identical(other.title, title) || other.title == title) &&
(identical(other.url, url) || other.url == url) &&
(identical(other.icon, icon) || other.icon == icon));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(title) ^
const DeepCollectionEquality().hash(url) ^
const DeepCollectionEquality().hash(icon);
int get hashCode => Object.hash(runtimeType, title, url, icon);
@JsonKey(ignore: true)
@override
@ -183,16 +177,16 @@ abstract class _ChannelLink implements ChannelLink {
@override
/// Link title.
String get title => throw _privateConstructorUsedError;
String get title;
@override
/// Link URL.
/// Already decoded with the YouTube shortener already taken out.
Uri get url => throw _privateConstructorUsedError;
Uri get url;
@override
/// Link Icon URL.
Uri get icon => throw _privateConstructorUsedError;
Uri get icon;
@override
@JsonKey(ignore: true)
_$ChannelLinkCopyWith<_ChannelLink> get copyWith =>

View File

@ -235,36 +235,24 @@ class _$_ChannelVideo implements _ChannelVideo {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ChannelVideo &&
(identical(other.videoId, videoId) ||
const DeepCollectionEquality()
.equals(other.videoId, videoId)) &&
(other.runtimeType == runtimeType &&
other is _ChannelVideo &&
(identical(other.videoId, videoId) || other.videoId == videoId) &&
(identical(other.videoTitle, videoTitle) ||
const DeepCollectionEquality()
.equals(other.videoTitle, videoTitle)) &&
other.videoTitle == videoTitle) &&
(identical(other.videoDuration, videoDuration) ||
const DeepCollectionEquality()
.equals(other.videoDuration, videoDuration)) &&
other.videoDuration == videoDuration) &&
(identical(other.videoThumbnail, videoThumbnail) ||
const DeepCollectionEquality()
.equals(other.videoThumbnail, videoThumbnail)) &&
other.videoThumbnail == videoThumbnail) &&
(identical(other.videoUploadDate, videoUploadDate) ||
const DeepCollectionEquality()
.equals(other.videoUploadDate, videoUploadDate)) &&
other.videoUploadDate == videoUploadDate) &&
(identical(other.videoViews, videoViews) ||
const DeepCollectionEquality()
.equals(other.videoViews, videoViews)));
other.videoViews == videoViews));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(videoId) ^
const DeepCollectionEquality().hash(videoTitle) ^
const DeepCollectionEquality().hash(videoDuration) ^
const DeepCollectionEquality().hash(videoThumbnail) ^
const DeepCollectionEquality().hash(videoUploadDate) ^
const DeepCollectionEquality().hash(videoViews);
int get hashCode => Object.hash(runtimeType, videoId, videoTitle,
videoDuration, videoThumbnail, videoUploadDate, videoViews);
@JsonKey(ignore: true)
@override
@ -284,28 +272,28 @@ abstract class _ChannelVideo implements ChannelVideo {
@override
/// Video ID.
VideoId get videoId => throw _privateConstructorUsedError;
VideoId get videoId;
@override
/// Video title.
String get videoTitle => throw _privateConstructorUsedError;
String get videoTitle;
@override
/// Video duration
Duration get videoDuration => throw _privateConstructorUsedError;
Duration get videoDuration;
@override
/// Video thumbnail
String get videoThumbnail => throw _privateConstructorUsedError;
String get videoThumbnail;
@override
/// Video upload date.
/// Formatted like 10 hours ago
String get videoUploadDate => throw _privateConstructorUsedError;
String get videoUploadDate;
@override
/// Video view count.
int get videoViews => throw _privateConstructorUsedError;
int get videoViews;
@override
@JsonKey(ignore: true)
_$ChannelVideoCopyWith<_ChannelVideo> get copyWith =>

View File

@ -113,14 +113,13 @@ class _$_Username implements _Username {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Username &&
(identical(other.value, value) ||
const DeepCollectionEquality().equals(other.value, value)));
(other.runtimeType == runtimeType &&
other is _Username &&
(identical(other.value, value) || other.value == value));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(value);
int get hashCode => Object.hash(runtimeType, value);
@JsonKey(ignore: true)
@override
@ -134,7 +133,7 @@ abstract class _Username implements Username {
@override
/// User name as string.
String get value => throw _privateConstructorUsedError;
String get value;
@override
@JsonKey(ignore: true)
_$UsernameCopyWith<_Username> get copyWith =>

View File

@ -153,24 +153,19 @@ class _$_Engagement extends _Engagement {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Engagement &&
(other.runtimeType == runtimeType &&
other is _Engagement &&
(identical(other.viewCount, viewCount) ||
const DeepCollectionEquality()
.equals(other.viewCount, viewCount)) &&
other.viewCount == viewCount) &&
(identical(other.likeCount, likeCount) ||
const DeepCollectionEquality()
.equals(other.likeCount, likeCount)) &&
other.likeCount == likeCount) &&
(identical(other.dislikeCount, dislikeCount) ||
const DeepCollectionEquality()
.equals(other.dislikeCount, dislikeCount)));
other.dislikeCount == dislikeCount));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(viewCount) ^
const DeepCollectionEquality().hash(likeCount) ^
const DeepCollectionEquality().hash(dislikeCount);
Object.hash(runtimeType, viewCount, likeCount, dislikeCount);
@JsonKey(ignore: true)
@override
@ -186,15 +181,15 @@ abstract class _Engagement extends Engagement {
@override
/// View count.
int get viewCount => throw _privateConstructorUsedError;
int get viewCount;
@override
/// Like count.
int? get likeCount => throw _privateConstructorUsedError;
int? get likeCount;
@override
/// Dislike count.
int? get dislikeCount => throw _privateConstructorUsedError;
int? get dislikeCount;
@override
@JsonKey(ignore: true)
_$EngagementCopyWith<_Engagement> get copyWith =>

View File

@ -150,21 +150,15 @@ class _$_Thumbnail implements _Thumbnail {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Thumbnail &&
(identical(other.url, url) ||
const DeepCollectionEquality().equals(other.url, url)) &&
(identical(other.height, height) ||
const DeepCollectionEquality().equals(other.height, height)) &&
(identical(other.width, width) ||
const DeepCollectionEquality().equals(other.width, width)));
(other.runtimeType == runtimeType &&
other is _Thumbnail &&
(identical(other.url, url) || other.url == url) &&
(identical(other.height, height) || other.height == height) &&
(identical(other.width, width) || other.width == width));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(url) ^
const DeepCollectionEquality().hash(height) ^
const DeepCollectionEquality().hash(width);
int get hashCode => Object.hash(runtimeType, url, height, width);
@JsonKey(ignore: true)
@override
@ -178,15 +172,15 @@ abstract class _Thumbnail implements Thumbnail {
@override
/// Image url.
Uri get url => throw _privateConstructorUsedError;
Uri get url;
@override
/// Image height.
int get height => throw _privateConstructorUsedError;
int get height;
@override
/// Image width.
int get width => throw _privateConstructorUsedError;
int get width;
@override
@JsonKey(ignore: true)
_$ThumbnailCopyWith<_Thumbnail> get copyWith =>

View File

@ -117,14 +117,13 @@ class _$_ThumbnailSet extends _ThumbnailSet {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ThumbnailSet &&
(identical(other.videoId, videoId) ||
const DeepCollectionEquality().equals(other.videoId, videoId)));
(other.runtimeType == runtimeType &&
other is _ThumbnailSet &&
(identical(other.videoId, videoId) || other.videoId == videoId));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(videoId);
int get hashCode => Object.hash(runtimeType, videoId);
@JsonKey(ignore: true)
@override
@ -139,7 +138,7 @@ abstract class _ThumbnailSet extends ThumbnailSet {
@override
/// Video id.
String get videoId => throw _privateConstructorUsedError;
String get videoId;
@override
@JsonKey(ignore: true)
_$ThumbnailSetCopyWith<_ThumbnailSet> get copyWith =>

View File

@ -274,37 +274,24 @@ class _$_Playlist extends _Playlist {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Playlist &&
(identical(other.id, id) ||
const DeepCollectionEquality().equals(other.id, id)) &&
(identical(other.title, title) ||
const DeepCollectionEquality().equals(other.title, title)) &&
(identical(other.author, author) ||
const DeepCollectionEquality().equals(other.author, author)) &&
(other.runtimeType == runtimeType &&
other is _Playlist &&
(identical(other.id, id) || other.id == id) &&
(identical(other.title, title) || other.title == title) &&
(identical(other.author, author) || other.author == author) &&
(identical(other.description, description) ||
const DeepCollectionEquality()
.equals(other.description, description)) &&
other.description == description) &&
(identical(other.thumbnails, thumbnails) ||
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails)) &&
other.thumbnails == thumbnails) &&
(identical(other.engagement, engagement) ||
const DeepCollectionEquality()
.equals(other.engagement, engagement)) &&
other.engagement == engagement) &&
(identical(other.videoCount, videoCount) ||
const DeepCollectionEquality()
.equals(other.videoCount, videoCount)));
other.videoCount == videoCount));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(id) ^
const DeepCollectionEquality().hash(title) ^
const DeepCollectionEquality().hash(author) ^
const DeepCollectionEquality().hash(description) ^
const DeepCollectionEquality().hash(thumbnails) ^
const DeepCollectionEquality().hash(engagement) ^
const DeepCollectionEquality().hash(videoCount);
int get hashCode => Object.hash(runtimeType, id, title, author, description,
thumbnails, engagement, videoCount);
@JsonKey(ignore: true)
@override
@ -326,33 +313,33 @@ abstract class _Playlist extends Playlist {
@override
/// Playlist ID.
PlaylistId get id => throw _privateConstructorUsedError;
PlaylistId get id;
@override
/// Playlist title.
String get title => throw _privateConstructorUsedError;
String get title;
@override
/// Playlist author.
/// Can be null if it's a system playlist (e.g. Video Mix, Topics, etc.).
String get author => throw _privateConstructorUsedError;
String get author;
@override
/// Playlist description.
String get description => throw _privateConstructorUsedError;
String get description;
@override
/// Available thumbnails for this playlist.
/// Can be null if the playlist is empty.
ThumbnailSet get thumbnails => throw _privateConstructorUsedError;
ThumbnailSet get thumbnails;
@override
/// Engagement statistics.
Engagement get engagement => throw _privateConstructorUsedError;
Engagement get engagement;
@override
/// Total videos in this playlist.
int? get videoCount => throw _privateConstructorUsedError;
int? get videoCount;
@override
@JsonKey(ignore: true)
_$PlaylistCopyWith<_Playlist> get copyWith =>

View File

@ -111,14 +111,13 @@ class _$_PlaylistId extends _PlaylistId {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _PlaylistId &&
(identical(other.value, value) ||
const DeepCollectionEquality().equals(other.value, value)));
(other.runtimeType == runtimeType &&
other is _PlaylistId &&
(identical(other.value, value) || other.value == value));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(value);
int get hashCode => Object.hash(runtimeType, value);
@JsonKey(ignore: true)
@override
@ -133,7 +132,7 @@ abstract class _PlaylistId extends PlaylistId {
@override
/// The playlist id as string.
String get value => throw _privateConstructorUsedError;
String get value;
@override
@JsonKey(ignore: true)
_$PlaylistIdCopyWith<_PlaylistId> get copyWith =>

View File

@ -1,6 +1,16 @@
import 'package:json_annotation/json_annotation.dart';
part 'fragment.g.dart';
/// Fragment used for DASH Manifests.
@JsonSerializable()
class Fragment {
final String path;
const Fragment(this.path);
factory Fragment.fromJson(Map<String, dynamic> json) =>
_$FragmentFromJson(json);
Map<String, dynamic> toJson() => _$FragmentToJson(this);
}

View File

@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'fragment.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Fragment _$FragmentFromJson(Map<String, dynamic> json) => Fragment(
json['path'] as String,
);
Map<String, dynamic> _$FragmentToJson(Fragment instance) => <String, dynamic>{
'path': instance.path,
};

View File

@ -9,7 +9,7 @@ part 'search_channel.freezed.dart';
@freezed
class SearchChannel with _$SearchChannel, BaseSearchContent {
/// Initialize a [SearchChannel] instance.
@With(BaseSearchContent)
@With<BaseSearchContent>()
const factory SearchChannel(
/// Channel id.

View File

@ -159,7 +159,7 @@ class __$SearchChannelCopyWithImpl<$Res>
/// @nodoc
@With(BaseSearchContent)
@With<BaseSearchContent>()
class _$_SearchChannel with BaseSearchContent implements _SearchChannel {
const _$_SearchChannel(this.id, this.name, this.description, this.videoCount);
@ -189,26 +189,19 @@ class _$_SearchChannel with BaseSearchContent implements _SearchChannel {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _SearchChannel &&
(identical(other.id, id) ||
const DeepCollectionEquality().equals(other.id, id)) &&
(identical(other.name, name) ||
const DeepCollectionEquality().equals(other.name, name)) &&
(other.runtimeType == runtimeType &&
other is _SearchChannel &&
(identical(other.id, id) || other.id == id) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.description, description) ||
const DeepCollectionEquality()
.equals(other.description, description)) &&
other.description == description) &&
(identical(other.videoCount, videoCount) ||
const DeepCollectionEquality()
.equals(other.videoCount, videoCount)));
other.videoCount == videoCount));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(id) ^
const DeepCollectionEquality().hash(name) ^
const DeepCollectionEquality().hash(description) ^
const DeepCollectionEquality().hash(videoCount);
Object.hash(runtimeType, id, name, description, videoCount);
@JsonKey(ignore: true)
@override
@ -224,20 +217,20 @@ abstract class _SearchChannel implements SearchChannel, BaseSearchContent {
@override
/// Channel id.
ChannelId get id => throw _privateConstructorUsedError;
ChannelId get id;
@override
/// Channel name.
String get name => throw _privateConstructorUsedError;
String get name;
@override
/// Description snippet.
/// Can be empty.
String get description => throw _privateConstructorUsedError;
String get description;
@override
/// Channel uploaded videos.
int get videoCount => throw _privateConstructorUsedError;
int get videoCount;
@override
@JsonKey(ignore: true)
_$SearchChannelCopyWith<_SearchChannel> get copyWith =>

View File

@ -10,7 +10,7 @@ part 'search_playlist.freezed.dart';
@freezed
class SearchPlaylist with _$SearchPlaylist, BaseSearchContent {
/// Initialize a [SearchPlaylist] instance.
@With(BaseSearchContent)
@With<BaseSearchContent>()
const factory SearchPlaylist(
/// PlaylistId.

View File

@ -166,7 +166,7 @@ class __$SearchPlaylistCopyWithImpl<$Res>
/// @nodoc
@With(BaseSearchContent)
@With<BaseSearchContent>()
class _$_SearchPlaylist with BaseSearchContent implements _SearchPlaylist {
const _$_SearchPlaylist(this.playlistId, this.playlistTitle,
this.playlistVideoCount, this.thumbnails);
@ -196,28 +196,21 @@ class _$_SearchPlaylist with BaseSearchContent implements _SearchPlaylist {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _SearchPlaylist &&
(other.runtimeType == runtimeType &&
other is _SearchPlaylist &&
(identical(other.playlistId, playlistId) ||
const DeepCollectionEquality()
.equals(other.playlistId, playlistId)) &&
other.playlistId == playlistId) &&
(identical(other.playlistTitle, playlistTitle) ||
const DeepCollectionEquality()
.equals(other.playlistTitle, playlistTitle)) &&
other.playlistTitle == playlistTitle) &&
(identical(other.playlistVideoCount, playlistVideoCount) ||
const DeepCollectionEquality()
.equals(other.playlistVideoCount, playlistVideoCount)) &&
(identical(other.thumbnails, thumbnails) ||
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails)));
other.playlistVideoCount == playlistVideoCount) &&
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(playlistId) ^
const DeepCollectionEquality().hash(playlistTitle) ^
const DeepCollectionEquality().hash(playlistVideoCount) ^
const DeepCollectionEquality().hash(thumbnails);
int get hashCode => Object.hash(runtimeType, playlistId, playlistTitle,
playlistVideoCount, const DeepCollectionEquality().hash(thumbnails));
@JsonKey(ignore: true)
@override
@ -232,19 +225,19 @@ abstract class _SearchPlaylist implements SearchPlaylist, BaseSearchContent {
@override
/// PlaylistId.
PlaylistId get playlistId => throw _privateConstructorUsedError;
PlaylistId get playlistId;
@override
/// Playlist title.
String get playlistTitle => throw _privateConstructorUsedError;
String get playlistTitle;
@override
/// Playlist video count, cannot be greater than 50.
int get playlistVideoCount => throw _privateConstructorUsedError;
int get playlistVideoCount;
@override
/// Video thumbnail
List<Thumbnail> get thumbnails => throw _privateConstructorUsedError;
List<Thumbnail> get thumbnails;
@override
@JsonKey(ignore: true)
_$SearchPlaylistCopyWith<_SearchPlaylist> get copyWith =>

View File

@ -10,7 +10,7 @@ part 'search_video.freezed.dart';
@freezed
class SearchVideo with _$SearchVideo, BaseSearchContent {
/// Initialize a [SearchVideo] instance.
@With(BaseSearchContent)
@With<BaseSearchContent>()
const factory SearchVideo(
/// Video ID.
VideoId id,

View File

@ -270,7 +270,7 @@ class __$SearchVideoCopyWithImpl<$Res> extends _$SearchVideoCopyWithImpl<$Res>
/// @nodoc
@With(BaseSearchContent)
@With<BaseSearchContent>()
class _$_SearchVideo with BaseSearchContent implements _SearchVideo {
const _$_SearchVideo(
this.id,
@ -334,48 +334,39 @@ class _$_SearchVideo with BaseSearchContent implements _SearchVideo {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _SearchVideo &&
(identical(other.id, id) ||
const DeepCollectionEquality().equals(other.id, id)) &&
(identical(other.title, title) ||
const DeepCollectionEquality().equals(other.title, title)) &&
(identical(other.author, author) ||
const DeepCollectionEquality().equals(other.author, author)) &&
(other.runtimeType == runtimeType &&
other is _SearchVideo &&
(identical(other.id, id) || other.id == id) &&
(identical(other.title, title) || other.title == title) &&
(identical(other.author, author) || other.author == author) &&
(identical(other.description, description) ||
const DeepCollectionEquality()
.equals(other.description, description)) &&
other.description == description) &&
(identical(other.duration, duration) ||
const DeepCollectionEquality()
.equals(other.duration, duration)) &&
other.duration == duration) &&
(identical(other.viewCount, viewCount) ||
const DeepCollectionEquality()
.equals(other.viewCount, viewCount)) &&
(identical(other.thumbnails, thumbnails) ||
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails)) &&
other.viewCount == viewCount) &&
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails) &&
(identical(other.uploadDate, uploadDate) ||
const DeepCollectionEquality()
.equals(other.uploadDate, uploadDate)) &&
(identical(other.isLive, isLive) ||
const DeepCollectionEquality().equals(other.isLive, isLive)) &&
other.uploadDate == uploadDate) &&
(identical(other.isLive, isLive) || other.isLive == isLive) &&
(identical(other.channelId, channelId) ||
const DeepCollectionEquality()
.equals(other.channelId, channelId)));
other.channelId == channelId));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(id) ^
const DeepCollectionEquality().hash(title) ^
const DeepCollectionEquality().hash(author) ^
const DeepCollectionEquality().hash(description) ^
const DeepCollectionEquality().hash(duration) ^
const DeepCollectionEquality().hash(viewCount) ^
const DeepCollectionEquality().hash(thumbnails) ^
const DeepCollectionEquality().hash(uploadDate) ^
const DeepCollectionEquality().hash(isLive) ^
const DeepCollectionEquality().hash(channelId);
int get hashCode => Object.hash(
runtimeType,
id,
title,
author,
description,
duration,
viewCount,
const DeepCollectionEquality().hash(thumbnails),
uploadDate,
isLive,
channelId);
@JsonKey(ignore: true)
@override
@ -399,44 +390,44 @@ abstract class _SearchVideo implements SearchVideo, BaseSearchContent {
@override
/// Video ID.
VideoId get id => throw _privateConstructorUsedError;
VideoId get id;
@override
/// Video title.
String get title => throw _privateConstructorUsedError;
String get title;
@override
/// Video author.
String get author => throw _privateConstructorUsedError;
String get author;
@override
/// Video description snippet. (Part of the full description if too long)
String get description => throw _privateConstructorUsedError;
String get description;
@override
/// Video duration as String, HH:MM:SS
String get duration => throw _privateConstructorUsedError;
String get duration;
@override
/// Video View Count
int get viewCount => throw _privateConstructorUsedError;
int get viewCount;
@override
/// Video thumbnail
List<Thumbnail> get thumbnails => throw _privateConstructorUsedError;
List<Thumbnail> get thumbnails;
@override
/// Video upload date - As string: 5 years ago.
String? get uploadDate => throw _privateConstructorUsedError;
String? get uploadDate;
@override
/// True if this video is a live stream.
// ignore: avoid_positional_boolean_parameters
bool get isLive => throw _privateConstructorUsedError;
bool get isLive;
@override
/// Channel id
String get channelId => throw _privateConstructorUsedError;
String get channelId;
@override
@JsonKey(ignore: true)
_$SearchVideoCopyWith<_SearchVideo> get copyWith =>

View File

@ -32,7 +32,7 @@ class _$ClosedCaptionTrackInfoTearOff {
);
}
ClosedCaptionTrackInfo fromJson(Map<String, Object> json) {
ClosedCaptionTrackInfo fromJson(Map<String, Object?> json) {
return ClosedCaptionTrackInfo.fromJson(json);
}
}
@ -205,26 +205,19 @@ class _$_ClosedCaptionTrackInfo extends _ClosedCaptionTrackInfo {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ClosedCaptionTrackInfo &&
(identical(other.url, url) ||
const DeepCollectionEquality().equals(other.url, url)) &&
(other.runtimeType == runtimeType &&
other is _ClosedCaptionTrackInfo &&
(identical(other.url, url) || other.url == url) &&
(identical(other.language, language) ||
const DeepCollectionEquality()
.equals(other.language, language)) &&
other.language == language) &&
(identical(other.isAutoGenerated, isAutoGenerated) ||
const DeepCollectionEquality()
.equals(other.isAutoGenerated, isAutoGenerated)) &&
(identical(other.format, format) ||
const DeepCollectionEquality().equals(other.format, format)));
other.isAutoGenerated == isAutoGenerated) &&
(identical(other.format, format) || other.format == format));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(url) ^
const DeepCollectionEquality().hash(language) ^
const DeepCollectionEquality().hash(isAutoGenerated) ^
const DeepCollectionEquality().hash(format);
Object.hash(runtimeType, url, language, isAutoGenerated, format);
@JsonKey(ignore: true)
@override
@ -250,19 +243,19 @@ abstract class _ClosedCaptionTrackInfo extends ClosedCaptionTrackInfo {
@override
/// Manifest URL of the associated track.
Uri get url => throw _privateConstructorUsedError;
Uri get url;
@override
/// Language of the associated track.
Language get language => throw _privateConstructorUsedError;
Language get language;
@override
/// Whether the associated track was automatically generated.
bool get isAutoGenerated => throw _privateConstructorUsedError;
bool get isAutoGenerated;
@override
/// Track format
ClosedCaptionFormat get format => throw _privateConstructorUsedError;
ClosedCaptionFormat get format;
@override
@JsonKey(ignore: true)
_$ClosedCaptionTrackInfoCopyWith<_ClosedCaptionTrackInfo> get copyWith =>

View File

@ -28,7 +28,7 @@ class _$LanguageTearOff {
);
}
Language fromJson(Map<String, Object> json) {
Language fromJson(Map<String, Object?> json) {
return Language.fromJson(json);
}
}
@ -143,18 +143,14 @@ class _$_Language extends _Language {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Language &&
(identical(other.code, code) ||
const DeepCollectionEquality().equals(other.code, code)) &&
(identical(other.name, name) ||
const DeepCollectionEquality().equals(other.name, name)));
(other.runtimeType == runtimeType &&
other is _Language &&
(identical(other.code, code) || other.code == code) &&
(identical(other.name, name) || other.name == name));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(code) ^
const DeepCollectionEquality().hash(name);
int get hashCode => Object.hash(runtimeType, code, name);
@JsonKey(ignore: true)
@override
@ -176,11 +172,11 @@ abstract class _Language extends Language {
@override
/// ISO 639-1 code of this language.
String get code => throw _privateConstructorUsedError;
String get code;
@override
/// Full English name of this language. This could be an empty string.
String get name => throw _privateConstructorUsedError;
String get name;
@override
@JsonKey(ignore: true)
_$LanguageCopyWith<_Language> get copyWith =>

View File

@ -288,42 +288,27 @@ class _$_Comment implements _Comment {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Comment &&
(identical(other.author, author) ||
const DeepCollectionEquality().equals(other.author, author)) &&
(other.runtimeType == runtimeType &&
other is _Comment &&
(identical(other.author, author) || other.author == author) &&
(identical(other.channelId, channelId) ||
const DeepCollectionEquality()
.equals(other.channelId, channelId)) &&
(identical(other.text, text) ||
const DeepCollectionEquality().equals(other.text, text)) &&
other.channelId == channelId) &&
(identical(other.text, text) || other.text == text) &&
(identical(other.likeCount, likeCount) ||
const DeepCollectionEquality()
.equals(other.likeCount, likeCount)) &&
other.likeCount == likeCount) &&
(identical(other.publishedTime, publishedTime) ||
const DeepCollectionEquality()
.equals(other.publishedTime, publishedTime)) &&
other.publishedTime == publishedTime) &&
(identical(other.replyCount, replyCount) ||
const DeepCollectionEquality()
.equals(other.replyCount, replyCount)) &&
other.replyCount == replyCount) &&
(identical(other.isHearted, isHearted) ||
const DeepCollectionEquality()
.equals(other.isHearted, isHearted)) &&
other.isHearted == isHearted) &&
(identical(other.continuation, continuation) ||
const DeepCollectionEquality()
.equals(other.continuation, continuation)));
other.continuation == continuation));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(author) ^
const DeepCollectionEquality().hash(channelId) ^
const DeepCollectionEquality().hash(text) ^
const DeepCollectionEquality().hash(likeCount) ^
const DeepCollectionEquality().hash(publishedTime) ^
const DeepCollectionEquality().hash(replyCount) ^
const DeepCollectionEquality().hash(isHearted) ^
const DeepCollectionEquality().hash(continuation);
int get hashCode => Object.hash(runtimeType, author, channelId, text,
likeCount, publishedTime, replyCount, isHearted, continuation);
@JsonKey(ignore: true)
@override
@ -345,38 +330,38 @@ abstract class _Comment implements Comment {
@override
/// Comment author name.
String get author => throw _privateConstructorUsedError;
String get author;
@override
/// Comment author channel id.
ChannelId get channelId => throw _privateConstructorUsedError;
ChannelId get channelId;
@override
/// Comment text.
String get text => throw _privateConstructorUsedError;
String get text;
@override
/// Comment likes count.
int get likeCount => throw _privateConstructorUsedError;
int get likeCount;
@override
/// Published time as string. (For example: "2 years ago")
String get publishedTime => throw _privateConstructorUsedError;
String get publishedTime;
@override
/// Comment reply count.
int get replyCount => throw _privateConstructorUsedError;
int get replyCount;
@override
/// True if the comment is hearted by the creator.
//ignore: avoid_positional_boolean_parameters
bool get isHearted => throw _privateConstructorUsedError;
bool get isHearted;
@override
/// Used internally.
/// Shouldn't be used in the code.
@internal
String? get continuation => throw _privateConstructorUsedError;
String? get continuation;
@override
@JsonKey(ignore: true)
_$CommentCopyWith<_Comment> get copyWith =>

View File

@ -1,23 +1,60 @@
import 'package:http_parser/http_parser.dart';
import 'package:json_annotation/json_annotation.dart';
import '../../reverse_engineering/models/fragment.dart';
import 'stream_info.dart';
import 'streams.dart';
part 'audio_only_stream_info.g.dart';
/// YouTube media stream that only contains audio.
class AudioOnlyStreamInfo extends AudioStreamInfo {
@JsonSerializable()
class AudioOnlyStreamInfo with StreamInfo, AudioStreamInfo {
@override
final int tag;
@override
final Uri url;
@override
final StreamContainer container;
@override
final FileSize size;
@override
final Bitrate bitrate;
@override
final String audioCodec;
@override
@JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson)
final MediaType codec;
@override
final List<Fragment> fragments;
@override
final String qualityLabel;
AudioOnlyStreamInfo(
int tag,
Uri url,
StreamContainer container,
FileSize size,
Bitrate bitrate,
String audioCodec,
List<Fragment> fragments,
MediaType codec,
String qualityLabel)
: super(tag, url, container, size, bitrate, audioCodec, fragments, codec,
qualityLabel);
this.tag,
this.url,
this.container,
this.size,
this.bitrate,
this.audioCodec,
this.qualityLabel,
this.fragments,
this.codec);
@override
String toString() => 'Audio-only ($tag | $container)';
factory AudioOnlyStreamInfo.fromJson(Map<String, dynamic> json) =>
_$AudioOnlyStreamInfoFromJson(json);
Map<String, dynamic> toJson() => _$AudioOnlyStreamInfoToJson(this);
}

View File

@ -0,0 +1,36 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'audio_only_stream_info.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
AudioOnlyStreamInfo _$AudioOnlyStreamInfoFromJson(Map<String, dynamic> json) =>
AudioOnlyStreamInfo(
json['tag'] as int,
Uri.parse(json['url'] as String),
StreamContainer.fromJson(json['container'] as Map<String, dynamic>),
FileSize.fromJson(json['size'] as Map<String, dynamic>),
Bitrate.fromJson(json['bitrate'] as Map<String, dynamic>),
json['audioCodec'] as String,
json['qualityLabel'] as String,
(json['fragments'] as List<dynamic>)
.map((e) => Fragment.fromJson(e as Map<String, dynamic>))
.toList(),
mediaTypeFromJson(json['codec'] as String),
);
Map<String, dynamic> _$AudioOnlyStreamInfoToJson(
AudioOnlyStreamInfo instance) =>
<String, dynamic>{
'tag': instance.tag,
'url': instance.url.toString(),
'container': instance.container,
'size': instance.size,
'bitrate': instance.bitrate,
'audioCodec': instance.audioCodec,
'codec': mediaTypeTojson(instance.codec),
'fragments': instance.fragments,
'qualityLabel': instance.qualityLabel,
};

View File

@ -1,24 +1,6 @@
import 'package:http_parser/http_parser.dart';
import '../../reverse_engineering/models/fragment.dart';
import 'streams.dart';
/// YouTube media stream that contains audio.
abstract class AudioStreamInfo extends StreamInfo {
/// Audio codec.
final String audioCodec;
///
AudioStreamInfo(
int tag,
Uri url,
StreamContainer container,
FileSize size,
Bitrate bitrate,
this.audioCodec,
List<Fragment> fragments,
MediaType codec,
String qualityLabel)
: super(
tag, url, container, size, bitrate, fragments, codec, qualityLabel);
mixin AudioStreamInfo on StreamInfo {
String get audioCodec;
}

View File

@ -1,6 +1,7 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'bitrate.freezed.dart';
part 'bitrate.g.dart';
/// Encapsulates bitrate.
@freezed
@ -15,12 +16,15 @@ class Bitrate with Comparable<Bitrate>, _$Bitrate {
double get gigaBitsPerSecond => megaBitsPerSecond / 1024;
/// Initializes an instance of [Bitrate]
@With.fromString('Comparable<Bitrate>')
@With<Comparable<Bitrate>>()
const factory Bitrate(
/// Bits per second.
int bitsPerSecond) = _Bitrate;
factory Bitrate.fromJson(Map<String, dynamic> json) =>
_$BitrateFromJson(json);
const Bitrate._();
static const Bitrate unknown = Bitrate(0);

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
Bitrate _$BitrateFromJson(Map<String, dynamic> json) {
return _Bitrate.fromJson(json);
}
/// @nodoc
class _$BitrateTearOff {
const _$BitrateTearOff();
@ -22,6 +26,10 @@ class _$BitrateTearOff {
bitsPerSecond,
);
}
Bitrate fromJson(Map<String, Object?> json) {
return Bitrate.fromJson(json);
}
}
/// @nodoc
@ -32,6 +40,7 @@ mixin _$Bitrate {
/// Bits per second.
int get bitsPerSecond => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$BitrateCopyWith<Bitrate> get copyWith => throw _privateConstructorUsedError;
}
@ -95,11 +104,14 @@ class __$BitrateCopyWithImpl<$Res> extends _$BitrateCopyWithImpl<$Res>
}
/// @nodoc
@With.fromString('Comparable<Bitrate>')
@JsonSerializable()
@With<Comparable<Bitrate>>()
class _$_Bitrate extends _Bitrate with Comparable<Bitrate> {
const _$_Bitrate(this.bitsPerSecond) : super._();
factory _$_Bitrate.fromJson(Map<String, dynamic> json) =>
_$$_BitrateFromJson(json);
@override
/// Bits per second.
@ -108,30 +120,36 @@ class _$_Bitrate extends _Bitrate with Comparable<Bitrate> {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Bitrate &&
(other.runtimeType == runtimeType &&
other is _Bitrate &&
(identical(other.bitsPerSecond, bitsPerSecond) ||
const DeepCollectionEquality()
.equals(other.bitsPerSecond, bitsPerSecond)));
other.bitsPerSecond == bitsPerSecond));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(bitsPerSecond);
int get hashCode => Object.hash(runtimeType, bitsPerSecond);
@JsonKey(ignore: true)
@override
_$BitrateCopyWith<_Bitrate> get copyWith =>
__$BitrateCopyWithImpl<_Bitrate>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_BitrateToJson(this);
}
}
abstract class _Bitrate extends Bitrate implements Comparable<Bitrate> {
const factory _Bitrate(int bitsPerSecond) = _$_Bitrate;
const _Bitrate._() : super._();
factory _Bitrate.fromJson(Map<String, dynamic> json) = _$_Bitrate.fromJson;
@override
/// Bits per second.
int get bitsPerSecond => throw _privateConstructorUsedError;
int get bitsPerSecond;
@override
@JsonKey(ignore: true)
_$BitrateCopyWith<_Bitrate> get copyWith =>

View File

@ -0,0 +1,16 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bitrate.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_Bitrate _$$_BitrateFromJson(Map<String, dynamic> json) => _$_Bitrate(
json['bitsPerSecond'] as int,
);
Map<String, dynamic> _$$_BitrateToJson(_$_Bitrate instance) =>
<String, dynamic>{
'bitsPerSecond': instance.bitsPerSecond,
};

View File

@ -1,6 +1,7 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'filesize.freezed.dart';
part 'filesize.g.dart';
/// Encapsulates file size.
@freezed
@ -15,12 +16,15 @@ class FileSize with Comparable<FileSize>, _$FileSize {
double get totalGigaBytes => totalMegaBytes / 1024;
/// Initializes an instance of [FileSize]
@With.fromString('Comparable<FileSize>')
@With<Comparable<FileSize>>()
const factory FileSize(
/// Total bytes.
int totalBytes) = _FileSize;
factory FileSize.fromJson(Map<String, dynamic> json) =>
_$FileSizeFromJson(json);
const FileSize._();
static const FileSize unknown = FileSize(0);

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
FileSize _$FileSizeFromJson(Map<String, dynamic> json) {
return _FileSize.fromJson(json);
}
/// @nodoc
class _$FileSizeTearOff {
const _$FileSizeTearOff();
@ -22,6 +26,10 @@ class _$FileSizeTearOff {
totalBytes,
);
}
FileSize fromJson(Map<String, Object?> json) {
return FileSize.fromJson(json);
}
}
/// @nodoc
@ -32,6 +40,7 @@ mixin _$FileSize {
/// Total bytes.
int get totalBytes => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$FileSizeCopyWith<FileSize> get copyWith =>
throw _privateConstructorUsedError;
@ -96,11 +105,14 @@ class __$FileSizeCopyWithImpl<$Res> extends _$FileSizeCopyWithImpl<$Res>
}
/// @nodoc
@With.fromString('Comparable<FileSize>')
@JsonSerializable()
@With<Comparable<FileSize>>()
class _$_FileSize extends _FileSize with Comparable<FileSize> {
const _$_FileSize(this.totalBytes) : super._();
factory _$_FileSize.fromJson(Map<String, dynamic> json) =>
_$$_FileSizeFromJson(json);
@override
/// Total bytes.
@ -109,30 +121,36 @@ class _$_FileSize extends _FileSize with Comparable<FileSize> {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _FileSize &&
(other.runtimeType == runtimeType &&
other is _FileSize &&
(identical(other.totalBytes, totalBytes) ||
const DeepCollectionEquality()
.equals(other.totalBytes, totalBytes)));
other.totalBytes == totalBytes));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(totalBytes);
int get hashCode => Object.hash(runtimeType, totalBytes);
@JsonKey(ignore: true)
@override
_$FileSizeCopyWith<_FileSize> get copyWith =>
__$FileSizeCopyWithImpl<_FileSize>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_FileSizeToJson(this);
}
}
abstract class _FileSize extends FileSize implements Comparable<FileSize> {
const factory _FileSize(int totalBytes) = _$_FileSize;
const _FileSize._() : super._();
factory _FileSize.fromJson(Map<String, dynamic> json) = _$_FileSize.fromJson;
@override
/// Total bytes.
int get totalBytes => throw _privateConstructorUsedError;
int get totalBytes;
@override
@JsonKey(ignore: true)
_$FileSizeCopyWith<_FileSize> get copyWith =>

View File

@ -0,0 +1,16 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'filesize.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_FileSize _$$_FileSizeFromJson(Map<String, dynamic> json) => _$_FileSize(
json['totalBytes'] as int,
);
Map<String, dynamic> _$$_FileSizeToJson(_$_FileSize instance) =>
<String, dynamic>{
'totalBytes': instance.totalBytes,
};

View File

@ -1,6 +1,7 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'framerate.freezed.dart';
part 'framerate.g.dart';
/// Encapsulates framerate.
@freezed
@ -13,6 +14,9 @@ class Framerate with Comparable<Framerate>, _$Framerate {
const Framerate._();
factory Framerate.fromJson(Map<String, dynamic> json) =>
_$FramerateFromJson(json);
///
bool operator >(Framerate other) => framesPerSecond > other.framesPerSecond;

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
Framerate _$FramerateFromJson(Map<String, dynamic> json) {
return _Framerate.fromJson(json);
}
/// @nodoc
class _$FramerateTearOff {
const _$FramerateTearOff();
@ -22,6 +26,10 @@ class _$FramerateTearOff {
framesPerSecond,
);
}
Framerate fromJson(Map<String, Object?> json) {
return Framerate.fromJson(json);
}
}
/// @nodoc
@ -32,6 +40,7 @@ mixin _$Framerate {
/// Framerate as frames per second
num get framesPerSecond => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$FramerateCopyWith<Framerate> get copyWith =>
throw _privateConstructorUsedError;
@ -97,10 +106,13 @@ class __$FramerateCopyWithImpl<$Res> extends _$FramerateCopyWithImpl<$Res>
}
/// @nodoc
@JsonSerializable()
class _$_Framerate extends _Framerate {
const _$_Framerate(this.framesPerSecond) : super._();
factory _$_Framerate.fromJson(Map<String, dynamic> json) =>
_$$_FramerateFromJson(json);
@override
/// Framerate as frames per second
@ -109,31 +121,37 @@ class _$_Framerate extends _Framerate {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Framerate &&
(other.runtimeType == runtimeType &&
other is _Framerate &&
(identical(other.framesPerSecond, framesPerSecond) ||
const DeepCollectionEquality()
.equals(other.framesPerSecond, framesPerSecond)));
other.framesPerSecond == framesPerSecond));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(framesPerSecond);
int get hashCode => Object.hash(runtimeType, framesPerSecond);
@JsonKey(ignore: true)
@override
_$FramerateCopyWith<_Framerate> get copyWith =>
__$FramerateCopyWithImpl<_Framerate>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_FramerateToJson(this);
}
}
abstract class _Framerate extends Framerate {
const factory _Framerate(num framesPerSecond) = _$_Framerate;
const _Framerate._() : super._();
factory _Framerate.fromJson(Map<String, dynamic> json) =
_$_Framerate.fromJson;
@override
/// Framerate as frames per second
num get framesPerSecond => throw _privateConstructorUsedError;
num get framesPerSecond;
@override
@JsonKey(ignore: true)
_$FramerateCopyWith<_Framerate> get copyWith =>

View File

@ -0,0 +1,16 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'framerate.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_Framerate _$$_FramerateFromJson(Map<String, dynamic> json) => _$_Framerate(
json['framesPerSecond'] as num,
);
Map<String, dynamic> _$$_FramerateToJson(_$_Framerate instance) =>
<String, dynamic>{
'framesPerSecond': instance.framesPerSecond,
};

View File

@ -1,4 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:http_parser/http_parser.dart';
import 'package:youtube_explode_dart/src/videos/streams/stream_info.dart';
import '../../reverse_engineering/models/fragment.dart';
import 'audio_stream_info.dart';
@ -10,8 +12,11 @@ import 'video_quality.dart';
import 'video_resolution.dart';
import 'video_stream_info.dart';
part 'muxed_stream_info.g.dart';
/// YouTube media stream that contains both audio and video.
class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
@JsonSerializable()
class MuxedStreamInfo with StreamInfo, AudioStreamInfo, VideoStreamInfo {
@override
final int tag;
@ -36,7 +41,7 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
/// Video quality label, as seen on YouTube.
@Deprecated('Use qualityLabel')
@override
final String videoQualityLabel;
String get videoQualityLabel => qualityLabel;
/// Video quality.
@override
@ -56,6 +61,7 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
/// Stream codec.
@override
@JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson)
final MediaType codec;
/// Stream codec.
@ -64,20 +70,25 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
/// Initializes an instance of [MuxedStreamInfo]
MuxedStreamInfo(
this.tag,
this.url,
this.container,
this.size,
this.bitrate,
this.audioCodec,
this.videoCodec,
@Deprecated('Use qualityLabel') this.videoQualityLabel,
this.videoQuality,
this.videoResolution,
this.framerate,
this.codec,
this.qualityLabel);
this.tag,
this.url,
this.container,
this.size,
this.bitrate,
this.audioCodec,
this.videoCodec,
this.qualityLabel,
this.videoQuality,
this.videoResolution,
this.framerate,
this.codec,
);
@override
String toString() => 'Muxed ($tag | $qualityLabel | $container)';
}
factory MuxedStreamInfo.fromJson(Map<String, dynamic> json) =>
_$MuxedStreamInfoFromJson(json);
Map<String, dynamic> toJson() => _$MuxedStreamInfoToJson(this);
}

View File

@ -0,0 +1,54 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'muxed_stream_info.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
MuxedStreamInfo _$MuxedStreamInfoFromJson(Map<String, dynamic> json) =>
MuxedStreamInfo(
json['tag'] as int,
Uri.parse(json['url'] as String),
StreamContainer.fromJson(json['container'] as Map<String, dynamic>),
FileSize.fromJson(json['size'] as Map<String, dynamic>),
Bitrate.fromJson(json['bitrate'] as Map<String, dynamic>),
json['audioCodec'] as String,
json['videoCodec'] as String,
json['qualityLabel'] as String,
$enumDecode(_$VideoQualityEnumMap, json['videoQuality']),
VideoResolution.fromJson(json['videoResolution'] as Map<String, dynamic>),
Framerate.fromJson(json['framerate'] as Map<String, dynamic>),
mediaTypeFromJson(json['codec'] as String),
);
Map<String, dynamic> _$MuxedStreamInfoToJson(MuxedStreamInfo instance) =>
<String, dynamic>{
'tag': instance.tag,
'url': instance.url.toString(),
'container': instance.container,
'size': instance.size,
'bitrate': instance.bitrate,
'audioCodec': instance.audioCodec,
'videoCodec': instance.videoCodec,
'videoQuality': _$VideoQualityEnumMap[instance.videoQuality],
'videoResolution': instance.videoResolution,
'framerate': instance.framerate,
'codec': mediaTypeTojson(instance.codec),
'qualityLabel': instance.qualityLabel,
};
const _$VideoQualityEnumMap = {
VideoQuality.unknown: 'unknown',
VideoQuality.low144: 'low144',
VideoQuality.low240: 'low240',
VideoQuality.medium360: 'medium360',
VideoQuality.medium480: 'medium480',
VideoQuality.high720: 'high720',
VideoQuality.high1080: 'high1080',
VideoQuality.high1440: 'high1440',
VideoQuality.high2160: 'high2160',
VideoQuality.high2880: 'high2880',
VideoQuality.high3072: 'high3072',
VideoQuality.high4320: 'high4320',
};

View File

@ -1,6 +1,7 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'stream_container.freezed.dart';
part 'stream_container.g.dart';
/// Stream container.
@freezed
@ -12,6 +13,9 @@ class StreamContainer with _$StreamContainer {
/// Can be used as file extension
String name) = _StreamContainer;
factory StreamContainer.fromJson(Map<String, dynamic> json) =>
StreamContainer.parse(json['name'] as String);
const StreamContainer._();
/// MPEG-4 Part 14 (.mp4).

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
StreamContainer _$StreamContainerFromJson(Map<String, dynamic> json) {
return _StreamContainer.fromJson(json);
}
/// @nodoc
class _$StreamContainerTearOff {
const _$StreamContainerTearOff();
@ -22,6 +26,10 @@ class _$StreamContainerTearOff {
name,
);
}
StreamContainer fromJson(Map<String, Object?> json) {
return StreamContainer.fromJson(json);
}
}
/// @nodoc
@ -33,6 +41,7 @@ mixin _$StreamContainer {
/// Can be used as file extension
String get name => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$StreamContainerCopyWith<StreamContainer> get copyWith =>
throw _privateConstructorUsedError;
@ -103,10 +112,13 @@ class __$StreamContainerCopyWithImpl<$Res>
}
/// @nodoc
@JsonSerializable()
class _$_StreamContainer extends _StreamContainer {
const _$_StreamContainer(this.name) : super._();
factory _$_StreamContainer.fromJson(Map<String, dynamic> json) =>
_$$_StreamContainerFromJson(json);
@override
/// Container name.
@ -116,30 +128,37 @@ class _$_StreamContainer extends _StreamContainer {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _StreamContainer &&
(identical(other.name, name) ||
const DeepCollectionEquality().equals(other.name, name)));
(other.runtimeType == runtimeType &&
other is _StreamContainer &&
(identical(other.name, name) || other.name == name));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(name);
int get hashCode => Object.hash(runtimeType, name);
@JsonKey(ignore: true)
@override
_$StreamContainerCopyWith<_StreamContainer> get copyWith =>
__$StreamContainerCopyWithImpl<_StreamContainer>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_StreamContainerToJson(this);
}
}
abstract class _StreamContainer extends StreamContainer {
const factory _StreamContainer(String name) = _$_StreamContainer;
const _StreamContainer._() : super._();
factory _StreamContainer.fromJson(Map<String, dynamic> json) =
_$_StreamContainer.fromJson;
@override
/// Container name.
/// Can be used as file extension
String get name => throw _privateConstructorUsedError;
String get name;
@override
@JsonKey(ignore: true)
_$StreamContainerCopyWith<_StreamContainer> get copyWith =>

View File

@ -0,0 +1,17 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'stream_container.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_StreamContainer _$$_StreamContainerFromJson(Map<String, dynamic> json) =>
_$_StreamContainer(
json['name'] as String,
);
Map<String, dynamic> _$$_StreamContainerToJson(_$_StreamContainer instance) =>
<String, dynamic>{
'name': instance.name,
};

View File

@ -2,40 +2,36 @@ import 'package:http_parser/http_parser.dart';
import '../../reverse_engineering/models/fragment.dart';
import '../videos.dart';
import 'bitrate.dart';
import 'filesize.dart';
import 'stream_container.dart';
/// Generic YouTube media stream.
abstract class StreamInfo {
mixin StreamInfo {
/// Stream tag.
/// Uniquely identifies a stream inside a manifest.
final int tag;
int get tag;
/// Stream URL.
final Uri url;
Uri get url;
/// Stream container.
final StreamContainer container;
StreamContainer get container;
/// Stream size.
final FileSize size;
FileSize get size;
/// Stream bitrate.
final Bitrate bitrate;
Bitrate get bitrate;
/// DASH streams contain multiple stream fragments.
final List<Fragment> fragments;
List<Fragment> get fragments;
/// Streams codec.
final MediaType codec;
MediaType get codec;
/// Stream quality label.
final String qualityLabel;
String get qualityLabel;
/// Initialize an instance of [StreamInfo].
StreamInfo(this.tag, this.url, this.container, this.size, this.bitrate,
this.fragments, this.codec, this.qualityLabel);
/// Convert to a json-serialized type.
Map<String, dynamic> toJson();
}
/// Extension for Iterables of StreamInfo.
@ -102,3 +98,7 @@ class _Column {
return buffer.toString();
}
}
String mediaTypeTojson(MediaType value) => value.toString();
MediaType mediaTypeFromJson(String value) => MediaType.parse(value);

View File

@ -6,7 +6,7 @@ export 'framerate.dart';
export 'muxed_stream_info.dart';
export 'stream_container.dart';
export 'stream_context.dart';
export 'stream_info.dart';
export 'stream_info.dart' hide mediaTypeFromJson, mediaTypeTojson;
export 'stream_manifest.dart';
export 'streams_client.dart';
export 'video_only_stream_info.dart';

View File

@ -127,9 +127,7 @@ class StreamsClient {
// Muxed or Video-only
if (!videoCodec.isNullOrWhiteSpace) {
var framerate = Framerate(streamInfo.framerate ?? 24);
var videoQualityLabel = streamInfo.qualityLabel;
var videoQuality = VideoQualityUtil.fromLabel(videoQualityLabel);
var videoQuality = VideoQualityUtil.fromLabel(streamInfo.qualityLabel);
var videoWidth = streamInfo.videoWidth;
var videoHeight = streamInfo.videoHeight;
@ -141,19 +139,19 @@ class StreamsClient {
if (!audioCodec.isNullOrWhiteSpace &&
streamInfo.source != StreamSource.adaptive) {
streams[tag] = MuxedStreamInfo(
tag,
url,
container,
fileSize,
bitrate,
audioCodec!,
videoCodec!,
videoQualityLabel,
videoQuality,
videoResolution,
framerate,
streamInfo.codec,
streamInfo.qualityLabel);
tag,
url,
container,
fileSize,
bitrate,
audioCodec!,
videoCodec!,
streamInfo.qualityLabel,
videoQuality,
videoResolution,
framerate,
streamInfo.codec,
);
continue;
}
@ -165,13 +163,12 @@ class StreamsClient {
fileSize,
bitrate,
videoCodec!,
videoQualityLabel,
streamInfo.qualityLabel,
videoQuality,
videoResolution,
framerate,
streamInfo.fragments ?? const [],
streamInfo.codec,
streamInfo.qualityLabel);
streamInfo.codec);
continue;
}
// Audio-only
@ -183,9 +180,9 @@ class StreamsClient {
fileSize,
bitrate,
audioCodec!,
streamInfo.qualityLabel,
streamInfo.fragments ?? const [],
streamInfo.codec,
streamInfo.qualityLabel);
streamInfo.codec);
}
// #if DEBUG

View File

@ -1,45 +1,83 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:http_parser/http_parser.dart';
import '../../../youtube_explode_dart.dart';
import '../../reverse_engineering/models/fragment.dart';
import 'bitrate.dart';
import 'filesize.dart';
import 'framerate.dart';
import 'stream_container.dart';
import 'stream_info.dart';
import 'video_quality.dart';
import 'video_resolution.dart';
import 'video_stream_info.dart';
part 'video_only_stream_info.g.dart';
/// YouTube media stream that only contains video.
class VideoOnlyStreamInfo extends VideoStreamInfo {
@JsonSerializable()
class VideoOnlyStreamInfo with StreamInfo, VideoStreamInfo {
@override
final int tag;
@override
final Uri url;
@override
final StreamContainer container;
@override
final FileSize size;
@override
final Bitrate bitrate;
@override
final String videoCodec;
@override
final String qualityLabel;
@override
String get videoQualityLabel => qualityLabel;
@override
final VideoQuality videoQuality;
@override
final VideoResolution videoResolution;
@override
final Framerate framerate;
@override
final List<Fragment> fragments;
@override
@JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson)
final MediaType codec;
VideoOnlyStreamInfo(
int tag,
Uri url,
StreamContainer container,
FileSize size,
Bitrate bitrate,
String videoCodec,
String videoQualityLabel,
VideoQuality videoQuality,
VideoResolution videoResolution,
Framerate framerate,
List<Fragment> fragments,
MediaType codec,
String qualityLabel)
: super(
tag,
url,
container,
size,
bitrate,
videoCodec,
videoQualityLabel,
videoQuality,
videoResolution,
framerate,
fragments,
codec,
qualityLabel);
this.tag,
this.url,
this.container,
this.size,
this.bitrate,
this.videoCodec,
this.qualityLabel,
this.videoQuality,
this.videoResolution,
this.framerate,
this.fragments,
this.codec);
@override
String toString() => 'Video-only ($tag | $videoResolution | $container)';
factory VideoOnlyStreamInfo.fromJson(Map<String, dynamic> json) =>
_$VideoOnlyStreamInfoFromJson(json);
Map<String, dynamic> toJson() => _$VideoOnlyStreamInfoToJson(this);
}

View File

@ -0,0 +1,57 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'video_only_stream_info.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
VideoOnlyStreamInfo _$VideoOnlyStreamInfoFromJson(Map<String, dynamic> json) =>
VideoOnlyStreamInfo(
json['tag'] as int,
Uri.parse(json['url'] as String),
StreamContainer.fromJson(json['container'] as Map<String, dynamic>),
FileSize.fromJson(json['size'] as Map<String, dynamic>),
Bitrate.fromJson(json['bitrate'] as Map<String, dynamic>),
json['videoCodec'] as String,
json['qualityLabel'] as String,
$enumDecode(_$VideoQualityEnumMap, json['videoQuality']),
VideoResolution.fromJson(json['videoResolution'] as Map<String, dynamic>),
Framerate.fromJson(json['framerate'] as Map<String, dynamic>),
(json['fragments'] as List<dynamic>)
.map((e) => Fragment.fromJson(e as Map<String, dynamic>))
.toList(),
mediaTypeFromJson(json['codec'] as String),
);
Map<String, dynamic> _$VideoOnlyStreamInfoToJson(
VideoOnlyStreamInfo instance) =>
<String, dynamic>{
'tag': instance.tag,
'url': instance.url.toString(),
'container': instance.container,
'size': instance.size,
'bitrate': instance.bitrate,
'videoCodec': instance.videoCodec,
'qualityLabel': instance.qualityLabel,
'videoQuality': _$VideoQualityEnumMap[instance.videoQuality],
'videoResolution': instance.videoResolution,
'framerate': instance.framerate,
'fragments': instance.fragments,
'codec': mediaTypeTojson(instance.codec),
};
const _$VideoQualityEnumMap = {
VideoQuality.unknown: 'unknown',
VideoQuality.low144: 'low144',
VideoQuality.low240: 'low240',
VideoQuality.medium360: 'medium360',
VideoQuality.medium480: 'medium480',
VideoQuality.high720: 'high720',
VideoQuality.high1080: 'high1080',
VideoQuality.high1440: 'high1440',
VideoQuality.high2160: 'high2160',
VideoQuality.high2880: 'high2880',
VideoQuality.high3072: 'high3072',
VideoQuality.high4320: 'high4320',
};

View File

@ -1,4 +1,9 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'video_resolution.g.dart';
/// Width and height of a video.
@JsonSerializable()
class VideoResolution implements Comparable<VideoResolution> {
/// Viewport width.
final int width;
@ -9,6 +14,11 @@ class VideoResolution implements Comparable<VideoResolution> {
/// Initializes an instance of [VideoResolution]
const VideoResolution(this.width, this.height);
factory VideoResolution.fromJson(Map<String, dynamic> json) =>
_$VideoResolutionFromJson(json);
Map<String, dynamic> toJson() => _$VideoResolutionToJson(this);
@override
String toString() => '${width}x$height';

View File

@ -0,0 +1,19 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'video_resolution.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
VideoResolution _$VideoResolutionFromJson(Map<String, dynamic> json) =>
VideoResolution(
json['width'] as int,
json['height'] as int,
);
Map<String, dynamic> _$VideoResolutionToJson(VideoResolution instance) =>
<String, dynamic>{
'width': instance.width,
'height': instance.height,
};

View File

@ -1,43 +1,22 @@
import 'package:http_parser/http_parser.dart';
import '../../reverse_engineering/models/fragment.dart';
import 'streams.dart';
/// YouTube media stream that contains video.
abstract class VideoStreamInfo extends StreamInfo {
mixin VideoStreamInfo on StreamInfo {
/// Video codec.
final String videoCodec;
String get videoCodec;
/// Video quality label, as seen on YouTube.
@Deprecated('Use qualityLabel')
final String videoQualityLabel;
String get videoQualityLabel;
/// Video quality.
final VideoQuality videoQuality;
VideoQuality get videoQuality;
/// Video resolution.
final VideoResolution videoResolution;
VideoResolution get videoResolution;
/// Video framerate.
final Framerate framerate;
///
VideoStreamInfo(
int tag,
Uri url,
StreamContainer container,
FileSize size,
Bitrate bitrate,
this.videoCodec,
@Deprecated('Use qualityLabel') this.videoQualityLabel,
this.videoQuality,
this.videoResolution,
this.framerate,
List<Fragment> fragments,
MediaType codec,
String qualityLabel)
: super(
tag, url, container, size, bitrate, fragments, codec, qualityLabel);
Framerate get framerate;
}
/// Extensions for Iterables of [VideoStreamInfo]

View File

@ -434,60 +434,48 @@ class _$_Video extends _Video {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Video &&
(identical(other.id, id) ||
const DeepCollectionEquality().equals(other.id, id)) &&
(identical(other.title, title) ||
const DeepCollectionEquality().equals(other.title, title)) &&
(identical(other.author, author) ||
const DeepCollectionEquality().equals(other.author, author)) &&
(other.runtimeType == runtimeType &&
other is _Video &&
(identical(other.id, id) || other.id == id) &&
(identical(other.title, title) || other.title == title) &&
(identical(other.author, author) || other.author == author) &&
(identical(other.channelId, channelId) ||
const DeepCollectionEquality()
.equals(other.channelId, channelId)) &&
other.channelId == channelId) &&
(identical(other.uploadDate, uploadDate) ||
const DeepCollectionEquality()
.equals(other.uploadDate, uploadDate)) &&
other.uploadDate == uploadDate) &&
(identical(other.publishDate, publishDate) ||
const DeepCollectionEquality()
.equals(other.publishDate, publishDate)) &&
other.publishDate == publishDate) &&
(identical(other.description, description) ||
const DeepCollectionEquality()
.equals(other.description, description)) &&
other.description == description) &&
(identical(other.duration, duration) ||
const DeepCollectionEquality()
.equals(other.duration, duration)) &&
other.duration == duration) &&
(identical(other.thumbnails, thumbnails) ||
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails)) &&
other.thumbnails == thumbnails) &&
(identical(other.keywords, keywords) ||
const DeepCollectionEquality()
.equals(other.keywords, keywords)) &&
other.keywords == keywords) &&
(identical(other.engagement, engagement) ||
const DeepCollectionEquality()
.equals(other.engagement, engagement)) &&
(identical(other.isLive, isLive) ||
const DeepCollectionEquality().equals(other.isLive, isLive)) &&
other.engagement == engagement) &&
(identical(other.isLive, isLive) || other.isLive == isLive) &&
(identical(other.watchPage, watchPage) ||
const DeepCollectionEquality()
.equals(other.watchPage, watchPage)));
other.watchPage == watchPage));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(id) ^
const DeepCollectionEquality().hash(title) ^
const DeepCollectionEquality().hash(author) ^
const DeepCollectionEquality().hash(channelId) ^
const DeepCollectionEquality().hash(uploadDate) ^
const DeepCollectionEquality().hash(publishDate) ^
const DeepCollectionEquality().hash(description) ^
const DeepCollectionEquality().hash(duration) ^
const DeepCollectionEquality().hash(thumbnails) ^
const DeepCollectionEquality().hash(keywords) ^
const DeepCollectionEquality().hash(engagement) ^
const DeepCollectionEquality().hash(isLive) ^
const DeepCollectionEquality().hash(watchPage);
int get hashCode => Object.hash(
runtimeType,
id,
title,
author,
channelId,
uploadDate,
publishDate,
description,
duration,
thumbnails,
keywords,
engagement,
isLive,
watchPage);
@JsonKey(ignore: true)
@override
@ -515,61 +503,60 @@ abstract class _Video extends Video {
@override
/// Video ID.
VideoId get id => throw _privateConstructorUsedError;
VideoId get id;
@override
/// Video title.
String get title => throw _privateConstructorUsedError;
String get title;
@override
/// Video author.
String get author => throw _privateConstructorUsedError;
String get author;
@override
/// Video author Id.
ChannelId get channelId => throw _privateConstructorUsedError;
ChannelId get channelId;
@override
/// Video upload date.
/// Note: For search queries it is calculated with:
/// DateTime.now() - how much time is was published.
DateTime? get uploadDate => throw _privateConstructorUsedError;
DateTime? get uploadDate;
@override
/// Video publish date.
DateTime? get publishDate => throw _privateConstructorUsedError;
DateTime? get publishDate;
@override
/// Video description.
String get description => throw _privateConstructorUsedError;
String get description;
@override
/// Duration of the video.
Duration? get duration => throw _privateConstructorUsedError;
Duration? get duration;
@override
/// Available thumbnails for this video.
ThumbnailSet get thumbnails => throw _privateConstructorUsedError;
ThumbnailSet get thumbnails;
@override
/// Search keywords used for this video.
UnmodifiableListView<String> get keywords =>
throw _privateConstructorUsedError;
UnmodifiableListView<String> get keywords;
@override
/// Engagement statistics for this video.
Engagement get engagement => throw _privateConstructorUsedError;
Engagement get engagement;
@override
/// Returns true if this is a live stream.
//ignore: avoid_positional_boolean_parameters
bool get isLive => throw _privateConstructorUsedError;
bool get isLive;
@override
/// Used internally.
/// Shouldn't be used in the code.
@internal
WatchPage? get watchPage => throw _privateConstructorUsedError;
WatchPage? get watchPage;
@override
@JsonKey(ignore: true)
_$VideoCopyWith<_Video> get copyWith => throw _privateConstructorUsedError;

View File

@ -85,7 +85,7 @@ class VideoId with _$VideoId {
return embedMatch;
}
// https://www.youtube.com/shorts/yIVRs6YSbOM
// https://www.youtube.com/shorts/yIVRs6YSbOM
var shortsMatch = _shortsMatchExp.firstMatch(url)?.group(1);
if (!shortsMatch.isNullOrWhiteSpace && validateVideoId(shortsMatch!)) {
return shortsMatch;

View File

@ -107,14 +107,13 @@ class _$_VideoId extends _VideoId {
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _VideoId &&
(identical(other.value, value) ||
const DeepCollectionEquality().equals(other.value, value)));
(other.runtimeType == runtimeType &&
other is _VideoId &&
(identical(other.value, value) || other.value == value));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(value);
int get hashCode => Object.hash(runtimeType, value);
@JsonKey(ignore: true)
@override
@ -129,7 +128,7 @@ abstract class _VideoId extends VideoId {
@override
/// ID as string.
String get value => throw _privateConstructorUsedError;
String get value;
@override
@JsonKey(ignore: true)
_$VideoIdCopyWith<_VideoId> get copyWith =>

View File

@ -5,23 +5,23 @@ version: 1.10.8
homepage: https://github.com/Hexer10/youtube_explode_dart
environment:
sdk: '>=2.13.0 <3.0.0'
sdk: '>=2.14.0 <3.0.0'
dependencies:
collection: ^1.15.0
freezed_annotation: ^0.14.3
freezed_annotation: ^0.15.0
html: ^0.15.0
http: ^0.13.0
http_parser: ^4.0.0
json_annotation: ^4.0.0
json_annotation: ^4.3.0
meta: ^1.3.0
xml: ^5.0.2
dev_dependencies:
build_runner: ^2.1.4
console: ^4.1.0
freezed: ^0.14.5
freezed: ^0.15.1+1
grinder: ^0.9.0
json_serializable: ^5.0.2
json_serializable: ^6.0.1
lint: ^1.7.2
test: ^1.18.2