From 37fbb3fdea229df0e2f20162ac4466a6800af738 Mon Sep 17 00:00:00 2001 From: Mattia Date: Fri, 12 Nov 2021 21:04:53 +0100 Subject: [PATCH] Implement json serialization for streams. #94 --- example/example.dart | 5 +- lib/src/channels/channel.freezed.dart | 30 +++--- lib/src/channels/channel_about.freezed.dart | 61 +++++------- lib/src/channels/channel_id.freezed.dart | 11 +-- lib/src/channels/channel_link.freezed.dart | 24 ++--- lib/src/channels/channel_video.freezed.dart | 44 +++------ lib/src/channels/username.freezed.dart | 11 +-- lib/src/common/engagement.freezed.dart | 23 ++--- lib/src/common/thumbnail.freezed.dart | 24 ++--- lib/src/common/thumbnail_set.freezed.dart | 11 +-- lib/src/playlists/playlist.freezed.dart | 49 ++++----- lib/src/playlists/playlist_id.freezed.dart | 11 +-- .../reverse_engineering/models/fragment.dart | 10 ++ .../models/fragment.g.dart | 15 +++ lib/src/search/search_channel.dart | 2 +- lib/src/search/search_channel.freezed.dart | 31 +++--- lib/src/search/search_playlist.dart | 2 +- lib/src/search/search_playlist.freezed.dart | 35 +++---- lib/src/search/search_video.dart | 2 +- lib/src/search/search_video.freezed.dart | 81 +++++++-------- .../closed_caption_track_info.freezed.dart | 31 +++--- .../closed_captions/language.freezed.dart | 20 ++-- lib/src/videos/comments/comment.freezed.dart | 55 ++++------- .../streams/audio_only_stream_info.dart | 61 +++++++++--- .../streams/audio_only_stream_info.g.dart | 36 +++++++ lib/src/videos/streams/audio_stream_info.dart | 22 +---- lib/src/videos/streams/bitrate.dart | 6 +- lib/src/videos/streams/bitrate.freezed.dart | 34 +++++-- lib/src/videos/streams/bitrate.g.dart | 16 +++ lib/src/videos/streams/filesize.dart | 6 +- lib/src/videos/streams/filesize.freezed.dart | 34 +++++-- lib/src/videos/streams/filesize.g.dart | 16 +++ lib/src/videos/streams/framerate.dart | 4 + lib/src/videos/streams/framerate.freezed.dart | 34 +++++-- lib/src/videos/streams/framerate.g.dart | 16 +++ lib/src/videos/streams/muxed_stream_info.dart | 43 +++++--- .../videos/streams/muxed_stream_info.g.dart | 54 ++++++++++ lib/src/videos/streams/stream_container.dart | 4 + .../streams/stream_container.freezed.dart | 33 +++++-- .../videos/streams/stream_container.g.dart | 17 ++++ lib/src/videos/streams/stream_info.dart | 30 +++--- lib/src/videos/streams/streams.dart | 2 +- lib/src/videos/streams/streams_client.dart | 39 ++++---- .../streams/video_only_stream_info.dart | 94 ++++++++++++------ .../streams/video_only_stream_info.g.dart | 57 +++++++++++ lib/src/videos/streams/video_resolution.dart | 10 ++ .../videos/streams/video_resolution.g.dart | 19 ++++ lib/src/videos/streams/video_stream_info.dart | 33 ++----- lib/src/videos/video.freezed.dart | 99 ++++++++----------- lib/src/videos/video_id.dart | 2 +- lib/src/videos/video_id.freezed.dart | 11 +-- pubspec.yaml | 10 +- 52 files changed, 852 insertions(+), 578 deletions(-) create mode 100644 lib/src/reverse_engineering/models/fragment.g.dart create mode 100644 lib/src/videos/streams/audio_only_stream_info.g.dart create mode 100644 lib/src/videos/streams/bitrate.g.dart create mode 100644 lib/src/videos/streams/filesize.g.dart create mode 100644 lib/src/videos/streams/framerate.g.dart create mode 100644 lib/src/videos/streams/muxed_stream_info.g.dart create mode 100644 lib/src/videos/streams/stream_container.g.dart create mode 100644 lib/src/videos/streams/video_only_stream_info.g.dart create mode 100644 lib/src/videos/streams/video_resolution.g.dart diff --git a/example/example.dart b/example/example.dart index 09771ca..9bf462c 100644 --- a/example/example.dart +++ b/example/example.dart @@ -3,10 +3,9 @@ import 'package:youtube_explode_dart/youtube_explode_dart.dart'; Future main() async { var yt = YoutubeExplode(); - var video = - await yt.videos.get('https://www.youtube.com/watch?v=AI7ULzgf8RU'); + var streamInfo = await yt.videos.streamsClient.getManifest('fRh_vgS2dFE'); - print('Title: ${video.title}'); + print(streamInfo); // Close the YoutubeExplode's http client. yt.close(); diff --git a/lib/src/channels/channel.freezed.dart b/lib/src/channels/channel.freezed.dart index 7cd87a9..825094c 100644 --- a/lib/src/channels/channel.freezed.dart +++ b/lib/src/channels/channel.freezed.dart @@ -182,26 +182,18 @@ class _$_Channel extends _Channel { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Channel && - (identical(other.id, id) || - const DeepCollectionEquality().equals(other.id, id)) && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.logoUrl, logoUrl) || - const DeepCollectionEquality() - .equals(other.logoUrl, logoUrl)) && + (other.runtimeType == runtimeType && + other is _Channel && + (identical(other.id, id) || other.id == id) && + (identical(other.title, title) || other.title == title) && + (identical(other.logoUrl, logoUrl) || other.logoUrl == logoUrl) && (identical(other.subscribersCount, subscribersCount) || - const DeepCollectionEquality() - .equals(other.subscribersCount, subscribersCount))); + other.subscribersCount == subscribersCount)); } @override int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(id) ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(logoUrl) ^ - const DeepCollectionEquality().hash(subscribersCount); + Object.hash(runtimeType, id, title, logoUrl, subscribersCount); @JsonKey(ignore: true) @override @@ -218,19 +210,19 @@ abstract class _Channel extends Channel { @override /// Channel ID. - ChannelId get id => throw _privateConstructorUsedError; + ChannelId get id; @override /// Channel title. - String get title => throw _privateConstructorUsedError; + String get title; @override /// URL of the channel's logo image. - String get logoUrl => throw _privateConstructorUsedError; + String get logoUrl; @override /// The (approximate) channel subscriber's count. - int? get subscribersCount => throw _privateConstructorUsedError; + int? get subscribersCount; @override @JsonKey(ignore: true) _$ChannelCopyWith<_Channel> get copyWith => diff --git a/lib/src/channels/channel_about.freezed.dart b/lib/src/channels/channel_about.freezed.dart index f994e01..dee40f4 100644 --- a/lib/src/channels/channel_about.freezed.dart +++ b/lib/src/channels/channel_about.freezed.dart @@ -249,39 +249,32 @@ class _$_ChannelAbout implements _ChannelAbout { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ChannelAbout && + (other.runtimeType == runtimeType && + other is _ChannelAbout && (identical(other.description, description) || - const DeepCollectionEquality() - .equals(other.description, description)) && + other.description == description) && (identical(other.viewCount, viewCount) || - const DeepCollectionEquality() - .equals(other.viewCount, viewCount)) && + other.viewCount == viewCount) && (identical(other.joinDate, joinDate) || - const DeepCollectionEquality() - .equals(other.joinDate, joinDate)) && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.thumbnails, thumbnails) || - const DeepCollectionEquality() - .equals(other.thumbnails, thumbnails)) && - (identical(other.country, country) || - const DeepCollectionEquality() - .equals(other.country, country)) && - (identical(other.channelLinks, channelLinks) || - const DeepCollectionEquality() - .equals(other.channelLinks, channelLinks))); + other.joinDate == joinDate) && + (identical(other.title, title) || other.title == title) && + const DeepCollectionEquality() + .equals(other.thumbnails, thumbnails) && + (identical(other.country, country) || other.country == country) && + const DeepCollectionEquality() + .equals(other.channelLinks, channelLinks)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(description) ^ - const DeepCollectionEquality().hash(viewCount) ^ - const DeepCollectionEquality().hash(joinDate) ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(thumbnails) ^ - const DeepCollectionEquality().hash(country) ^ - const DeepCollectionEquality().hash(channelLinks); + int get hashCode => Object.hash( + runtimeType, + description, + viewCount, + joinDate, + title, + const DeepCollectionEquality().hash(thumbnails), + country, + const DeepCollectionEquality().hash(channelLinks)); @JsonKey(ignore: true) @override @@ -302,32 +295,32 @@ abstract class _ChannelAbout implements ChannelAbout { @override /// Full channel description. - String get description => throw _privateConstructorUsedError; + String get description; @override /// Channel view count. - int get viewCount => throw _privateConstructorUsedError; + int get viewCount; @override /// Channel join date. /// Formatted as: Gen 01, 2000 - String get joinDate => throw _privateConstructorUsedError; + String get joinDate; @override /// Channel title. - String get title => throw _privateConstructorUsedError; + String get title; @override /// Channel thumbnails. - List get thumbnails => throw _privateConstructorUsedError; + List get thumbnails; @override /// Channel country. - String get country => throw _privateConstructorUsedError; + String get country; @override /// Channel links. - List get channelLinks => throw _privateConstructorUsedError; + List get channelLinks; @override @JsonKey(ignore: true) _$ChannelAboutCopyWith<_ChannelAbout> get copyWith => diff --git a/lib/src/channels/channel_id.freezed.dart b/lib/src/channels/channel_id.freezed.dart index 5cc00d6..ab5c650 100644 --- a/lib/src/channels/channel_id.freezed.dart +++ b/lib/src/channels/channel_id.freezed.dart @@ -109,14 +109,13 @@ class _$_ChannelId extends _ChannelId { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ChannelId && - (identical(other.value, value) || - const DeepCollectionEquality().equals(other.value, value))); + (other.runtimeType == runtimeType && + other is _ChannelId && + (identical(other.value, value) || other.value == value)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(value); + int get hashCode => Object.hash(runtimeType, value); @JsonKey(ignore: true) @override @@ -131,7 +130,7 @@ abstract class _ChannelId extends ChannelId { @override /// ID as a string. - String get value => throw _privateConstructorUsedError; + String get value; @override @JsonKey(ignore: true) _$ChannelIdCopyWith<_ChannelId> get copyWith => diff --git a/lib/src/channels/channel_link.freezed.dart b/lib/src/channels/channel_link.freezed.dart index 6475ff4..3b1ec35 100644 --- a/lib/src/channels/channel_link.freezed.dart +++ b/lib/src/channels/channel_link.freezed.dart @@ -155,21 +155,15 @@ class _$_ChannelLink implements _ChannelLink { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ChannelLink && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.url, url) || - const DeepCollectionEquality().equals(other.url, url)) && - (identical(other.icon, icon) || - const DeepCollectionEquality().equals(other.icon, icon))); + (other.runtimeType == runtimeType && + other is _ChannelLink && + (identical(other.title, title) || other.title == title) && + (identical(other.url, url) || other.url == url) && + (identical(other.icon, icon) || other.icon == icon)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(url) ^ - const DeepCollectionEquality().hash(icon); + int get hashCode => Object.hash(runtimeType, title, url, icon); @JsonKey(ignore: true) @override @@ -183,16 +177,16 @@ abstract class _ChannelLink implements ChannelLink { @override /// Link title. - String get title => throw _privateConstructorUsedError; + String get title; @override /// Link URL. /// Already decoded with the YouTube shortener already taken out. - Uri get url => throw _privateConstructorUsedError; + Uri get url; @override /// Link Icon URL. - Uri get icon => throw _privateConstructorUsedError; + Uri get icon; @override @JsonKey(ignore: true) _$ChannelLinkCopyWith<_ChannelLink> get copyWith => diff --git a/lib/src/channels/channel_video.freezed.dart b/lib/src/channels/channel_video.freezed.dart index cf8c2f1..2690d7b 100644 --- a/lib/src/channels/channel_video.freezed.dart +++ b/lib/src/channels/channel_video.freezed.dart @@ -235,36 +235,24 @@ class _$_ChannelVideo implements _ChannelVideo { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ChannelVideo && - (identical(other.videoId, videoId) || - const DeepCollectionEquality() - .equals(other.videoId, videoId)) && + (other.runtimeType == runtimeType && + other is _ChannelVideo && + (identical(other.videoId, videoId) || other.videoId == videoId) && (identical(other.videoTitle, videoTitle) || - const DeepCollectionEquality() - .equals(other.videoTitle, videoTitle)) && + other.videoTitle == videoTitle) && (identical(other.videoDuration, videoDuration) || - const DeepCollectionEquality() - .equals(other.videoDuration, videoDuration)) && + other.videoDuration == videoDuration) && (identical(other.videoThumbnail, videoThumbnail) || - const DeepCollectionEquality() - .equals(other.videoThumbnail, videoThumbnail)) && + other.videoThumbnail == videoThumbnail) && (identical(other.videoUploadDate, videoUploadDate) || - const DeepCollectionEquality() - .equals(other.videoUploadDate, videoUploadDate)) && + other.videoUploadDate == videoUploadDate) && (identical(other.videoViews, videoViews) || - const DeepCollectionEquality() - .equals(other.videoViews, videoViews))); + other.videoViews == videoViews)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(videoId) ^ - const DeepCollectionEquality().hash(videoTitle) ^ - const DeepCollectionEquality().hash(videoDuration) ^ - const DeepCollectionEquality().hash(videoThumbnail) ^ - const DeepCollectionEquality().hash(videoUploadDate) ^ - const DeepCollectionEquality().hash(videoViews); + int get hashCode => Object.hash(runtimeType, videoId, videoTitle, + videoDuration, videoThumbnail, videoUploadDate, videoViews); @JsonKey(ignore: true) @override @@ -284,28 +272,28 @@ abstract class _ChannelVideo implements ChannelVideo { @override /// Video ID. - VideoId get videoId => throw _privateConstructorUsedError; + VideoId get videoId; @override /// Video title. - String get videoTitle => throw _privateConstructorUsedError; + String get videoTitle; @override /// Video duration - Duration get videoDuration => throw _privateConstructorUsedError; + Duration get videoDuration; @override /// Video thumbnail - String get videoThumbnail => throw _privateConstructorUsedError; + String get videoThumbnail; @override /// Video upload date. /// Formatted like 10 hours ago - String get videoUploadDate => throw _privateConstructorUsedError; + String get videoUploadDate; @override /// Video view count. - int get videoViews => throw _privateConstructorUsedError; + int get videoViews; @override @JsonKey(ignore: true) _$ChannelVideoCopyWith<_ChannelVideo> get copyWith => diff --git a/lib/src/channels/username.freezed.dart b/lib/src/channels/username.freezed.dart index 8ca2c86..e9084d6 100644 --- a/lib/src/channels/username.freezed.dart +++ b/lib/src/channels/username.freezed.dart @@ -113,14 +113,13 @@ class _$_Username implements _Username { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Username && - (identical(other.value, value) || - const DeepCollectionEquality().equals(other.value, value))); + (other.runtimeType == runtimeType && + other is _Username && + (identical(other.value, value) || other.value == value)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(value); + int get hashCode => Object.hash(runtimeType, value); @JsonKey(ignore: true) @override @@ -134,7 +133,7 @@ abstract class _Username implements Username { @override /// User name as string. - String get value => throw _privateConstructorUsedError; + String get value; @override @JsonKey(ignore: true) _$UsernameCopyWith<_Username> get copyWith => diff --git a/lib/src/common/engagement.freezed.dart b/lib/src/common/engagement.freezed.dart index 2e0ca14..070822a 100644 --- a/lib/src/common/engagement.freezed.dart +++ b/lib/src/common/engagement.freezed.dart @@ -153,24 +153,19 @@ class _$_Engagement extends _Engagement { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Engagement && + (other.runtimeType == runtimeType && + other is _Engagement && (identical(other.viewCount, viewCount) || - const DeepCollectionEquality() - .equals(other.viewCount, viewCount)) && + other.viewCount == viewCount) && (identical(other.likeCount, likeCount) || - const DeepCollectionEquality() - .equals(other.likeCount, likeCount)) && + other.likeCount == likeCount) && (identical(other.dislikeCount, dislikeCount) || - const DeepCollectionEquality() - .equals(other.dislikeCount, dislikeCount))); + other.dislikeCount == dislikeCount)); } @override int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(viewCount) ^ - const DeepCollectionEquality().hash(likeCount) ^ - const DeepCollectionEquality().hash(dislikeCount); + Object.hash(runtimeType, viewCount, likeCount, dislikeCount); @JsonKey(ignore: true) @override @@ -186,15 +181,15 @@ abstract class _Engagement extends Engagement { @override /// View count. - int get viewCount => throw _privateConstructorUsedError; + int get viewCount; @override /// Like count. - int? get likeCount => throw _privateConstructorUsedError; + int? get likeCount; @override /// Dislike count. - int? get dislikeCount => throw _privateConstructorUsedError; + int? get dislikeCount; @override @JsonKey(ignore: true) _$EngagementCopyWith<_Engagement> get copyWith => diff --git a/lib/src/common/thumbnail.freezed.dart b/lib/src/common/thumbnail.freezed.dart index d42020f..b9af4fd 100644 --- a/lib/src/common/thumbnail.freezed.dart +++ b/lib/src/common/thumbnail.freezed.dart @@ -150,21 +150,15 @@ class _$_Thumbnail implements _Thumbnail { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Thumbnail && - (identical(other.url, url) || - const DeepCollectionEquality().equals(other.url, url)) && - (identical(other.height, height) || - const DeepCollectionEquality().equals(other.height, height)) && - (identical(other.width, width) || - const DeepCollectionEquality().equals(other.width, width))); + (other.runtimeType == runtimeType && + other is _Thumbnail && + (identical(other.url, url) || other.url == url) && + (identical(other.height, height) || other.height == height) && + (identical(other.width, width) || other.width == width)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(url) ^ - const DeepCollectionEquality().hash(height) ^ - const DeepCollectionEquality().hash(width); + int get hashCode => Object.hash(runtimeType, url, height, width); @JsonKey(ignore: true) @override @@ -178,15 +172,15 @@ abstract class _Thumbnail implements Thumbnail { @override /// Image url. - Uri get url => throw _privateConstructorUsedError; + Uri get url; @override /// Image height. - int get height => throw _privateConstructorUsedError; + int get height; @override /// Image width. - int get width => throw _privateConstructorUsedError; + int get width; @override @JsonKey(ignore: true) _$ThumbnailCopyWith<_Thumbnail> get copyWith => diff --git a/lib/src/common/thumbnail_set.freezed.dart b/lib/src/common/thumbnail_set.freezed.dart index cf7a3d0..e6dd5d8 100644 --- a/lib/src/common/thumbnail_set.freezed.dart +++ b/lib/src/common/thumbnail_set.freezed.dart @@ -117,14 +117,13 @@ class _$_ThumbnailSet extends _ThumbnailSet { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ThumbnailSet && - (identical(other.videoId, videoId) || - const DeepCollectionEquality().equals(other.videoId, videoId))); + (other.runtimeType == runtimeType && + other is _ThumbnailSet && + (identical(other.videoId, videoId) || other.videoId == videoId)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(videoId); + int get hashCode => Object.hash(runtimeType, videoId); @JsonKey(ignore: true) @override @@ -139,7 +138,7 @@ abstract class _ThumbnailSet extends ThumbnailSet { @override /// Video id. - String get videoId => throw _privateConstructorUsedError; + String get videoId; @override @JsonKey(ignore: true) _$ThumbnailSetCopyWith<_ThumbnailSet> get copyWith => diff --git a/lib/src/playlists/playlist.freezed.dart b/lib/src/playlists/playlist.freezed.dart index ec523e2..2391aeb 100644 --- a/lib/src/playlists/playlist.freezed.dart +++ b/lib/src/playlists/playlist.freezed.dart @@ -274,37 +274,24 @@ class _$_Playlist extends _Playlist { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Playlist && - (identical(other.id, id) || - const DeepCollectionEquality().equals(other.id, id)) && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.author, author) || - const DeepCollectionEquality().equals(other.author, author)) && + (other.runtimeType == runtimeType && + other is _Playlist && + (identical(other.id, id) || other.id == id) && + (identical(other.title, title) || other.title == title) && + (identical(other.author, author) || other.author == author) && (identical(other.description, description) || - const DeepCollectionEquality() - .equals(other.description, description)) && + other.description == description) && (identical(other.thumbnails, thumbnails) || - const DeepCollectionEquality() - .equals(other.thumbnails, thumbnails)) && + other.thumbnails == thumbnails) && (identical(other.engagement, engagement) || - const DeepCollectionEquality() - .equals(other.engagement, engagement)) && + other.engagement == engagement) && (identical(other.videoCount, videoCount) || - const DeepCollectionEquality() - .equals(other.videoCount, videoCount))); + other.videoCount == videoCount)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(id) ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(author) ^ - const DeepCollectionEquality().hash(description) ^ - const DeepCollectionEquality().hash(thumbnails) ^ - const DeepCollectionEquality().hash(engagement) ^ - const DeepCollectionEquality().hash(videoCount); + int get hashCode => Object.hash(runtimeType, id, title, author, description, + thumbnails, engagement, videoCount); @JsonKey(ignore: true) @override @@ -326,33 +313,33 @@ abstract class _Playlist extends Playlist { @override /// Playlist ID. - PlaylistId get id => throw _privateConstructorUsedError; + PlaylistId get id; @override /// Playlist title. - String get title => throw _privateConstructorUsedError; + String get title; @override /// Playlist author. /// Can be null if it's a system playlist (e.g. Video Mix, Topics, etc.). - String get author => throw _privateConstructorUsedError; + String get author; @override /// Playlist description. - String get description => throw _privateConstructorUsedError; + String get description; @override /// Available thumbnails for this playlist. /// Can be null if the playlist is empty. - ThumbnailSet get thumbnails => throw _privateConstructorUsedError; + ThumbnailSet get thumbnails; @override /// Engagement statistics. - Engagement get engagement => throw _privateConstructorUsedError; + Engagement get engagement; @override /// Total videos in this playlist. - int? get videoCount => throw _privateConstructorUsedError; + int? get videoCount; @override @JsonKey(ignore: true) _$PlaylistCopyWith<_Playlist> get copyWith => diff --git a/lib/src/playlists/playlist_id.freezed.dart b/lib/src/playlists/playlist_id.freezed.dart index b94b370..b0e97c1 100644 --- a/lib/src/playlists/playlist_id.freezed.dart +++ b/lib/src/playlists/playlist_id.freezed.dart @@ -111,14 +111,13 @@ class _$_PlaylistId extends _PlaylistId { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _PlaylistId && - (identical(other.value, value) || - const DeepCollectionEquality().equals(other.value, value))); + (other.runtimeType == runtimeType && + other is _PlaylistId && + (identical(other.value, value) || other.value == value)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(value); + int get hashCode => Object.hash(runtimeType, value); @JsonKey(ignore: true) @override @@ -133,7 +132,7 @@ abstract class _PlaylistId extends PlaylistId { @override /// The playlist id as string. - String get value => throw _privateConstructorUsedError; + String get value; @override @JsonKey(ignore: true) _$PlaylistIdCopyWith<_PlaylistId> get copyWith => diff --git a/lib/src/reverse_engineering/models/fragment.dart b/lib/src/reverse_engineering/models/fragment.dart index df7ddf0..87a9582 100644 --- a/lib/src/reverse_engineering/models/fragment.dart +++ b/lib/src/reverse_engineering/models/fragment.dart @@ -1,6 +1,16 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'fragment.g.dart'; + /// Fragment used for DASH Manifests. +@JsonSerializable() class Fragment { final String path; const Fragment(this.path); + + factory Fragment.fromJson(Map json) => + _$FragmentFromJson(json); + + Map toJson() => _$FragmentToJson(this); } diff --git a/lib/src/reverse_engineering/models/fragment.g.dart b/lib/src/reverse_engineering/models/fragment.g.dart new file mode 100644 index 0000000..07aba84 --- /dev/null +++ b/lib/src/reverse_engineering/models/fragment.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'fragment.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Fragment _$FragmentFromJson(Map json) => Fragment( + json['path'] as String, + ); + +Map _$FragmentToJson(Fragment instance) => { + 'path': instance.path, + }; diff --git a/lib/src/search/search_channel.dart b/lib/src/search/search_channel.dart index c5e12c9..faa8f81 100644 --- a/lib/src/search/search_channel.dart +++ b/lib/src/search/search_channel.dart @@ -9,7 +9,7 @@ part 'search_channel.freezed.dart'; @freezed class SearchChannel with _$SearchChannel, BaseSearchContent { /// Initialize a [SearchChannel] instance. - @With(BaseSearchContent) + @With() const factory SearchChannel( /// Channel id. diff --git a/lib/src/search/search_channel.freezed.dart b/lib/src/search/search_channel.freezed.dart index acf8e81..853324e 100644 --- a/lib/src/search/search_channel.freezed.dart +++ b/lib/src/search/search_channel.freezed.dart @@ -159,7 +159,7 @@ class __$SearchChannelCopyWithImpl<$Res> /// @nodoc -@With(BaseSearchContent) +@With() class _$_SearchChannel with BaseSearchContent implements _SearchChannel { const _$_SearchChannel(this.id, this.name, this.description, this.videoCount); @@ -189,26 +189,19 @@ class _$_SearchChannel with BaseSearchContent implements _SearchChannel { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _SearchChannel && - (identical(other.id, id) || - const DeepCollectionEquality().equals(other.id, id)) && - (identical(other.name, name) || - const DeepCollectionEquality().equals(other.name, name)) && + (other.runtimeType == runtimeType && + other is _SearchChannel && + (identical(other.id, id) || other.id == id) && + (identical(other.name, name) || other.name == name) && (identical(other.description, description) || - const DeepCollectionEquality() - .equals(other.description, description)) && + other.description == description) && (identical(other.videoCount, videoCount) || - const DeepCollectionEquality() - .equals(other.videoCount, videoCount))); + other.videoCount == videoCount)); } @override int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(id) ^ - const DeepCollectionEquality().hash(name) ^ - const DeepCollectionEquality().hash(description) ^ - const DeepCollectionEquality().hash(videoCount); + Object.hash(runtimeType, id, name, description, videoCount); @JsonKey(ignore: true) @override @@ -224,20 +217,20 @@ abstract class _SearchChannel implements SearchChannel, BaseSearchContent { @override /// Channel id. - ChannelId get id => throw _privateConstructorUsedError; + ChannelId get id; @override /// Channel name. - String get name => throw _privateConstructorUsedError; + String get name; @override /// Description snippet. /// Can be empty. - String get description => throw _privateConstructorUsedError; + String get description; @override /// Channel uploaded videos. - int get videoCount => throw _privateConstructorUsedError; + int get videoCount; @override @JsonKey(ignore: true) _$SearchChannelCopyWith<_SearchChannel> get copyWith => diff --git a/lib/src/search/search_playlist.dart b/lib/src/search/search_playlist.dart index cb34b3f..8f4c85c 100644 --- a/lib/src/search/search_playlist.dart +++ b/lib/src/search/search_playlist.dart @@ -10,7 +10,7 @@ part 'search_playlist.freezed.dart'; @freezed class SearchPlaylist with _$SearchPlaylist, BaseSearchContent { /// Initialize a [SearchPlaylist] instance. - @With(BaseSearchContent) + @With() const factory SearchPlaylist( /// PlaylistId. diff --git a/lib/src/search/search_playlist.freezed.dart b/lib/src/search/search_playlist.freezed.dart index 4972758..9295e8c 100644 --- a/lib/src/search/search_playlist.freezed.dart +++ b/lib/src/search/search_playlist.freezed.dart @@ -166,7 +166,7 @@ class __$SearchPlaylistCopyWithImpl<$Res> /// @nodoc -@With(BaseSearchContent) +@With() class _$_SearchPlaylist with BaseSearchContent implements _SearchPlaylist { const _$_SearchPlaylist(this.playlistId, this.playlistTitle, this.playlistVideoCount, this.thumbnails); @@ -196,28 +196,21 @@ class _$_SearchPlaylist with BaseSearchContent implements _SearchPlaylist { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _SearchPlaylist && + (other.runtimeType == runtimeType && + other is _SearchPlaylist && (identical(other.playlistId, playlistId) || - const DeepCollectionEquality() - .equals(other.playlistId, playlistId)) && + other.playlistId == playlistId) && (identical(other.playlistTitle, playlistTitle) || - const DeepCollectionEquality() - .equals(other.playlistTitle, playlistTitle)) && + other.playlistTitle == playlistTitle) && (identical(other.playlistVideoCount, playlistVideoCount) || - const DeepCollectionEquality() - .equals(other.playlistVideoCount, playlistVideoCount)) && - (identical(other.thumbnails, thumbnails) || - const DeepCollectionEquality() - .equals(other.thumbnails, thumbnails))); + other.playlistVideoCount == playlistVideoCount) && + const DeepCollectionEquality() + .equals(other.thumbnails, thumbnails)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(playlistId) ^ - const DeepCollectionEquality().hash(playlistTitle) ^ - const DeepCollectionEquality().hash(playlistVideoCount) ^ - const DeepCollectionEquality().hash(thumbnails); + int get hashCode => Object.hash(runtimeType, playlistId, playlistTitle, + playlistVideoCount, const DeepCollectionEquality().hash(thumbnails)); @JsonKey(ignore: true) @override @@ -232,19 +225,19 @@ abstract class _SearchPlaylist implements SearchPlaylist, BaseSearchContent { @override /// PlaylistId. - PlaylistId get playlistId => throw _privateConstructorUsedError; + PlaylistId get playlistId; @override /// Playlist title. - String get playlistTitle => throw _privateConstructorUsedError; + String get playlistTitle; @override /// Playlist video count, cannot be greater than 50. - int get playlistVideoCount => throw _privateConstructorUsedError; + int get playlistVideoCount; @override /// Video thumbnail - List get thumbnails => throw _privateConstructorUsedError; + List get thumbnails; @override @JsonKey(ignore: true) _$SearchPlaylistCopyWith<_SearchPlaylist> get copyWith => diff --git a/lib/src/search/search_video.dart b/lib/src/search/search_video.dart index adb45fb..5f241ff 100644 --- a/lib/src/search/search_video.dart +++ b/lib/src/search/search_video.dart @@ -10,7 +10,7 @@ part 'search_video.freezed.dart'; @freezed class SearchVideo with _$SearchVideo, BaseSearchContent { /// Initialize a [SearchVideo] instance. - @With(BaseSearchContent) + @With() const factory SearchVideo( /// Video ID. VideoId id, diff --git a/lib/src/search/search_video.freezed.dart b/lib/src/search/search_video.freezed.dart index 9dc50c3..ddf02c0 100644 --- a/lib/src/search/search_video.freezed.dart +++ b/lib/src/search/search_video.freezed.dart @@ -270,7 +270,7 @@ class __$SearchVideoCopyWithImpl<$Res> extends _$SearchVideoCopyWithImpl<$Res> /// @nodoc -@With(BaseSearchContent) +@With() class _$_SearchVideo with BaseSearchContent implements _SearchVideo { const _$_SearchVideo( this.id, @@ -334,48 +334,39 @@ class _$_SearchVideo with BaseSearchContent implements _SearchVideo { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _SearchVideo && - (identical(other.id, id) || - const DeepCollectionEquality().equals(other.id, id)) && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.author, author) || - const DeepCollectionEquality().equals(other.author, author)) && + (other.runtimeType == runtimeType && + other is _SearchVideo && + (identical(other.id, id) || other.id == id) && + (identical(other.title, title) || other.title == title) && + (identical(other.author, author) || other.author == author) && (identical(other.description, description) || - const DeepCollectionEquality() - .equals(other.description, description)) && + other.description == description) && (identical(other.duration, duration) || - const DeepCollectionEquality() - .equals(other.duration, duration)) && + other.duration == duration) && (identical(other.viewCount, viewCount) || - const DeepCollectionEquality() - .equals(other.viewCount, viewCount)) && - (identical(other.thumbnails, thumbnails) || - const DeepCollectionEquality() - .equals(other.thumbnails, thumbnails)) && + other.viewCount == viewCount) && + const DeepCollectionEquality() + .equals(other.thumbnails, thumbnails) && (identical(other.uploadDate, uploadDate) || - const DeepCollectionEquality() - .equals(other.uploadDate, uploadDate)) && - (identical(other.isLive, isLive) || - const DeepCollectionEquality().equals(other.isLive, isLive)) && + other.uploadDate == uploadDate) && + (identical(other.isLive, isLive) || other.isLive == isLive) && (identical(other.channelId, channelId) || - const DeepCollectionEquality() - .equals(other.channelId, channelId))); + other.channelId == channelId)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(id) ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(author) ^ - const DeepCollectionEquality().hash(description) ^ - const DeepCollectionEquality().hash(duration) ^ - const DeepCollectionEquality().hash(viewCount) ^ - const DeepCollectionEquality().hash(thumbnails) ^ - const DeepCollectionEquality().hash(uploadDate) ^ - const DeepCollectionEquality().hash(isLive) ^ - const DeepCollectionEquality().hash(channelId); + int get hashCode => Object.hash( + runtimeType, + id, + title, + author, + description, + duration, + viewCount, + const DeepCollectionEquality().hash(thumbnails), + uploadDate, + isLive, + channelId); @JsonKey(ignore: true) @override @@ -399,44 +390,44 @@ abstract class _SearchVideo implements SearchVideo, BaseSearchContent { @override /// Video ID. - VideoId get id => throw _privateConstructorUsedError; + VideoId get id; @override /// Video title. - String get title => throw _privateConstructorUsedError; + String get title; @override /// Video author. - String get author => throw _privateConstructorUsedError; + String get author; @override /// Video description snippet. (Part of the full description if too long) - String get description => throw _privateConstructorUsedError; + String get description; @override /// Video duration as String, HH:MM:SS - String get duration => throw _privateConstructorUsedError; + String get duration; @override /// Video View Count - int get viewCount => throw _privateConstructorUsedError; + int get viewCount; @override /// Video thumbnail - List get thumbnails => throw _privateConstructorUsedError; + List get thumbnails; @override /// Video upload date - As string: 5 years ago. - String? get uploadDate => throw _privateConstructorUsedError; + String? get uploadDate; @override /// True if this video is a live stream. // ignore: avoid_positional_boolean_parameters - bool get isLive => throw _privateConstructorUsedError; + bool get isLive; @override /// Channel id - String get channelId => throw _privateConstructorUsedError; + String get channelId; @override @JsonKey(ignore: true) _$SearchVideoCopyWith<_SearchVideo> get copyWith => diff --git a/lib/src/videos/closed_captions/closed_caption_track_info.freezed.dart b/lib/src/videos/closed_captions/closed_caption_track_info.freezed.dart index b1b20b8..d4ec33a 100644 --- a/lib/src/videos/closed_captions/closed_caption_track_info.freezed.dart +++ b/lib/src/videos/closed_captions/closed_caption_track_info.freezed.dart @@ -32,7 +32,7 @@ class _$ClosedCaptionTrackInfoTearOff { ); } - ClosedCaptionTrackInfo fromJson(Map json) { + ClosedCaptionTrackInfo fromJson(Map json) { return ClosedCaptionTrackInfo.fromJson(json); } } @@ -205,26 +205,19 @@ class _$_ClosedCaptionTrackInfo extends _ClosedCaptionTrackInfo { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ClosedCaptionTrackInfo && - (identical(other.url, url) || - const DeepCollectionEquality().equals(other.url, url)) && + (other.runtimeType == runtimeType && + other is _ClosedCaptionTrackInfo && + (identical(other.url, url) || other.url == url) && (identical(other.language, language) || - const DeepCollectionEquality() - .equals(other.language, language)) && + other.language == language) && (identical(other.isAutoGenerated, isAutoGenerated) || - const DeepCollectionEquality() - .equals(other.isAutoGenerated, isAutoGenerated)) && - (identical(other.format, format) || - const DeepCollectionEquality().equals(other.format, format))); + other.isAutoGenerated == isAutoGenerated) && + (identical(other.format, format) || other.format == format)); } @override int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(url) ^ - const DeepCollectionEquality().hash(language) ^ - const DeepCollectionEquality().hash(isAutoGenerated) ^ - const DeepCollectionEquality().hash(format); + Object.hash(runtimeType, url, language, isAutoGenerated, format); @JsonKey(ignore: true) @override @@ -250,19 +243,19 @@ abstract class _ClosedCaptionTrackInfo extends ClosedCaptionTrackInfo { @override /// Manifest URL of the associated track. - Uri get url => throw _privateConstructorUsedError; + Uri get url; @override /// Language of the associated track. - Language get language => throw _privateConstructorUsedError; + Language get language; @override /// Whether the associated track was automatically generated. - bool get isAutoGenerated => throw _privateConstructorUsedError; + bool get isAutoGenerated; @override /// Track format - ClosedCaptionFormat get format => throw _privateConstructorUsedError; + ClosedCaptionFormat get format; @override @JsonKey(ignore: true) _$ClosedCaptionTrackInfoCopyWith<_ClosedCaptionTrackInfo> get copyWith => diff --git a/lib/src/videos/closed_captions/language.freezed.dart b/lib/src/videos/closed_captions/language.freezed.dart index 7284d2b..e23176e 100644 --- a/lib/src/videos/closed_captions/language.freezed.dart +++ b/lib/src/videos/closed_captions/language.freezed.dart @@ -28,7 +28,7 @@ class _$LanguageTearOff { ); } - Language fromJson(Map json) { + Language fromJson(Map json) { return Language.fromJson(json); } } @@ -143,18 +143,14 @@ class _$_Language extends _Language { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Language && - (identical(other.code, code) || - const DeepCollectionEquality().equals(other.code, code)) && - (identical(other.name, name) || - const DeepCollectionEquality().equals(other.name, name))); + (other.runtimeType == runtimeType && + other is _Language && + (identical(other.code, code) || other.code == code) && + (identical(other.name, name) || other.name == name)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(code) ^ - const DeepCollectionEquality().hash(name); + int get hashCode => Object.hash(runtimeType, code, name); @JsonKey(ignore: true) @override @@ -176,11 +172,11 @@ abstract class _Language extends Language { @override /// ISO 639-1 code of this language. - String get code => throw _privateConstructorUsedError; + String get code; @override /// Full English name of this language. This could be an empty string. - String get name => throw _privateConstructorUsedError; + String get name; @override @JsonKey(ignore: true) _$LanguageCopyWith<_Language> get copyWith => diff --git a/lib/src/videos/comments/comment.freezed.dart b/lib/src/videos/comments/comment.freezed.dart index 3b36d15..9a061d4 100644 --- a/lib/src/videos/comments/comment.freezed.dart +++ b/lib/src/videos/comments/comment.freezed.dart @@ -288,42 +288,27 @@ class _$_Comment implements _Comment { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Comment && - (identical(other.author, author) || - const DeepCollectionEquality().equals(other.author, author)) && + (other.runtimeType == runtimeType && + other is _Comment && + (identical(other.author, author) || other.author == author) && (identical(other.channelId, channelId) || - const DeepCollectionEquality() - .equals(other.channelId, channelId)) && - (identical(other.text, text) || - const DeepCollectionEquality().equals(other.text, text)) && + other.channelId == channelId) && + (identical(other.text, text) || other.text == text) && (identical(other.likeCount, likeCount) || - const DeepCollectionEquality() - .equals(other.likeCount, likeCount)) && + other.likeCount == likeCount) && (identical(other.publishedTime, publishedTime) || - const DeepCollectionEquality() - .equals(other.publishedTime, publishedTime)) && + other.publishedTime == publishedTime) && (identical(other.replyCount, replyCount) || - const DeepCollectionEquality() - .equals(other.replyCount, replyCount)) && + other.replyCount == replyCount) && (identical(other.isHearted, isHearted) || - const DeepCollectionEquality() - .equals(other.isHearted, isHearted)) && + other.isHearted == isHearted) && (identical(other.continuation, continuation) || - const DeepCollectionEquality() - .equals(other.continuation, continuation))); + other.continuation == continuation)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(author) ^ - const DeepCollectionEquality().hash(channelId) ^ - const DeepCollectionEquality().hash(text) ^ - const DeepCollectionEquality().hash(likeCount) ^ - const DeepCollectionEquality().hash(publishedTime) ^ - const DeepCollectionEquality().hash(replyCount) ^ - const DeepCollectionEquality().hash(isHearted) ^ - const DeepCollectionEquality().hash(continuation); + int get hashCode => Object.hash(runtimeType, author, channelId, text, + likeCount, publishedTime, replyCount, isHearted, continuation); @JsonKey(ignore: true) @override @@ -345,38 +330,38 @@ abstract class _Comment implements Comment { @override /// Comment author name. - String get author => throw _privateConstructorUsedError; + String get author; @override /// Comment author channel id. - ChannelId get channelId => throw _privateConstructorUsedError; + ChannelId get channelId; @override /// Comment text. - String get text => throw _privateConstructorUsedError; + String get text; @override /// Comment likes count. - int get likeCount => throw _privateConstructorUsedError; + int get likeCount; @override /// Published time as string. (For example: "2 years ago") - String get publishedTime => throw _privateConstructorUsedError; + String get publishedTime; @override /// Comment reply count. - int get replyCount => throw _privateConstructorUsedError; + int get replyCount; @override /// True if the comment is hearted by the creator. //ignore: avoid_positional_boolean_parameters - bool get isHearted => throw _privateConstructorUsedError; + bool get isHearted; @override /// Used internally. /// Shouldn't be used in the code. @internal - String? get continuation => throw _privateConstructorUsedError; + String? get continuation; @override @JsonKey(ignore: true) _$CommentCopyWith<_Comment> get copyWith => diff --git a/lib/src/videos/streams/audio_only_stream_info.dart b/lib/src/videos/streams/audio_only_stream_info.dart index 15f79a6..7a5af7a 100644 --- a/lib/src/videos/streams/audio_only_stream_info.dart +++ b/lib/src/videos/streams/audio_only_stream_info.dart @@ -1,23 +1,60 @@ import 'package:http_parser/http_parser.dart'; +import 'package:json_annotation/json_annotation.dart'; import '../../reverse_engineering/models/fragment.dart'; +import 'stream_info.dart'; import 'streams.dart'; +part 'audio_only_stream_info.g.dart'; + /// YouTube media stream that only contains audio. -class AudioOnlyStreamInfo extends AudioStreamInfo { +@JsonSerializable() +class AudioOnlyStreamInfo with StreamInfo, AudioStreamInfo { + @override + final int tag; + + @override + final Uri url; + + @override + final StreamContainer container; + + @override + final FileSize size; + + @override + final Bitrate bitrate; + + @override + final String audioCodec; + + @override + @JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson) + final MediaType codec; + + @override + final List fragments; + + @override + final String qualityLabel; + AudioOnlyStreamInfo( - int tag, - Uri url, - StreamContainer container, - FileSize size, - Bitrate bitrate, - String audioCodec, - List fragments, - MediaType codec, - String qualityLabel) - : super(tag, url, container, size, bitrate, audioCodec, fragments, codec, - qualityLabel); + this.tag, + this.url, + this.container, + this.size, + this.bitrate, + this.audioCodec, + this.qualityLabel, + this.fragments, + this.codec); @override String toString() => 'Audio-only ($tag | $container)'; + + factory AudioOnlyStreamInfo.fromJson(Map json) => + _$AudioOnlyStreamInfoFromJson(json); + + Map toJson() => _$AudioOnlyStreamInfoToJson(this); + } diff --git a/lib/src/videos/streams/audio_only_stream_info.g.dart b/lib/src/videos/streams/audio_only_stream_info.g.dart new file mode 100644 index 0000000..d397580 --- /dev/null +++ b/lib/src/videos/streams/audio_only_stream_info.g.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'audio_only_stream_info.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AudioOnlyStreamInfo _$AudioOnlyStreamInfoFromJson(Map json) => + AudioOnlyStreamInfo( + json['tag'] as int, + Uri.parse(json['url'] as String), + StreamContainer.fromJson(json['container'] as Map), + FileSize.fromJson(json['size'] as Map), + Bitrate.fromJson(json['bitrate'] as Map), + json['audioCodec'] as String, + json['qualityLabel'] as String, + (json['fragments'] as List) + .map((e) => Fragment.fromJson(e as Map)) + .toList(), + mediaTypeFromJson(json['codec'] as String), + ); + +Map _$AudioOnlyStreamInfoToJson( + AudioOnlyStreamInfo instance) => + { + '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, + }; diff --git a/lib/src/videos/streams/audio_stream_info.dart b/lib/src/videos/streams/audio_stream_info.dart index b9334c1..ff91af2 100644 --- a/lib/src/videos/streams/audio_stream_info.dart +++ b/lib/src/videos/streams/audio_stream_info.dart @@ -1,24 +1,6 @@ -import 'package:http_parser/http_parser.dart'; - -import '../../reverse_engineering/models/fragment.dart'; import 'streams.dart'; /// YouTube media stream that contains audio. -abstract class AudioStreamInfo extends StreamInfo { - /// Audio codec. - final String audioCodec; - - /// - AudioStreamInfo( - int tag, - Uri url, - StreamContainer container, - FileSize size, - Bitrate bitrate, - this.audioCodec, - List fragments, - MediaType codec, - String qualityLabel) - : super( - tag, url, container, size, bitrate, fragments, codec, qualityLabel); +mixin AudioStreamInfo on StreamInfo { + String get audioCodec; } diff --git a/lib/src/videos/streams/bitrate.dart b/lib/src/videos/streams/bitrate.dart index 287430e..5351f4e 100644 --- a/lib/src/videos/streams/bitrate.dart +++ b/lib/src/videos/streams/bitrate.dart @@ -1,6 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'bitrate.freezed.dart'; +part 'bitrate.g.dart'; /// Encapsulates bitrate. @freezed @@ -15,12 +16,15 @@ class Bitrate with Comparable, _$Bitrate { double get gigaBitsPerSecond => megaBitsPerSecond / 1024; /// Initializes an instance of [Bitrate] - @With.fromString('Comparable') + @With>() const factory Bitrate( /// Bits per second. int bitsPerSecond) = _Bitrate; + factory Bitrate.fromJson(Map json) => + _$BitrateFromJson(json); + const Bitrate._(); static const Bitrate unknown = Bitrate(0); diff --git a/lib/src/videos/streams/bitrate.freezed.dart b/lib/src/videos/streams/bitrate.freezed.dart index fb7a6bf..12ce6dd 100644 --- a/lib/src/videos/streams/bitrate.freezed.dart +++ b/lib/src/videos/streams/bitrate.freezed.dart @@ -13,6 +13,10 @@ T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); +Bitrate _$BitrateFromJson(Map json) { + return _Bitrate.fromJson(json); +} + /// @nodoc class _$BitrateTearOff { const _$BitrateTearOff(); @@ -22,6 +26,10 @@ class _$BitrateTearOff { bitsPerSecond, ); } + + Bitrate fromJson(Map json) { + return Bitrate.fromJson(json); + } } /// @nodoc @@ -32,6 +40,7 @@ mixin _$Bitrate { /// Bits per second. int get bitsPerSecond => throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) $BitrateCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -95,11 +104,14 @@ class __$BitrateCopyWithImpl<$Res> extends _$BitrateCopyWithImpl<$Res> } /// @nodoc - -@With.fromString('Comparable') +@JsonSerializable() +@With>() class _$_Bitrate extends _Bitrate with Comparable { const _$_Bitrate(this.bitsPerSecond) : super._(); + factory _$_Bitrate.fromJson(Map json) => + _$$_BitrateFromJson(json); + @override /// Bits per second. @@ -108,30 +120,36 @@ class _$_Bitrate extends _Bitrate with Comparable { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Bitrate && + (other.runtimeType == runtimeType && + other is _Bitrate && (identical(other.bitsPerSecond, bitsPerSecond) || - const DeepCollectionEquality() - .equals(other.bitsPerSecond, bitsPerSecond))); + other.bitsPerSecond == bitsPerSecond)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(bitsPerSecond); + int get hashCode => Object.hash(runtimeType, bitsPerSecond); @JsonKey(ignore: true) @override _$BitrateCopyWith<_Bitrate> get copyWith => __$BitrateCopyWithImpl<_Bitrate>(this, _$identity); + + @override + Map toJson() { + return _$$_BitrateToJson(this); + } } abstract class _Bitrate extends Bitrate implements Comparable { const factory _Bitrate(int bitsPerSecond) = _$_Bitrate; const _Bitrate._() : super._(); + factory _Bitrate.fromJson(Map json) = _$_Bitrate.fromJson; + @override /// Bits per second. - int get bitsPerSecond => throw _privateConstructorUsedError; + int get bitsPerSecond; @override @JsonKey(ignore: true) _$BitrateCopyWith<_Bitrate> get copyWith => diff --git a/lib/src/videos/streams/bitrate.g.dart b/lib/src/videos/streams/bitrate.g.dart new file mode 100644 index 0000000..bce853c --- /dev/null +++ b/lib/src/videos/streams/bitrate.g.dart @@ -0,0 +1,16 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'bitrate.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_Bitrate _$$_BitrateFromJson(Map json) => _$_Bitrate( + json['bitsPerSecond'] as int, + ); + +Map _$$_BitrateToJson(_$_Bitrate instance) => + { + 'bitsPerSecond': instance.bitsPerSecond, + }; diff --git a/lib/src/videos/streams/filesize.dart b/lib/src/videos/streams/filesize.dart index d73c960..c94001d 100644 --- a/lib/src/videos/streams/filesize.dart +++ b/lib/src/videos/streams/filesize.dart @@ -1,6 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'filesize.freezed.dart'; +part 'filesize.g.dart'; /// Encapsulates file size. @freezed @@ -15,12 +16,15 @@ class FileSize with Comparable, _$FileSize { double get totalGigaBytes => totalMegaBytes / 1024; /// Initializes an instance of [FileSize] - @With.fromString('Comparable') + @With>() const factory FileSize( /// Total bytes. int totalBytes) = _FileSize; + factory FileSize.fromJson(Map json) => + _$FileSizeFromJson(json); + const FileSize._(); static const FileSize unknown = FileSize(0); diff --git a/lib/src/videos/streams/filesize.freezed.dart b/lib/src/videos/streams/filesize.freezed.dart index 47bbe06..512c2f8 100644 --- a/lib/src/videos/streams/filesize.freezed.dart +++ b/lib/src/videos/streams/filesize.freezed.dart @@ -13,6 +13,10 @@ T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); +FileSize _$FileSizeFromJson(Map json) { + return _FileSize.fromJson(json); +} + /// @nodoc class _$FileSizeTearOff { const _$FileSizeTearOff(); @@ -22,6 +26,10 @@ class _$FileSizeTearOff { totalBytes, ); } + + FileSize fromJson(Map json) { + return FileSize.fromJson(json); + } } /// @nodoc @@ -32,6 +40,7 @@ mixin _$FileSize { /// Total bytes. int get totalBytes => throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) $FileSizeCopyWith get copyWith => throw _privateConstructorUsedError; @@ -96,11 +105,14 @@ class __$FileSizeCopyWithImpl<$Res> extends _$FileSizeCopyWithImpl<$Res> } /// @nodoc - -@With.fromString('Comparable') +@JsonSerializable() +@With>() class _$_FileSize extends _FileSize with Comparable { const _$_FileSize(this.totalBytes) : super._(); + factory _$_FileSize.fromJson(Map json) => + _$$_FileSizeFromJson(json); + @override /// Total bytes. @@ -109,30 +121,36 @@ class _$_FileSize extends _FileSize with Comparable { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _FileSize && + (other.runtimeType == runtimeType && + other is _FileSize && (identical(other.totalBytes, totalBytes) || - const DeepCollectionEquality() - .equals(other.totalBytes, totalBytes))); + other.totalBytes == totalBytes)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(totalBytes); + int get hashCode => Object.hash(runtimeType, totalBytes); @JsonKey(ignore: true) @override _$FileSizeCopyWith<_FileSize> get copyWith => __$FileSizeCopyWithImpl<_FileSize>(this, _$identity); + + @override + Map toJson() { + return _$$_FileSizeToJson(this); + } } abstract class _FileSize extends FileSize implements Comparable { const factory _FileSize(int totalBytes) = _$_FileSize; const _FileSize._() : super._(); + factory _FileSize.fromJson(Map json) = _$_FileSize.fromJson; + @override /// Total bytes. - int get totalBytes => throw _privateConstructorUsedError; + int get totalBytes; @override @JsonKey(ignore: true) _$FileSizeCopyWith<_FileSize> get copyWith => diff --git a/lib/src/videos/streams/filesize.g.dart b/lib/src/videos/streams/filesize.g.dart new file mode 100644 index 0000000..d07ecd9 --- /dev/null +++ b/lib/src/videos/streams/filesize.g.dart @@ -0,0 +1,16 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'filesize.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_FileSize _$$_FileSizeFromJson(Map json) => _$_FileSize( + json['totalBytes'] as int, + ); + +Map _$$_FileSizeToJson(_$_FileSize instance) => + { + 'totalBytes': instance.totalBytes, + }; diff --git a/lib/src/videos/streams/framerate.dart b/lib/src/videos/streams/framerate.dart index 675962a..0c59536 100644 --- a/lib/src/videos/streams/framerate.dart +++ b/lib/src/videos/streams/framerate.dart @@ -1,6 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'framerate.freezed.dart'; +part 'framerate.g.dart'; /// Encapsulates framerate. @freezed @@ -13,6 +14,9 @@ class Framerate with Comparable, _$Framerate { const Framerate._(); + factory Framerate.fromJson(Map json) => + _$FramerateFromJson(json); + /// bool operator >(Framerate other) => framesPerSecond > other.framesPerSecond; diff --git a/lib/src/videos/streams/framerate.freezed.dart b/lib/src/videos/streams/framerate.freezed.dart index f689f21..205a0c7 100644 --- a/lib/src/videos/streams/framerate.freezed.dart +++ b/lib/src/videos/streams/framerate.freezed.dart @@ -13,6 +13,10 @@ T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); +Framerate _$FramerateFromJson(Map json) { + return _Framerate.fromJson(json); +} + /// @nodoc class _$FramerateTearOff { const _$FramerateTearOff(); @@ -22,6 +26,10 @@ class _$FramerateTearOff { framesPerSecond, ); } + + Framerate fromJson(Map json) { + return Framerate.fromJson(json); + } } /// @nodoc @@ -32,6 +40,7 @@ mixin _$Framerate { /// Framerate as frames per second num get framesPerSecond => throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) $FramerateCopyWith get copyWith => throw _privateConstructorUsedError; @@ -97,10 +106,13 @@ class __$FramerateCopyWithImpl<$Res> extends _$FramerateCopyWithImpl<$Res> } /// @nodoc - +@JsonSerializable() class _$_Framerate extends _Framerate { const _$_Framerate(this.framesPerSecond) : super._(); + factory _$_Framerate.fromJson(Map json) => + _$$_FramerateFromJson(json); + @override /// Framerate as frames per second @@ -109,31 +121,37 @@ class _$_Framerate extends _Framerate { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Framerate && + (other.runtimeType == runtimeType && + other is _Framerate && (identical(other.framesPerSecond, framesPerSecond) || - const DeepCollectionEquality() - .equals(other.framesPerSecond, framesPerSecond))); + other.framesPerSecond == framesPerSecond)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(framesPerSecond); + int get hashCode => Object.hash(runtimeType, framesPerSecond); @JsonKey(ignore: true) @override _$FramerateCopyWith<_Framerate> get copyWith => __$FramerateCopyWithImpl<_Framerate>(this, _$identity); + + @override + Map toJson() { + return _$$_FramerateToJson(this); + } } abstract class _Framerate extends Framerate { const factory _Framerate(num framesPerSecond) = _$_Framerate; const _Framerate._() : super._(); + factory _Framerate.fromJson(Map json) = + _$_Framerate.fromJson; + @override /// Framerate as frames per second - num get framesPerSecond => throw _privateConstructorUsedError; + num get framesPerSecond; @override @JsonKey(ignore: true) _$FramerateCopyWith<_Framerate> get copyWith => diff --git a/lib/src/videos/streams/framerate.g.dart b/lib/src/videos/streams/framerate.g.dart new file mode 100644 index 0000000..d0ff88f --- /dev/null +++ b/lib/src/videos/streams/framerate.g.dart @@ -0,0 +1,16 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'framerate.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_Framerate _$$_FramerateFromJson(Map json) => _$_Framerate( + json['framesPerSecond'] as num, + ); + +Map _$$_FramerateToJson(_$_Framerate instance) => + { + 'framesPerSecond': instance.framesPerSecond, + }; diff --git a/lib/src/videos/streams/muxed_stream_info.dart b/lib/src/videos/streams/muxed_stream_info.dart index 919e08f..1635eb5 100644 --- a/lib/src/videos/streams/muxed_stream_info.dart +++ b/lib/src/videos/streams/muxed_stream_info.dart @@ -1,4 +1,6 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:http_parser/http_parser.dart'; +import 'package:youtube_explode_dart/src/videos/streams/stream_info.dart'; import '../../reverse_engineering/models/fragment.dart'; import 'audio_stream_info.dart'; @@ -10,8 +12,11 @@ import 'video_quality.dart'; import 'video_resolution.dart'; import 'video_stream_info.dart'; +part 'muxed_stream_info.g.dart'; + /// YouTube media stream that contains both audio and video. -class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo { +@JsonSerializable() +class MuxedStreamInfo with StreamInfo, AudioStreamInfo, VideoStreamInfo { @override final int tag; @@ -36,7 +41,7 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo { /// Video quality label, as seen on YouTube. @Deprecated('Use qualityLabel') @override - final String videoQualityLabel; + String get videoQualityLabel => qualityLabel; /// Video quality. @override @@ -56,6 +61,7 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo { /// Stream codec. @override + @JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson) final MediaType codec; /// Stream codec. @@ -64,20 +70,25 @@ class MuxedStreamInfo implements AudioStreamInfo, VideoStreamInfo { /// Initializes an instance of [MuxedStreamInfo] MuxedStreamInfo( - this.tag, - this.url, - this.container, - this.size, - this.bitrate, - this.audioCodec, - this.videoCodec, - @Deprecated('Use qualityLabel') this.videoQualityLabel, - this.videoQuality, - this.videoResolution, - this.framerate, - this.codec, - this.qualityLabel); + this.tag, + this.url, + this.container, + this.size, + this.bitrate, + this.audioCodec, + this.videoCodec, + this.qualityLabel, + this.videoQuality, + this.videoResolution, + this.framerate, + this.codec, + ); @override String toString() => 'Muxed ($tag | $qualityLabel | $container)'; -} + + factory MuxedStreamInfo.fromJson(Map json) => + _$MuxedStreamInfoFromJson(json); + + Map toJson() => _$MuxedStreamInfoToJson(this); +} \ No newline at end of file diff --git a/lib/src/videos/streams/muxed_stream_info.g.dart b/lib/src/videos/streams/muxed_stream_info.g.dart new file mode 100644 index 0000000..cb09388 --- /dev/null +++ b/lib/src/videos/streams/muxed_stream_info.g.dart @@ -0,0 +1,54 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'muxed_stream_info.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MuxedStreamInfo _$MuxedStreamInfoFromJson(Map json) => + MuxedStreamInfo( + json['tag'] as int, + Uri.parse(json['url'] as String), + StreamContainer.fromJson(json['container'] as Map), + FileSize.fromJson(json['size'] as Map), + Bitrate.fromJson(json['bitrate'] as Map), + json['audioCodec'] as String, + json['videoCodec'] as String, + json['qualityLabel'] as String, + $enumDecode(_$VideoQualityEnumMap, json['videoQuality']), + VideoResolution.fromJson(json['videoResolution'] as Map), + Framerate.fromJson(json['framerate'] as Map), + mediaTypeFromJson(json['codec'] as String), + ); + +Map _$MuxedStreamInfoToJson(MuxedStreamInfo instance) => + { + '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', +}; diff --git a/lib/src/videos/streams/stream_container.dart b/lib/src/videos/streams/stream_container.dart index 311454e..516a842 100644 --- a/lib/src/videos/streams/stream_container.dart +++ b/lib/src/videos/streams/stream_container.dart @@ -1,6 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'stream_container.freezed.dart'; +part 'stream_container.g.dart'; /// Stream container. @freezed @@ -12,6 +13,9 @@ class StreamContainer with _$StreamContainer { /// Can be used as file extension String name) = _StreamContainer; + factory StreamContainer.fromJson(Map json) => + StreamContainer.parse(json['name'] as String); + const StreamContainer._(); /// MPEG-4 Part 14 (.mp4). diff --git a/lib/src/videos/streams/stream_container.freezed.dart b/lib/src/videos/streams/stream_container.freezed.dart index e87bf76..d572803 100644 --- a/lib/src/videos/streams/stream_container.freezed.dart +++ b/lib/src/videos/streams/stream_container.freezed.dart @@ -13,6 +13,10 @@ T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); +StreamContainer _$StreamContainerFromJson(Map json) { + return _StreamContainer.fromJson(json); +} + /// @nodoc class _$StreamContainerTearOff { const _$StreamContainerTearOff(); @@ -22,6 +26,10 @@ class _$StreamContainerTearOff { name, ); } + + StreamContainer fromJson(Map json) { + return StreamContainer.fromJson(json); + } } /// @nodoc @@ -33,6 +41,7 @@ mixin _$StreamContainer { /// Can be used as file extension String get name => throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) $StreamContainerCopyWith get copyWith => throw _privateConstructorUsedError; @@ -103,10 +112,13 @@ class __$StreamContainerCopyWithImpl<$Res> } /// @nodoc - +@JsonSerializable() class _$_StreamContainer extends _StreamContainer { const _$_StreamContainer(this.name) : super._(); + factory _$_StreamContainer.fromJson(Map json) => + _$$_StreamContainerFromJson(json); + @override /// Container name. @@ -116,30 +128,37 @@ class _$_StreamContainer extends _StreamContainer { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _StreamContainer && - (identical(other.name, name) || - const DeepCollectionEquality().equals(other.name, name))); + (other.runtimeType == runtimeType && + other is _StreamContainer && + (identical(other.name, name) || other.name == name)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(name); + int get hashCode => Object.hash(runtimeType, name); @JsonKey(ignore: true) @override _$StreamContainerCopyWith<_StreamContainer> get copyWith => __$StreamContainerCopyWithImpl<_StreamContainer>(this, _$identity); + + @override + Map toJson() { + return _$$_StreamContainerToJson(this); + } } abstract class _StreamContainer extends StreamContainer { const factory _StreamContainer(String name) = _$_StreamContainer; const _StreamContainer._() : super._(); + factory _StreamContainer.fromJson(Map json) = + _$_StreamContainer.fromJson; + @override /// Container name. /// Can be used as file extension - String get name => throw _privateConstructorUsedError; + String get name; @override @JsonKey(ignore: true) _$StreamContainerCopyWith<_StreamContainer> get copyWith => diff --git a/lib/src/videos/streams/stream_container.g.dart b/lib/src/videos/streams/stream_container.g.dart new file mode 100644 index 0000000..e1688d5 --- /dev/null +++ b/lib/src/videos/streams/stream_container.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stream_container.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_StreamContainer _$$_StreamContainerFromJson(Map json) => + _$_StreamContainer( + json['name'] as String, + ); + +Map _$$_StreamContainerToJson(_$_StreamContainer instance) => + { + 'name': instance.name, + }; diff --git a/lib/src/videos/streams/stream_info.dart b/lib/src/videos/streams/stream_info.dart index f42dc1c..db43368 100644 --- a/lib/src/videos/streams/stream_info.dart +++ b/lib/src/videos/streams/stream_info.dart @@ -2,40 +2,36 @@ import 'package:http_parser/http_parser.dart'; import '../../reverse_engineering/models/fragment.dart'; import '../videos.dart'; -import 'bitrate.dart'; -import 'filesize.dart'; -import 'stream_container.dart'; /// Generic YouTube media stream. -abstract class StreamInfo { +mixin StreamInfo { /// Stream tag. /// Uniquely identifies a stream inside a manifest. - final int tag; + int get tag; /// Stream URL. - final Uri url; + Uri get url; /// Stream container. - final StreamContainer container; + StreamContainer get container; /// Stream size. - final FileSize size; + FileSize get size; /// Stream bitrate. - final Bitrate bitrate; + Bitrate get bitrate; /// DASH streams contain multiple stream fragments. - final List fragments; + List get fragments; /// Streams codec. - final MediaType codec; + MediaType get codec; /// Stream quality label. - final String qualityLabel; + String get qualityLabel; - /// Initialize an instance of [StreamInfo]. - StreamInfo(this.tag, this.url, this.container, this.size, this.bitrate, - this.fragments, this.codec, this.qualityLabel); + /// Convert to a json-serialized type. + Map toJson(); } /// Extension for Iterables of StreamInfo. @@ -102,3 +98,7 @@ class _Column { return buffer.toString(); } } + +String mediaTypeTojson(MediaType value) => value.toString(); +MediaType mediaTypeFromJson(String value) => MediaType.parse(value); + diff --git a/lib/src/videos/streams/streams.dart b/lib/src/videos/streams/streams.dart index 235f95b..9565289 100644 --- a/lib/src/videos/streams/streams.dart +++ b/lib/src/videos/streams/streams.dart @@ -6,7 +6,7 @@ export 'framerate.dart'; export 'muxed_stream_info.dart'; export 'stream_container.dart'; export 'stream_context.dart'; -export 'stream_info.dart'; +export 'stream_info.dart' hide mediaTypeFromJson, mediaTypeTojson; export 'stream_manifest.dart'; export 'streams_client.dart'; export 'video_only_stream_info.dart'; diff --git a/lib/src/videos/streams/streams_client.dart b/lib/src/videos/streams/streams_client.dart index da73e21..d1a35d0 100644 --- a/lib/src/videos/streams/streams_client.dart +++ b/lib/src/videos/streams/streams_client.dart @@ -127,9 +127,7 @@ class StreamsClient { // Muxed or Video-only if (!videoCodec.isNullOrWhiteSpace) { var framerate = Framerate(streamInfo.framerate ?? 24); - var videoQualityLabel = streamInfo.qualityLabel; - - var videoQuality = VideoQualityUtil.fromLabel(videoQualityLabel); + var videoQuality = VideoQualityUtil.fromLabel(streamInfo.qualityLabel); var videoWidth = streamInfo.videoWidth; var videoHeight = streamInfo.videoHeight; @@ -141,19 +139,19 @@ class StreamsClient { if (!audioCodec.isNullOrWhiteSpace && streamInfo.source != StreamSource.adaptive) { streams[tag] = MuxedStreamInfo( - tag, - url, - container, - fileSize, - bitrate, - audioCodec!, - videoCodec!, - videoQualityLabel, - videoQuality, - videoResolution, - framerate, - streamInfo.codec, - streamInfo.qualityLabel); + tag, + url, + container, + fileSize, + bitrate, + audioCodec!, + videoCodec!, + streamInfo.qualityLabel, + videoQuality, + videoResolution, + framerate, + streamInfo.codec, + ); continue; } @@ -165,13 +163,12 @@ class StreamsClient { fileSize, bitrate, videoCodec!, - videoQualityLabel, + streamInfo.qualityLabel, videoQuality, videoResolution, framerate, streamInfo.fragments ?? const [], - streamInfo.codec, - streamInfo.qualityLabel); + streamInfo.codec); continue; } // Audio-only @@ -183,9 +180,9 @@ class StreamsClient { fileSize, bitrate, audioCodec!, + streamInfo.qualityLabel, streamInfo.fragments ?? const [], - streamInfo.codec, - streamInfo.qualityLabel); + streamInfo.codec); } // #if DEBUG diff --git a/lib/src/videos/streams/video_only_stream_info.dart b/lib/src/videos/streams/video_only_stream_info.dart index 5fe3e11..03b725a 100644 --- a/lib/src/videos/streams/video_only_stream_info.dart +++ b/lib/src/videos/streams/video_only_stream_info.dart @@ -1,45 +1,83 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:http_parser/http_parser.dart'; +import '../../../youtube_explode_dart.dart'; import '../../reverse_engineering/models/fragment.dart'; import 'bitrate.dart'; import 'filesize.dart'; import 'framerate.dart'; import 'stream_container.dart'; +import 'stream_info.dart'; import 'video_quality.dart'; import 'video_resolution.dart'; import 'video_stream_info.dart'; +part 'video_only_stream_info.g.dart'; + /// YouTube media stream that only contains video. -class VideoOnlyStreamInfo extends VideoStreamInfo { +@JsonSerializable() +class VideoOnlyStreamInfo with StreamInfo, VideoStreamInfo { + @override + final int tag; + + @override + final Uri url; + + @override + final StreamContainer container; + + @override + final FileSize size; + + @override + final Bitrate bitrate; + + @override + final String videoCodec; + + @override + final String qualityLabel; + + @override + String get videoQualityLabel => qualityLabel; + + @override + final VideoQuality videoQuality; + + @override + final VideoResolution videoResolution; + + @override + final Framerate framerate; + + @override + final List fragments; + + @override + @JsonKey(toJson: mediaTypeTojson, fromJson: mediaTypeFromJson) + final MediaType codec; + VideoOnlyStreamInfo( - int tag, - Uri url, - StreamContainer container, - FileSize size, - Bitrate bitrate, - String videoCodec, - String videoQualityLabel, - VideoQuality videoQuality, - VideoResolution videoResolution, - Framerate framerate, - List fragments, - MediaType codec, - String qualityLabel) - : super( - tag, - url, - container, - size, - bitrate, - videoCodec, - videoQualityLabel, - videoQuality, - videoResolution, - framerate, - fragments, - codec, - qualityLabel); + this.tag, + this.url, + this.container, + this.size, + this.bitrate, + this.videoCodec, + this.qualityLabel, + this.videoQuality, + this.videoResolution, + this.framerate, + this.fragments, + this.codec); @override String toString() => 'Video-only ($tag | $videoResolution | $container)'; + + factory VideoOnlyStreamInfo.fromJson(Map json) => + _$VideoOnlyStreamInfoFromJson(json); + + Map toJson() => _$VideoOnlyStreamInfoToJson(this); + + } diff --git a/lib/src/videos/streams/video_only_stream_info.g.dart b/lib/src/videos/streams/video_only_stream_info.g.dart new file mode 100644 index 0000000..b98bc2e --- /dev/null +++ b/lib/src/videos/streams/video_only_stream_info.g.dart @@ -0,0 +1,57 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'video_only_stream_info.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +VideoOnlyStreamInfo _$VideoOnlyStreamInfoFromJson(Map json) => + VideoOnlyStreamInfo( + json['tag'] as int, + Uri.parse(json['url'] as String), + StreamContainer.fromJson(json['container'] as Map), + FileSize.fromJson(json['size'] as Map), + Bitrate.fromJson(json['bitrate'] as Map), + json['videoCodec'] as String, + json['qualityLabel'] as String, + $enumDecode(_$VideoQualityEnumMap, json['videoQuality']), + VideoResolution.fromJson(json['videoResolution'] as Map), + Framerate.fromJson(json['framerate'] as Map), + (json['fragments'] as List) + .map((e) => Fragment.fromJson(e as Map)) + .toList(), + mediaTypeFromJson(json['codec'] as String), + ); + +Map _$VideoOnlyStreamInfoToJson( + VideoOnlyStreamInfo instance) => + { + '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', +}; diff --git a/lib/src/videos/streams/video_resolution.dart b/lib/src/videos/streams/video_resolution.dart index b5a968f..e0898ca 100644 --- a/lib/src/videos/streams/video_resolution.dart +++ b/lib/src/videos/streams/video_resolution.dart @@ -1,4 +1,9 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'video_resolution.g.dart'; + /// Width and height of a video. +@JsonSerializable() class VideoResolution implements Comparable { /// Viewport width. final int width; @@ -9,6 +14,11 @@ class VideoResolution implements Comparable { /// Initializes an instance of [VideoResolution] const VideoResolution(this.width, this.height); + factory VideoResolution.fromJson(Map json) => + _$VideoResolutionFromJson(json); + + Map toJson() => _$VideoResolutionToJson(this); + @override String toString() => '${width}x$height'; diff --git a/lib/src/videos/streams/video_resolution.g.dart b/lib/src/videos/streams/video_resolution.g.dart new file mode 100644 index 0000000..d1f48f8 --- /dev/null +++ b/lib/src/videos/streams/video_resolution.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'video_resolution.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +VideoResolution _$VideoResolutionFromJson(Map json) => + VideoResolution( + json['width'] as int, + json['height'] as int, + ); + +Map _$VideoResolutionToJson(VideoResolution instance) => + { + 'width': instance.width, + 'height': instance.height, + }; diff --git a/lib/src/videos/streams/video_stream_info.dart b/lib/src/videos/streams/video_stream_info.dart index 4638a1f..828b96a 100644 --- a/lib/src/videos/streams/video_stream_info.dart +++ b/lib/src/videos/streams/video_stream_info.dart @@ -1,43 +1,22 @@ -import 'package:http_parser/http_parser.dart'; - -import '../../reverse_engineering/models/fragment.dart'; import 'streams.dart'; /// YouTube media stream that contains video. -abstract class VideoStreamInfo extends StreamInfo { +mixin VideoStreamInfo on StreamInfo { /// Video codec. - final String videoCodec; + String get videoCodec; /// Video quality label, as seen on YouTube. @Deprecated('Use qualityLabel') - final String videoQualityLabel; + String get videoQualityLabel; /// Video quality. - final VideoQuality videoQuality; + VideoQuality get videoQuality; /// Video resolution. - final VideoResolution videoResolution; + VideoResolution get videoResolution; /// Video framerate. - final Framerate framerate; - - /// - VideoStreamInfo( - int tag, - Uri url, - StreamContainer container, - FileSize size, - Bitrate bitrate, - this.videoCodec, - @Deprecated('Use qualityLabel') this.videoQualityLabel, - this.videoQuality, - this.videoResolution, - this.framerate, - List fragments, - MediaType codec, - String qualityLabel) - : super( - tag, url, container, size, bitrate, fragments, codec, qualityLabel); + Framerate get framerate; } /// Extensions for Iterables of [VideoStreamInfo] diff --git a/lib/src/videos/video.freezed.dart b/lib/src/videos/video.freezed.dart index eca3eb7..306f8c2 100644 --- a/lib/src/videos/video.freezed.dart +++ b/lib/src/videos/video.freezed.dart @@ -434,60 +434,48 @@ class _$_Video extends _Video { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _Video && - (identical(other.id, id) || - const DeepCollectionEquality().equals(other.id, id)) && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.author, author) || - const DeepCollectionEquality().equals(other.author, author)) && + (other.runtimeType == runtimeType && + other is _Video && + (identical(other.id, id) || other.id == id) && + (identical(other.title, title) || other.title == title) && + (identical(other.author, author) || other.author == author) && (identical(other.channelId, channelId) || - const DeepCollectionEquality() - .equals(other.channelId, channelId)) && + other.channelId == channelId) && (identical(other.uploadDate, uploadDate) || - const DeepCollectionEquality() - .equals(other.uploadDate, uploadDate)) && + other.uploadDate == uploadDate) && (identical(other.publishDate, publishDate) || - const DeepCollectionEquality() - .equals(other.publishDate, publishDate)) && + other.publishDate == publishDate) && (identical(other.description, description) || - const DeepCollectionEquality() - .equals(other.description, description)) && + other.description == description) && (identical(other.duration, duration) || - const DeepCollectionEquality() - .equals(other.duration, duration)) && + other.duration == duration) && (identical(other.thumbnails, thumbnails) || - const DeepCollectionEquality() - .equals(other.thumbnails, thumbnails)) && + other.thumbnails == thumbnails) && (identical(other.keywords, keywords) || - const DeepCollectionEquality() - .equals(other.keywords, keywords)) && + other.keywords == keywords) && (identical(other.engagement, engagement) || - const DeepCollectionEquality() - .equals(other.engagement, engagement)) && - (identical(other.isLive, isLive) || - const DeepCollectionEquality().equals(other.isLive, isLive)) && + other.engagement == engagement) && + (identical(other.isLive, isLive) || other.isLive == isLive) && (identical(other.watchPage, watchPage) || - const DeepCollectionEquality() - .equals(other.watchPage, watchPage))); + other.watchPage == watchPage)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(id) ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(author) ^ - const DeepCollectionEquality().hash(channelId) ^ - const DeepCollectionEquality().hash(uploadDate) ^ - const DeepCollectionEquality().hash(publishDate) ^ - const DeepCollectionEquality().hash(description) ^ - const DeepCollectionEquality().hash(duration) ^ - const DeepCollectionEquality().hash(thumbnails) ^ - const DeepCollectionEquality().hash(keywords) ^ - const DeepCollectionEquality().hash(engagement) ^ - const DeepCollectionEquality().hash(isLive) ^ - const DeepCollectionEquality().hash(watchPage); + int get hashCode => Object.hash( + runtimeType, + id, + title, + author, + channelId, + uploadDate, + publishDate, + description, + duration, + thumbnails, + keywords, + engagement, + isLive, + watchPage); @JsonKey(ignore: true) @override @@ -515,61 +503,60 @@ abstract class _Video extends Video { @override /// Video ID. - VideoId get id => throw _privateConstructorUsedError; + VideoId get id; @override /// Video title. - String get title => throw _privateConstructorUsedError; + String get title; @override /// Video author. - String get author => throw _privateConstructorUsedError; + String get author; @override /// Video author Id. - ChannelId get channelId => throw _privateConstructorUsedError; + ChannelId get channelId; @override /// Video upload date. /// Note: For search queries it is calculated with: /// DateTime.now() - how much time is was published. - DateTime? get uploadDate => throw _privateConstructorUsedError; + DateTime? get uploadDate; @override /// Video publish date. - DateTime? get publishDate => throw _privateConstructorUsedError; + DateTime? get publishDate; @override /// Video description. - String get description => throw _privateConstructorUsedError; + String get description; @override /// Duration of the video. - Duration? get duration => throw _privateConstructorUsedError; + Duration? get duration; @override /// Available thumbnails for this video. - ThumbnailSet get thumbnails => throw _privateConstructorUsedError; + ThumbnailSet get thumbnails; @override /// Search keywords used for this video. - UnmodifiableListView get keywords => - throw _privateConstructorUsedError; + UnmodifiableListView get keywords; @override /// Engagement statistics for this video. - Engagement get engagement => throw _privateConstructorUsedError; + Engagement get engagement; @override /// Returns true if this is a live stream. //ignore: avoid_positional_boolean_parameters - bool get isLive => throw _privateConstructorUsedError; + bool get isLive; @override /// Used internally. /// Shouldn't be used in the code. @internal - WatchPage? get watchPage => throw _privateConstructorUsedError; + WatchPage? get watchPage; @override @JsonKey(ignore: true) _$VideoCopyWith<_Video> get copyWith => throw _privateConstructorUsedError; diff --git a/lib/src/videos/video_id.dart b/lib/src/videos/video_id.dart index 5a7ba34..041bfa7 100644 --- a/lib/src/videos/video_id.dart +++ b/lib/src/videos/video_id.dart @@ -85,7 +85,7 @@ class VideoId with _$VideoId { return embedMatch; } - // https://www.youtube.com/shorts/yIVRs6YSbOM + // https://www.youtube.com/shorts/yIVRs6YSbOM var shortsMatch = _shortsMatchExp.firstMatch(url)?.group(1); if (!shortsMatch.isNullOrWhiteSpace && validateVideoId(shortsMatch!)) { return shortsMatch; diff --git a/lib/src/videos/video_id.freezed.dart b/lib/src/videos/video_id.freezed.dart index 8d0b7a6..4bccb73 100644 --- a/lib/src/videos/video_id.freezed.dart +++ b/lib/src/videos/video_id.freezed.dart @@ -107,14 +107,13 @@ class _$_VideoId extends _VideoId { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _VideoId && - (identical(other.value, value) || - const DeepCollectionEquality().equals(other.value, value))); + (other.runtimeType == runtimeType && + other is _VideoId && + (identical(other.value, value) || other.value == value)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(value); + int get hashCode => Object.hash(runtimeType, value); @JsonKey(ignore: true) @override @@ -129,7 +128,7 @@ abstract class _VideoId extends VideoId { @override /// ID as string. - String get value => throw _privateConstructorUsedError; + String get value; @override @JsonKey(ignore: true) _$VideoIdCopyWith<_VideoId> get copyWith => diff --git a/pubspec.yaml b/pubspec.yaml index 9fbc72c..8cd2790 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,23 +5,23 @@ version: 1.10.8 homepage: https://github.com/Hexer10/youtube_explode_dart environment: - sdk: '>=2.13.0 <3.0.0' + sdk: '>=2.14.0 <3.0.0' dependencies: collection: ^1.15.0 - freezed_annotation: ^0.14.3 + freezed_annotation: ^0.15.0 html: ^0.15.0 http: ^0.13.0 http_parser: ^4.0.0 - json_annotation: ^4.0.0 + json_annotation: ^4.3.0 meta: ^1.3.0 xml: ^5.0.2 dev_dependencies: build_runner: ^2.1.4 console: ^4.1.0 - freezed: ^0.14.5 + freezed: ^0.15.1+1 grinder: ^0.9.0 - json_serializable: ^5.0.2 + json_serializable: ^6.0.1 lint: ^1.7.2 test: ^1.18.2