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 { Future<void> main() async {
var yt = YoutubeExplode(); var yt = YoutubeExplode();
var video = var streamInfo = await yt.videos.streamsClient.getManifest('fRh_vgS2dFE');
await yt.videos.get('https://www.youtube.com/watch?v=AI7ULzgf8RU');
print('Title: ${video.title}'); print(streamInfo);
// Close the YoutubeExplode's http client. // Close the YoutubeExplode's http client.
yt.close(); yt.close();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -111,14 +111,13 @@ class _$_PlaylistId extends _PlaylistId {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _PlaylistId && (other.runtimeType == runtimeType &&
(identical(other.value, value) || other is _PlaylistId &&
const DeepCollectionEquality().equals(other.value, value))); (identical(other.value, value) || other.value == value));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(runtimeType, value);
runtimeType.hashCode ^ const DeepCollectionEquality().hash(value);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -133,7 +132,7 @@ abstract class _PlaylistId extends PlaylistId {
@override @override
/// The playlist id as string. /// The playlist id as string.
String get value => throw _privateConstructorUsedError; String get value;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$PlaylistIdCopyWith<_PlaylistId> get copyWith => _$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. /// Fragment used for DASH Manifests.
@JsonSerializable()
class Fragment { class Fragment {
final String path; final String path;
const Fragment(this.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 @freezed
class SearchChannel with _$SearchChannel, BaseSearchContent { class SearchChannel with _$SearchChannel, BaseSearchContent {
/// Initialize a [SearchChannel] instance. /// Initialize a [SearchChannel] instance.
@With(BaseSearchContent) @With<BaseSearchContent>()
const factory SearchChannel( const factory SearchChannel(
/// Channel id. /// Channel id.

View File

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

View File

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

View File

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

View File

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

View File

@ -270,7 +270,7 @@ class __$SearchVideoCopyWithImpl<$Res> extends _$SearchVideoCopyWithImpl<$Res>
/// @nodoc /// @nodoc
@With(BaseSearchContent) @With<BaseSearchContent>()
class _$_SearchVideo with BaseSearchContent implements _SearchVideo { class _$_SearchVideo with BaseSearchContent implements _SearchVideo {
const _$_SearchVideo( const _$_SearchVideo(
this.id, this.id,
@ -334,48 +334,39 @@ class _$_SearchVideo with BaseSearchContent implements _SearchVideo {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _SearchVideo && (other.runtimeType == runtimeType &&
(identical(other.id, id) || other is _SearchVideo &&
const DeepCollectionEquality().equals(other.id, id)) && (identical(other.id, id) || other.id == id) &&
(identical(other.title, title) || (identical(other.title, title) || other.title == title) &&
const DeepCollectionEquality().equals(other.title, title)) && (identical(other.author, author) || other.author == author) &&
(identical(other.author, author) ||
const DeepCollectionEquality().equals(other.author, author)) &&
(identical(other.description, description) || (identical(other.description, description) ||
const DeepCollectionEquality() other.description == description) &&
.equals(other.description, description)) &&
(identical(other.duration, duration) || (identical(other.duration, duration) ||
const DeepCollectionEquality() other.duration == duration) &&
.equals(other.duration, duration)) &&
(identical(other.viewCount, viewCount) || (identical(other.viewCount, viewCount) ||
const DeepCollectionEquality() other.viewCount == viewCount) &&
.equals(other.viewCount, viewCount)) && const DeepCollectionEquality()
(identical(other.thumbnails, thumbnails) || .equals(other.thumbnails, thumbnails) &&
const DeepCollectionEquality()
.equals(other.thumbnails, thumbnails)) &&
(identical(other.uploadDate, uploadDate) || (identical(other.uploadDate, uploadDate) ||
const DeepCollectionEquality() other.uploadDate == uploadDate) &&
.equals(other.uploadDate, uploadDate)) && (identical(other.isLive, isLive) || other.isLive == isLive) &&
(identical(other.isLive, isLive) ||
const DeepCollectionEquality().equals(other.isLive, isLive)) &&
(identical(other.channelId, channelId) || (identical(other.channelId, channelId) ||
const DeepCollectionEquality() other.channelId == channelId));
.equals(other.channelId, channelId)));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(
runtimeType.hashCode ^ runtimeType,
const DeepCollectionEquality().hash(id) ^ id,
const DeepCollectionEquality().hash(title) ^ title,
const DeepCollectionEquality().hash(author) ^ author,
const DeepCollectionEquality().hash(description) ^ description,
const DeepCollectionEquality().hash(duration) ^ duration,
const DeepCollectionEquality().hash(viewCount) ^ viewCount,
const DeepCollectionEquality().hash(thumbnails) ^ const DeepCollectionEquality().hash(thumbnails),
const DeepCollectionEquality().hash(uploadDate) ^ uploadDate,
const DeepCollectionEquality().hash(isLive) ^ isLive,
const DeepCollectionEquality().hash(channelId); channelId);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -399,44 +390,44 @@ abstract class _SearchVideo implements SearchVideo, BaseSearchContent {
@override @override
/// Video ID. /// Video ID.
VideoId get id => throw _privateConstructorUsedError; VideoId get id;
@override @override
/// Video title. /// Video title.
String get title => throw _privateConstructorUsedError; String get title;
@override @override
/// Video author. /// Video author.
String get author => throw _privateConstructorUsedError; String get author;
@override @override
/// Video description snippet. (Part of the full description if too long) /// Video description snippet. (Part of the full description if too long)
String get description => throw _privateConstructorUsedError; String get description;
@override @override
/// Video duration as String, HH:MM:SS /// Video duration as String, HH:MM:SS
String get duration => throw _privateConstructorUsedError; String get duration;
@override @override
/// Video View Count /// Video View Count
int get viewCount => throw _privateConstructorUsedError; int get viewCount;
@override @override
/// Video thumbnail /// Video thumbnail
List<Thumbnail> get thumbnails => throw _privateConstructorUsedError; List<Thumbnail> get thumbnails;
@override @override
/// Video upload date - As string: 5 years ago. /// Video upload date - As string: 5 years ago.
String? get uploadDate => throw _privateConstructorUsedError; String? get uploadDate;
@override @override
/// True if this video is a live stream. /// True if this video is a live stream.
// ignore: avoid_positional_boolean_parameters // ignore: avoid_positional_boolean_parameters
bool get isLive => throw _privateConstructorUsedError; bool get isLive;
@override @override
/// Channel id /// Channel id
String get channelId => throw _privateConstructorUsedError; String get channelId;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$SearchVideoCopyWith<_SearchVideo> get copyWith => _$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); return ClosedCaptionTrackInfo.fromJson(json);
} }
} }
@ -205,26 +205,19 @@ class _$_ClosedCaptionTrackInfo extends _ClosedCaptionTrackInfo {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _ClosedCaptionTrackInfo && (other.runtimeType == runtimeType &&
(identical(other.url, url) || other is _ClosedCaptionTrackInfo &&
const DeepCollectionEquality().equals(other.url, url)) && (identical(other.url, url) || other.url == url) &&
(identical(other.language, language) || (identical(other.language, language) ||
const DeepCollectionEquality() other.language == language) &&
.equals(other.language, language)) &&
(identical(other.isAutoGenerated, isAutoGenerated) || (identical(other.isAutoGenerated, isAutoGenerated) ||
const DeepCollectionEquality() other.isAutoGenerated == isAutoGenerated) &&
.equals(other.isAutoGenerated, isAutoGenerated)) && (identical(other.format, format) || other.format == format));
(identical(other.format, format) ||
const DeepCollectionEquality().equals(other.format, format)));
} }
@override @override
int get hashCode => int get hashCode =>
runtimeType.hashCode ^ Object.hash(runtimeType, url, language, isAutoGenerated, format);
const DeepCollectionEquality().hash(url) ^
const DeepCollectionEquality().hash(language) ^
const DeepCollectionEquality().hash(isAutoGenerated) ^
const DeepCollectionEquality().hash(format);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -250,19 +243,19 @@ abstract class _ClosedCaptionTrackInfo extends ClosedCaptionTrackInfo {
@override @override
/// Manifest URL of the associated track. /// Manifest URL of the associated track.
Uri get url => throw _privateConstructorUsedError; Uri get url;
@override @override
/// Language of the associated track. /// Language of the associated track.
Language get language => throw _privateConstructorUsedError; Language get language;
@override @override
/// Whether the associated track was automatically generated. /// Whether the associated track was automatically generated.
bool get isAutoGenerated => throw _privateConstructorUsedError; bool get isAutoGenerated;
@override @override
/// Track format /// Track format
ClosedCaptionFormat get format => throw _privateConstructorUsedError; ClosedCaptionFormat get format;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$ClosedCaptionTrackInfoCopyWith<_ClosedCaptionTrackInfo> get copyWith => _$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); return Language.fromJson(json);
} }
} }
@ -143,18 +143,14 @@ class _$_Language extends _Language {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _Language && (other.runtimeType == runtimeType &&
(identical(other.code, code) || other is _Language &&
const DeepCollectionEquality().equals(other.code, code)) && (identical(other.code, code) || other.code == code) &&
(identical(other.name, name) || (identical(other.name, name) || other.name == name));
const DeepCollectionEquality().equals(other.name, name)));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(runtimeType, code, name);
runtimeType.hashCode ^
const DeepCollectionEquality().hash(code) ^
const DeepCollectionEquality().hash(name);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@ -176,11 +172,11 @@ abstract class _Language extends Language {
@override @override
/// ISO 639-1 code of this language. /// ISO 639-1 code of this language.
String get code => throw _privateConstructorUsedError; String get code;
@override @override
/// Full English name of this language. This could be an empty string. /// Full English name of this language. This could be an empty string.
String get name => throw _privateConstructorUsedError; String get name;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$LanguageCopyWith<_Language> get copyWith => _$LanguageCopyWith<_Language> get copyWith =>

View File

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

View File

@ -1,23 +1,60 @@
import 'package:http_parser/http_parser.dart'; import 'package:http_parser/http_parser.dart';
import 'package:json_annotation/json_annotation.dart';
import '../../reverse_engineering/models/fragment.dart'; import '../../reverse_engineering/models/fragment.dart';
import 'stream_info.dart';
import 'streams.dart'; import 'streams.dart';
part 'audio_only_stream_info.g.dart';
/// YouTube media stream that only contains audio. /// 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( AudioOnlyStreamInfo(
int tag, this.tag,
Uri url, this.url,
StreamContainer container, this.container,
FileSize size, this.size,
Bitrate bitrate, this.bitrate,
String audioCodec, this.audioCodec,
List<Fragment> fragments, this.qualityLabel,
MediaType codec, this.fragments,
String qualityLabel) this.codec);
: super(tag, url, container, size, bitrate, audioCodec, fragments, codec,
qualityLabel);
@override @override
String toString() => 'Audio-only ($tag | $container)'; 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'; import 'streams.dart';
/// YouTube media stream that contains audio. /// YouTube media stream that contains audio.
abstract class AudioStreamInfo extends StreamInfo { mixin AudioStreamInfo on StreamInfo {
/// Audio codec. String get audioCodec;
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);
} }

View File

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

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( 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'); '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 /// @nodoc
class _$BitrateTearOff { class _$BitrateTearOff {
const _$BitrateTearOff(); const _$BitrateTearOff();
@ -22,6 +26,10 @@ class _$BitrateTearOff {
bitsPerSecond, bitsPerSecond,
); );
} }
Bitrate fromJson(Map<String, Object?> json) {
return Bitrate.fromJson(json);
}
} }
/// @nodoc /// @nodoc
@ -32,6 +40,7 @@ mixin _$Bitrate {
/// Bits per second. /// Bits per second.
int get bitsPerSecond => throw _privateConstructorUsedError; int get bitsPerSecond => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$BitrateCopyWith<Bitrate> get copyWith => throw _privateConstructorUsedError; $BitrateCopyWith<Bitrate> get copyWith => throw _privateConstructorUsedError;
} }
@ -95,11 +104,14 @@ class __$BitrateCopyWithImpl<$Res> extends _$BitrateCopyWithImpl<$Res>
} }
/// @nodoc /// @nodoc
@JsonSerializable()
@With.fromString('Comparable<Bitrate>') @With<Comparable<Bitrate>>()
class _$_Bitrate extends _Bitrate with Comparable<Bitrate> { class _$_Bitrate extends _Bitrate with Comparable<Bitrate> {
const _$_Bitrate(this.bitsPerSecond) : super._(); const _$_Bitrate(this.bitsPerSecond) : super._();
factory _$_Bitrate.fromJson(Map<String, dynamic> json) =>
_$$_BitrateFromJson(json);
@override @override
/// Bits per second. /// Bits per second.
@ -108,30 +120,36 @@ class _$_Bitrate extends _Bitrate with Comparable<Bitrate> {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _Bitrate && (other.runtimeType == runtimeType &&
other is _Bitrate &&
(identical(other.bitsPerSecond, bitsPerSecond) || (identical(other.bitsPerSecond, bitsPerSecond) ||
const DeepCollectionEquality() other.bitsPerSecond == bitsPerSecond));
.equals(other.bitsPerSecond, bitsPerSecond)));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(runtimeType, bitsPerSecond);
runtimeType.hashCode ^ const DeepCollectionEquality().hash(bitsPerSecond);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
_$BitrateCopyWith<_Bitrate> get copyWith => _$BitrateCopyWith<_Bitrate> get copyWith =>
__$BitrateCopyWithImpl<_Bitrate>(this, _$identity); __$BitrateCopyWithImpl<_Bitrate>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_BitrateToJson(this);
}
} }
abstract class _Bitrate extends Bitrate implements Comparable<Bitrate> { abstract class _Bitrate extends Bitrate implements Comparable<Bitrate> {
const factory _Bitrate(int bitsPerSecond) = _$_Bitrate; const factory _Bitrate(int bitsPerSecond) = _$_Bitrate;
const _Bitrate._() : super._(); const _Bitrate._() : super._();
factory _Bitrate.fromJson(Map<String, dynamic> json) = _$_Bitrate.fromJson;
@override @override
/// Bits per second. /// Bits per second.
int get bitsPerSecond => throw _privateConstructorUsedError; int get bitsPerSecond;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$BitrateCopyWith<_Bitrate> get copyWith => _$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'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'filesize.freezed.dart'; part 'filesize.freezed.dart';
part 'filesize.g.dart';
/// Encapsulates file size. /// Encapsulates file size.
@freezed @freezed
@ -15,12 +16,15 @@ class FileSize with Comparable<FileSize>, _$FileSize {
double get totalGigaBytes => totalMegaBytes / 1024; double get totalGigaBytes => totalMegaBytes / 1024;
/// Initializes an instance of [FileSize] /// Initializes an instance of [FileSize]
@With.fromString('Comparable<FileSize>') @With<Comparable<FileSize>>()
const factory FileSize( const factory FileSize(
/// Total bytes. /// Total bytes.
int totalBytes) = _FileSize; int totalBytes) = _FileSize;
factory FileSize.fromJson(Map<String, dynamic> json) =>
_$FileSizeFromJson(json);
const FileSize._(); const FileSize._();
static const FileSize unknown = FileSize(0); static const FileSize unknown = FileSize(0);

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( 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'); '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 /// @nodoc
class _$FileSizeTearOff { class _$FileSizeTearOff {
const _$FileSizeTearOff(); const _$FileSizeTearOff();
@ -22,6 +26,10 @@ class _$FileSizeTearOff {
totalBytes, totalBytes,
); );
} }
FileSize fromJson(Map<String, Object?> json) {
return FileSize.fromJson(json);
}
} }
/// @nodoc /// @nodoc
@ -32,6 +40,7 @@ mixin _$FileSize {
/// Total bytes. /// Total bytes.
int get totalBytes => throw _privateConstructorUsedError; int get totalBytes => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$FileSizeCopyWith<FileSize> get copyWith => $FileSizeCopyWith<FileSize> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -96,11 +105,14 @@ class __$FileSizeCopyWithImpl<$Res> extends _$FileSizeCopyWithImpl<$Res>
} }
/// @nodoc /// @nodoc
@JsonSerializable()
@With.fromString('Comparable<FileSize>') @With<Comparable<FileSize>>()
class _$_FileSize extends _FileSize with Comparable<FileSize> { class _$_FileSize extends _FileSize with Comparable<FileSize> {
const _$_FileSize(this.totalBytes) : super._(); const _$_FileSize(this.totalBytes) : super._();
factory _$_FileSize.fromJson(Map<String, dynamic> json) =>
_$$_FileSizeFromJson(json);
@override @override
/// Total bytes. /// Total bytes.
@ -109,30 +121,36 @@ class _$_FileSize extends _FileSize with Comparable<FileSize> {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _FileSize && (other.runtimeType == runtimeType &&
other is _FileSize &&
(identical(other.totalBytes, totalBytes) || (identical(other.totalBytes, totalBytes) ||
const DeepCollectionEquality() other.totalBytes == totalBytes));
.equals(other.totalBytes, totalBytes)));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(runtimeType, totalBytes);
runtimeType.hashCode ^ const DeepCollectionEquality().hash(totalBytes);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
_$FileSizeCopyWith<_FileSize> get copyWith => _$FileSizeCopyWith<_FileSize> get copyWith =>
__$FileSizeCopyWithImpl<_FileSize>(this, _$identity); __$FileSizeCopyWithImpl<_FileSize>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_FileSizeToJson(this);
}
} }
abstract class _FileSize extends FileSize implements Comparable<FileSize> { abstract class _FileSize extends FileSize implements Comparable<FileSize> {
const factory _FileSize(int totalBytes) = _$_FileSize; const factory _FileSize(int totalBytes) = _$_FileSize;
const _FileSize._() : super._(); const _FileSize._() : super._();
factory _FileSize.fromJson(Map<String, dynamic> json) = _$_FileSize.fromJson;
@override @override
/// Total bytes. /// Total bytes.
int get totalBytes => throw _privateConstructorUsedError; int get totalBytes;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$FileSizeCopyWith<_FileSize> get copyWith => _$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'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'framerate.freezed.dart'; part 'framerate.freezed.dart';
part 'framerate.g.dart';
/// Encapsulates framerate. /// Encapsulates framerate.
@freezed @freezed
@ -13,6 +14,9 @@ class Framerate with Comparable<Framerate>, _$Framerate {
const Framerate._(); const Framerate._();
factory Framerate.fromJson(Map<String, dynamic> json) =>
_$FramerateFromJson(json);
/// ///
bool operator >(Framerate other) => framesPerSecond > other.framesPerSecond; bool operator >(Framerate other) => framesPerSecond > other.framesPerSecond;

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( 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'); '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 /// @nodoc
class _$FramerateTearOff { class _$FramerateTearOff {
const _$FramerateTearOff(); const _$FramerateTearOff();
@ -22,6 +26,10 @@ class _$FramerateTearOff {
framesPerSecond, framesPerSecond,
); );
} }
Framerate fromJson(Map<String, Object?> json) {
return Framerate.fromJson(json);
}
} }
/// @nodoc /// @nodoc
@ -32,6 +40,7 @@ mixin _$Framerate {
/// Framerate as frames per second /// Framerate as frames per second
num get framesPerSecond => throw _privateConstructorUsedError; num get framesPerSecond => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$FramerateCopyWith<Framerate> get copyWith => $FramerateCopyWith<Framerate> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -97,10 +106,13 @@ class __$FramerateCopyWithImpl<$Res> extends _$FramerateCopyWithImpl<$Res>
} }
/// @nodoc /// @nodoc
@JsonSerializable()
class _$_Framerate extends _Framerate { class _$_Framerate extends _Framerate {
const _$_Framerate(this.framesPerSecond) : super._(); const _$_Framerate(this.framesPerSecond) : super._();
factory _$_Framerate.fromJson(Map<String, dynamic> json) =>
_$$_FramerateFromJson(json);
@override @override
/// Framerate as frames per second /// Framerate as frames per second
@ -109,31 +121,37 @@ class _$_Framerate extends _Framerate {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _Framerate && (other.runtimeType == runtimeType &&
other is _Framerate &&
(identical(other.framesPerSecond, framesPerSecond) || (identical(other.framesPerSecond, framesPerSecond) ||
const DeepCollectionEquality() other.framesPerSecond == framesPerSecond));
.equals(other.framesPerSecond, framesPerSecond)));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(runtimeType, framesPerSecond);
runtimeType.hashCode ^
const DeepCollectionEquality().hash(framesPerSecond);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
_$FramerateCopyWith<_Framerate> get copyWith => _$FramerateCopyWith<_Framerate> get copyWith =>
__$FramerateCopyWithImpl<_Framerate>(this, _$identity); __$FramerateCopyWithImpl<_Framerate>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_FramerateToJson(this);
}
} }
abstract class _Framerate extends Framerate { abstract class _Framerate extends Framerate {
const factory _Framerate(num framesPerSecond) = _$_Framerate; const factory _Framerate(num framesPerSecond) = _$_Framerate;
const _Framerate._() : super._(); const _Framerate._() : super._();
factory _Framerate.fromJson(Map<String, dynamic> json) =
_$_Framerate.fromJson;
@override @override
/// Framerate as frames per second /// Framerate as frames per second
num get framesPerSecond => throw _privateConstructorUsedError; num get framesPerSecond;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$FramerateCopyWith<_Framerate> get copyWith => _$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:http_parser/http_parser.dart';
import 'package:youtube_explode_dart/src/videos/streams/stream_info.dart';
import '../../reverse_engineering/models/fragment.dart'; import '../../reverse_engineering/models/fragment.dart';
import 'audio_stream_info.dart'; import 'audio_stream_info.dart';
@ -10,8 +12,11 @@ import 'video_quality.dart';
import 'video_resolution.dart'; import 'video_resolution.dart';
import 'video_stream_info.dart'; import 'video_stream_info.dart';
part 'muxed_stream_info.g.dart';
/// YouTube media stream that contains both audio and video. /// YouTube media stream that contains both audio and video.
class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo { @JsonSerializable()
class MuxedStreamInfo with StreamInfo, AudioStreamInfo, VideoStreamInfo {
@override @override
final int tag; final int tag;
@ -36,7 +41,7 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
/// Video quality label, as seen on YouTube. /// Video quality label, as seen on YouTube.
@Deprecated('Use qualityLabel') @Deprecated('Use qualityLabel')
@override @override
final String videoQualityLabel; String get videoQualityLabel => qualityLabel;
/// Video quality. /// Video quality.
@override @override
@ -56,6 +61,7 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
/// Stream codec. /// Stream codec.
@override @override
@JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson)
final MediaType codec; final MediaType codec;
/// Stream codec. /// Stream codec.
@ -64,20 +70,25 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo {
/// Initializes an instance of [MuxedStreamInfo] /// Initializes an instance of [MuxedStreamInfo]
MuxedStreamInfo( MuxedStreamInfo(
this.tag, this.tag,
this.url, this.url,
this.container, this.container,
this.size, this.size,
this.bitrate, this.bitrate,
this.audioCodec, this.audioCodec,
this.videoCodec, this.videoCodec,
@Deprecated('Use qualityLabel') this.videoQualityLabel, this.qualityLabel,
this.videoQuality, this.videoQuality,
this.videoResolution, this.videoResolution,
this.framerate, this.framerate,
this.codec, this.codec,
this.qualityLabel); );
@override @override
String toString() => 'Muxed ($tag | $qualityLabel | $container)'; 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'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'stream_container.freezed.dart'; part 'stream_container.freezed.dart';
part 'stream_container.g.dart';
/// Stream container. /// Stream container.
@freezed @freezed
@ -12,6 +13,9 @@ class StreamContainer with _$StreamContainer {
/// Can be used as file extension /// Can be used as file extension
String name) = _StreamContainer; String name) = _StreamContainer;
factory StreamContainer.fromJson(Map<String, dynamic> json) =>
StreamContainer.parse(json['name'] as String);
const StreamContainer._(); const StreamContainer._();
/// MPEG-4 Part 14 (.mp4). /// MPEG-4 Part 14 (.mp4).

View File

@ -13,6 +13,10 @@ T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( 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'); '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 /// @nodoc
class _$StreamContainerTearOff { class _$StreamContainerTearOff {
const _$StreamContainerTearOff(); const _$StreamContainerTearOff();
@ -22,6 +26,10 @@ class _$StreamContainerTearOff {
name, name,
); );
} }
StreamContainer fromJson(Map<String, Object?> json) {
return StreamContainer.fromJson(json);
}
} }
/// @nodoc /// @nodoc
@ -33,6 +41,7 @@ mixin _$StreamContainer {
/// Can be used as file extension /// Can be used as file extension
String get name => throw _privateConstructorUsedError; String get name => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$StreamContainerCopyWith<StreamContainer> get copyWith => $StreamContainerCopyWith<StreamContainer> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -103,10 +112,13 @@ class __$StreamContainerCopyWithImpl<$Res>
} }
/// @nodoc /// @nodoc
@JsonSerializable()
class _$_StreamContainer extends _StreamContainer { class _$_StreamContainer extends _StreamContainer {
const _$_StreamContainer(this.name) : super._(); const _$_StreamContainer(this.name) : super._();
factory _$_StreamContainer.fromJson(Map<String, dynamic> json) =>
_$$_StreamContainerFromJson(json);
@override @override
/// Container name. /// Container name.
@ -116,30 +128,37 @@ class _$_StreamContainer extends _StreamContainer {
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
return identical(this, other) || return identical(this, other) ||
(other is _StreamContainer && (other.runtimeType == runtimeType &&
(identical(other.name, name) || other is _StreamContainer &&
const DeepCollectionEquality().equals(other.name, name))); (identical(other.name, name) || other.name == name));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(runtimeType, name);
runtimeType.hashCode ^ const DeepCollectionEquality().hash(name);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
_$StreamContainerCopyWith<_StreamContainer> get copyWith => _$StreamContainerCopyWith<_StreamContainer> get copyWith =>
__$StreamContainerCopyWithImpl<_StreamContainer>(this, _$identity); __$StreamContainerCopyWithImpl<_StreamContainer>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$_StreamContainerToJson(this);
}
} }
abstract class _StreamContainer extends StreamContainer { abstract class _StreamContainer extends StreamContainer {
const factory _StreamContainer(String name) = _$_StreamContainer; const factory _StreamContainer(String name) = _$_StreamContainer;
const _StreamContainer._() : super._(); const _StreamContainer._() : super._();
factory _StreamContainer.fromJson(Map<String, dynamic> json) =
_$_StreamContainer.fromJson;
@override @override
/// Container name. /// Container name.
/// Can be used as file extension /// Can be used as file extension
String get name => throw _privateConstructorUsedError; String get name;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$StreamContainerCopyWith<_StreamContainer> get copyWith => _$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 '../../reverse_engineering/models/fragment.dart';
import '../videos.dart'; import '../videos.dart';
import 'bitrate.dart';
import 'filesize.dart';
import 'stream_container.dart';
/// Generic YouTube media stream. /// Generic YouTube media stream.
abstract class StreamInfo { mixin StreamInfo {
/// Stream tag. /// Stream tag.
/// Uniquely identifies a stream inside a manifest. /// Uniquely identifies a stream inside a manifest.
final int tag; int get tag;
/// Stream URL. /// Stream URL.
final Uri url; Uri get url;
/// Stream container. /// Stream container.
final StreamContainer container; StreamContainer get container;
/// Stream size. /// Stream size.
final FileSize size; FileSize get size;
/// Stream bitrate. /// Stream bitrate.
final Bitrate bitrate; Bitrate get bitrate;
/// DASH streams contain multiple stream fragments. /// DASH streams contain multiple stream fragments.
final List<Fragment> fragments; List<Fragment> get fragments;
/// Streams codec. /// Streams codec.
final MediaType codec; MediaType get codec;
/// Stream quality label. /// Stream quality label.
final String qualityLabel; String get qualityLabel;
/// Initialize an instance of [StreamInfo]. /// Convert to a json-serialized type.
StreamInfo(this.tag, this.url, this.container, this.size, this.bitrate, Map<String, dynamic> toJson();
this.fragments, this.codec, this.qualityLabel);
} }
/// Extension for Iterables of StreamInfo. /// Extension for Iterables of StreamInfo.
@ -102,3 +98,7 @@ class _Column {
return buffer.toString(); 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 'muxed_stream_info.dart';
export 'stream_container.dart'; export 'stream_container.dart';
export 'stream_context.dart'; export 'stream_context.dart';
export 'stream_info.dart'; export 'stream_info.dart' hide mediaTypeFromJson, mediaTypeTojson;
export 'stream_manifest.dart'; export 'stream_manifest.dart';
export 'streams_client.dart'; export 'streams_client.dart';
export 'video_only_stream_info.dart'; export 'video_only_stream_info.dart';

View File

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

View File

@ -1,45 +1,83 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:http_parser/http_parser.dart'; import 'package:http_parser/http_parser.dart';
import '../../../youtube_explode_dart.dart';
import '../../reverse_engineering/models/fragment.dart'; import '../../reverse_engineering/models/fragment.dart';
import 'bitrate.dart'; import 'bitrate.dart';
import 'filesize.dart'; import 'filesize.dart';
import 'framerate.dart'; import 'framerate.dart';
import 'stream_container.dart'; import 'stream_container.dart';
import 'stream_info.dart';
import 'video_quality.dart'; import 'video_quality.dart';
import 'video_resolution.dart'; import 'video_resolution.dart';
import 'video_stream_info.dart'; import 'video_stream_info.dart';
part 'video_only_stream_info.g.dart';
/// YouTube media stream that only contains video. /// 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( VideoOnlyStreamInfo(
int tag, this.tag,
Uri url, this.url,
StreamContainer container, this.container,
FileSize size, this.size,
Bitrate bitrate, this.bitrate,
String videoCodec, this.videoCodec,
String videoQualityLabel, this.qualityLabel,
VideoQuality videoQuality, this.videoQuality,
VideoResolution videoResolution, this.videoResolution,
Framerate framerate, this.framerate,
List<Fragment> fragments, this.fragments,
MediaType codec, this.codec);
String qualityLabel)
: super(
tag,
url,
container,
size,
bitrate,
videoCodec,
videoQualityLabel,
videoQuality,
videoResolution,
framerate,
fragments,
codec,
qualityLabel);
@override @override
String toString() => 'Video-only ($tag | $videoResolution | $container)'; 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. /// Width and height of a video.
@JsonSerializable()
class VideoResolution implements Comparable<VideoResolution> { class VideoResolution implements Comparable<VideoResolution> {
/// Viewport width. /// Viewport width.
final int width; final int width;
@ -9,6 +14,11 @@ class VideoResolution implements Comparable<VideoResolution> {
/// Initializes an instance of [VideoResolution] /// Initializes an instance of [VideoResolution]
const VideoResolution(this.width, this.height); const VideoResolution(this.width, this.height);
factory VideoResolution.fromJson(Map<String, dynamic> json) =>
_$VideoResolutionFromJson(json);
Map<String, dynamic> toJson() => _$VideoResolutionToJson(this);
@override @override
String toString() => '${width}x$height'; 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'; import 'streams.dart';
/// YouTube media stream that contains video. /// YouTube media stream that contains video.
abstract class VideoStreamInfo extends StreamInfo { mixin VideoStreamInfo on StreamInfo {
/// Video codec. /// Video codec.
final String videoCodec; String get videoCodec;
/// Video quality label, as seen on YouTube. /// Video quality label, as seen on YouTube.
@Deprecated('Use qualityLabel') @Deprecated('Use qualityLabel')
final String videoQualityLabel; String get videoQualityLabel;
/// Video quality. /// Video quality.
final VideoQuality videoQuality; VideoQuality get videoQuality;
/// Video resolution. /// Video resolution.
final VideoResolution videoResolution; VideoResolution get videoResolution;
/// Video framerate. /// Video framerate.
final Framerate framerate; Framerate get 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);
} }
/// Extensions for Iterables of [VideoStreamInfo] /// Extensions for Iterables of [VideoStreamInfo]

View File

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

View File

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

View File

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

View File

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