chore: remove unnecessary files and youtube_explode

This commit is contained in:
Kingkor Roy Tirtho 2023-05-14 15:00:07 +06:00
parent 962d9118dd
commit 5a4e3baa51
6 changed files with 5 additions and 445 deletions

View File

@ -1,101 +0,0 @@
import 'package:hive/hive.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
part 'cache_track.g.dart';
@HiveType(typeId: 2)
class CacheTrackEngagement {
@HiveField(0)
late int viewCount;
@HiveField(1)
late int? likeCount;
@HiveField(2)
late int? dislikeCount;
CacheTrackEngagement();
CacheTrackEngagement.fromEngagement(Engagement engagement)
: viewCount = engagement.viewCount,
likeCount = engagement.likeCount,
dislikeCount = engagement.dislikeCount;
}
@HiveType(typeId: 3)
class CacheTrackSkipSegment {
@HiveField(0)
late int start;
@HiveField(1)
late int end;
CacheTrackSkipSegment();
CacheTrackSkipSegment.fromJson(Map map)
: start = map["start"].toInt(),
end = map["end"].toInt();
Map<String, int> toJson() {
return Map.castFrom<String, dynamic, String, int>(
{"start": start, "end": end});
}
}
@HiveType(typeId: 1)
class CacheTrack extends HiveObject {
@HiveField(0)
late String id;
@HiveField(1)
late String title;
@HiveField(2)
late String channelId;
@HiveField(3)
late String? uploadDate;
@HiveField(4)
late String? publishDate;
@HiveField(5)
late String description;
@HiveField(6)
late String? duration;
@HiveField(7)
late List<String>? keywords;
@HiveField(8)
late CacheTrackEngagement engagement;
@HiveField(9)
late String mode;
@HiveField(10)
late String author;
@HiveField(11)
late List<CacheTrackSkipSegment>? skipSegments;
CacheTrack();
CacheTrack.fromVideo(
Video video,
this.mode, {
required List<Map<String, int>> skipSegments,
}) : id = video.id.value,
title = video.title,
author = video.author,
channelId = video.channelId.value,
uploadDate = video.uploadDate.toString(),
publishDate = video.publishDate.toString(),
description = video.description,
duration = video.duration.toString(),
keywords = video.keywords,
engagement = CacheTrackEngagement.fromEngagement(video.engagement),
skipSegments = skipSegments
.map((segment) => CacheTrackSkipSegment.fromJson(segment))
.toList();
}

View File

@ -1,148 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'cache_track.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class CacheTrackEngagementAdapter extends TypeAdapter<CacheTrackEngagement> {
@override
final int typeId = 2;
@override
CacheTrackEngagement read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return CacheTrackEngagement()
..viewCount = fields[0] as int
..likeCount = fields[1] as int?
..dislikeCount = fields[2] as int?;
}
@override
void write(BinaryWriter writer, CacheTrackEngagement obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.viewCount)
..writeByte(1)
..write(obj.likeCount)
..writeByte(2)
..write(obj.dislikeCount);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CacheTrackEngagementAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class CacheTrackSkipSegmentAdapter extends TypeAdapter<CacheTrackSkipSegment> {
@override
final int typeId = 3;
@override
CacheTrackSkipSegment read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return CacheTrackSkipSegment()
..start = fields[0] as int
..end = fields[1] as int;
}
@override
void write(BinaryWriter writer, CacheTrackSkipSegment obj) {
writer
..writeByte(2)
..writeByte(0)
..write(obj.start)
..writeByte(1)
..write(obj.end);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CacheTrackSkipSegmentAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class CacheTrackAdapter extends TypeAdapter<CacheTrack> {
@override
final int typeId = 1;
@override
CacheTrack read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return CacheTrack()
..id = fields[0] as String
..title = fields[1] as String
..channelId = fields[2] as String
..uploadDate = fields[3] as String?
..publishDate = fields[4] as String?
..description = fields[5] as String
..duration = fields[6] as String?
..keywords = (fields[7] as List?)?.cast<String>()
..engagement = fields[8] as CacheTrackEngagement
..mode = fields[9] as String
..author = fields[10] as String
..skipSegments = (fields[11] as List?)?.cast<CacheTrackSkipSegment>();
}
@override
void write(BinaryWriter writer, CacheTrack obj) {
writer
..writeByte(12)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.title)
..writeByte(2)
..write(obj.channelId)
..writeByte(3)
..write(obj.uploadDate)
..writeByte(4)
..write(obj.publishDate)
..writeByte(5)
..write(obj.description)
..writeByte(6)
..write(obj.duration)
..writeByte(7)
..write(obj.keywords)
..writeByte(8)
..write(obj.engagement)
..writeByte(9)
..write(obj.mode)
..writeByte(10)
..write(obj.author)
..writeByte(11)
..write(obj.skipSegments);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CacheTrackAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@ -1,37 +1,6 @@
import 'dart:convert';
import 'package:catcher/catcher.dart';
import 'package:http/http.dart';
import 'package:piped_client/piped_client.dart';
import 'package:spotube/entities/cache_track.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/models/track.dart';
import 'package:spotube/provider/user_preferences_provider.dart';
import 'package:spotube/services/youtube.dart';
import 'package:spotube/utils/duration.dart';
extension PipedSearchItemExtension on PipedSearchItem {
static PipedSearchItemStream fromCacheTrack(CacheTrack cacheTrack) {
return PipedSearchItemStream(
type: PipedSearchItemType.stream,
url: "watch?v=${cacheTrack.id}",
title: cacheTrack.title,
uploaderName: cacheTrack.author,
uploaderUrl: "/channel/${cacheTrack.channelId}",
uploaded: -1,
uploadedDate: cacheTrack.uploadDate ?? "",
shortDescription: cacheTrack.description,
isShort: false,
thumbnail: "",
duration: cacheTrack.duration != null
? tryParseDuration(cacheTrack.duration!) ?? Duration.zero
: Duration.zero,
uploaderAvatar: "",
uploaderVerified: false,
views: cacheTrack.engagement.viewCount,
);
}
}
extension PipedStreamResponseExtension on PipedStreamResponse {
static Future<PipedStreamResponse> fromBackendTrack(

View File

@ -1,159 +0,0 @@
import 'dart:convert';
import 'package:catcher/catcher.dart';
import 'package:http/http.dart';
import 'package:spotube/entities/cache_track.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/models/track.dart';
import 'package:spotube/provider/user_preferences_provider.dart';
import 'package:spotube/utils/duration.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
extension VideoFromCacheTrackExtension on Video {
static Video fromCacheTrack(CacheTrack cacheTrack) {
return Video(
VideoId.fromString(cacheTrack.id),
cacheTrack.title,
cacheTrack.author,
ChannelId.fromString(cacheTrack.channelId),
cacheTrack.uploadDate != null
? DateTime.tryParse(cacheTrack.uploadDate!)
: null,
cacheTrack.uploadDate,
cacheTrack.publishDate != null
? DateTime.tryParse(cacheTrack.publishDate!)
: null,
cacheTrack.description,
cacheTrack.duration != null
? tryParseDuration(cacheTrack.duration!)
: null,
ThumbnailSet(cacheTrack.id),
cacheTrack.keywords,
Engagement(
cacheTrack.engagement.viewCount,
cacheTrack.engagement.likeCount,
cacheTrack.engagement.dislikeCount,
),
false,
);
}
static Future<Video> fromBackendTrack(
BackendTrack track, YoutubeExplode youtube) {
return youtube.videos.get(VideoId.fromString(track.youtubeId));
}
}
extension ThumbnailSetJson on ThumbnailSet {
static ThumbnailSet fromJson(Map<String, dynamic> map) {
return ThumbnailSet(map["videoId"]);
}
Map<String, dynamic> toJson() {
return {
"videoId": videoId,
};
}
}
extension EngagementJson on Engagement {
static Engagement fromJson(Map<String, dynamic> map) {
return Engagement(
map["viewCount"],
map["likeCount"],
map["dislikeCount"],
);
}
Map<String, dynamic> toJson() {
return {
"dislikeCount": dislikeCount,
"likeCount": likeCount,
"viewCount": viewCount,
};
}
}
extension VideoToJson on Video {
static Video fromJson(Map<String, dynamic> map) {
return Video(
VideoId(map["id"]),
map["title"],
map["author"],
ChannelId(map["channelId"]),
DateTime.tryParse(map["uploadDate"]),
map["uploadDate"],
DateTime.tryParse(map["publishDate"]),
map["description"],
parseDuration(map["duration"]),
ThumbnailSetJson.fromJson(map["thumbnails"]),
List.castFrom<dynamic, String>(map["keywords"]),
EngagementJson.fromJson(map["engagement"]),
map["isLive"],
);
}
Map<String, dynamic> toJson() {
return {
"hasWatchPage": hasWatchPage,
"url": url,
"author": author,
"channelId": channelId.value,
"description": description,
"duration": duration.toString(),
"engagement": engagement.toJson(),
"id": id.value,
"isLive": isLive,
"keywords": keywords.toList(),
"publishDate": publishDate.toString(),
"thumbnails": thumbnails.toJson(),
"title": title,
"uploadDate": uploadDate.toString(),
};
}
}
extension GetSkipSegments on Video {
Future<List<Map<String, int>>> getSkipSegments(
UserPreferences preferences) async {
if (!preferences.skipSponsorSegments) return [];
try {
final res = await get(Uri(
scheme: "https",
host: "sponsor.ajay.app",
path: "/api/skipSegments",
queryParameters: {
"videoID": id.value,
"category": [
'sponsor',
'selfpromo',
'interaction',
'intro',
'outro',
'music_offtopic'
],
"actionType": 'skip'
},
));
if (res.body == "Not Found") {
return List.castFrom<dynamic, Map<String, int>>([]);
}
final data = jsonDecode(res.body) as List;
final segments = data.map((obj) {
return Map.castFrom<String, dynamic, String, int>({
"start": obj["segment"].first.toInt(),
"end": obj["segment"].last.toInt(),
});
}).toList();
getLogger(Video).v(
"[SponsorBlock] successfully fetched skip segments for $title | ${id.value}",
);
return List.castFrom<dynamic, Map<String, int>>(segments);
} catch (e, stack) {
Catcher.reportCheckedError(e, stack);
return List.castFrom<dynamic, Map<String, int>>([]);
}
}
}

View File

@ -9,14 +9,12 @@ import 'package:flutter/services.dart';
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:media_kit/media_kit.dart';
import 'package:metadata_god/metadata_god.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/components/shared/dialogs/replace_downloaded_dialog.dart';
import 'package:spotube/entities/cache_track.dart';
import 'package:spotube/collections/routes.dart';
import 'package:spotube/collections/intents.dart';
import 'package:spotube/l10n/l10n.dart';
@ -97,9 +95,6 @@ Future<void> main(List<String> rawArgs) async {
cacheDir: (await getApplicationSupportDirectory()).path,
);
await PersistedStateNotifier.initializeBoxes();
Hive.registerAdapter(CacheTrackAdapter());
Hive.registerAdapter(CacheTrackEngagementAdapter());
Hive.registerAdapter(CacheTrackSkipSegmentAdapter());
Catcher(
enableLogger: arguments["verbose"],

View File

@ -14,12 +14,16 @@ import 'package:spotube/provider/user_preferences_provider.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/services/audio_services/audio_services.dart';
import 'package:spotube/utils/type_conversion_utils.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
/// Things to implement:
/// * [x] Sponsor-Block skip
/// * [x] Prefetch next track as [SpotubeTrack] on 80% of current track
/// * [ ] Mixed Queue containing both [SpotubeTrack] and [LocalTrack]
/// * [ ] Modification of the Queue
/// * [ ] Add track at the end
/// * [ ] Add track at the beginning
/// * [ ] Remove track
/// * [ ] Reorder track
/// * [ ] Caching and loading of cache of tracks
/// * [ ] Shuffling and loop => playlist, track, none
/// * [ ] Alternative Track Source