Skip to content

Commit

Permalink
feat: use local track as a fallback youtube audio cache
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Feb 19, 2024
1 parent a6a3ebd commit a669ad4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 11 deletions.
31 changes: 26 additions & 5 deletions lib/base/audio_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,8 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
disableVideo: isAudioOnlyPlayback,
whatToAwait: () async => await playerStoppingSeikoo.future,
startPlaying: startPlaying,
possibleAudioFiles: audioCacheMap[item.id] ?? [],
possibleLocalFiles: Indexer.inst.allTracksMappedByYTID[item.id] ?? [],
);
if (item != currentVideo) return;

Expand Down Expand Up @@ -923,6 +925,8 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
disableVideo: isAudioOnlyPlayback,
whatToAwait: () async => await playerStoppingSeikoo.future,
startPlaying: startPlaying,
possibleAudioFiles: audioCacheMap[item.id] ?? [],
possibleLocalFiles: Indexer.inst.allTracksMappedByYTID[item.id] ?? [],
);
if (!okaySetFromCache()) {
showSnackError('skipping');
Expand Down Expand Up @@ -962,6 +966,8 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
required bool disableVideo,
required Future<void> Function() whatToAwait,
required bool startPlaying,
required List<AudioCacheDetails> possibleAudioFiles,
required List<Track> possibleLocalFiles,
}) async {
// ------ Getting Video ------
final allCachedVideos = VideoController.inst.getNVFromID(item.id);
Expand All @@ -980,12 +986,27 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
final mediaItem = item.toMediaItem(currentVideoInfo.value, currentVideoThumbnail.value, index, currentQueue.length);

// ------ Getting Audio ------
final audioFiles = await _getCachedAudiosForID.thready({
"dirPath": AppDirs.AUDIOS_CACHE,
"id": item.id,
});
final audioFiles = possibleAudioFiles.isNotEmpty
? possibleAudioFiles
: await _getCachedAudiosForID.thready({
"dirPath": AppDirs.AUDIOS_CACHE,
"id": item.id,
});
final finalAudioFiles = audioFiles..sortByReverseAlt((e) => e.bitrate ?? 0, (e) => e.file.fileSizeSync() ?? 0);
final cachedAudio = finalAudioFiles.firstOrNull;
AudioCacheDetails? cachedAudio = finalAudioFiles.firstOrNull;

if (cachedAudio == null) {
final localTrack = possibleLocalFiles.firstOrNull;
if (localTrack != null) {
cachedAudio = AudioCacheDetails(
youtubeId: item.id,
bitrate: localTrack.bitrate,
langaugeCode: null,
langaugeName: null,
file: File(localTrack.path),
);
}
}

// ------ Playing ------
if (cachedVideo != null && cachedAudio != null && !disableVideo) {
Expand Down
18 changes: 14 additions & 4 deletions lib/controller/indexer_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Indexer {
final trackStatsMap = <Track, TrackStats>{}.obs;

var allFolderCovers = <String, String>{}; // {directoryPath, imagePath}
var allTracksMappedByYTID = <String, List<Track>>{};

/// Used to prevent duplicated track (by filename).
final Map<String, bool> _currentFileNamesMap = {};
Expand Down Expand Up @@ -667,6 +668,7 @@ class Indexer {
for (final trext in tracks) {
final tr = trext.toTrack();
allTracksMappedByPath[tr] = trext;
allTracksMappedByYTID.addForce(trext.youtubeID, tr);
_currentFileNamesMap[trext.path.getFilename] = true;
if (checkForDuplicates) {
tracksInfoList.addNoDuplicates(tr);
Expand Down Expand Up @@ -876,6 +878,7 @@ class Indexer {
oldTracks.add(ot);
newTracks.add(nt);
allTracksMappedByPath[ot] = e.value;
allTracksMappedByYTID.addForce(e.value.youtubeID, ot);
_currentFileNamesMap.remove(ot.filename);
_currentFileNamesMap[nt.filename] = true;

Expand Down Expand Up @@ -923,6 +926,7 @@ class Indexer {
void _clearLists() {
tracksInfoList.clear();
allTracksMappedByPath.clear();
allTracksMappedByYTID.clear();
SearchSortController.inst.sortMedia(MediaType.track);
}

Expand Down Expand Up @@ -965,6 +969,7 @@ class Indexer {
final trs = await _fetchMediaStoreTracks();
tracksInfoList.clear();
allTracksMappedByPath.clear();
allTracksMappedByYTID.clear();
_currentFileNamesMap.clear();
_addTracksToLists(trs.map((e) => e.$1), false);
} else {
Expand Down Expand Up @@ -1077,8 +1082,9 @@ class Indexer {
genresConfig: GenresSplitConfig.settings(),
);
final tracksResult = await _readTracksFileCompute.thready(splitconfig);
allTracksMappedByPath.value = tracksResult;
tracksInfoList.addAll(tracksResult.keys);
allTracksMappedByPath.value = tracksResult.$1;
allTracksMappedByYTID = tracksResult.$2;
tracksInfoList.value = tracksResult.$3;

printy("All Tracks Length From File: ${tracksInfoList.length}");
}
Expand All @@ -1100,8 +1106,10 @@ class Indexer {
return map;
}

static Future<Map<Track, TrackExtended>> _readTracksFileCompute(_SplitArtistGenreConfig config) async {
static (Map<Track, TrackExtended>, Map<String, List<Track>>, List<Track>) _readTracksFileCompute(_SplitArtistGenreConfig config) {
final map = <Track, TrackExtended>{};
final idsMap = <String, List<Track>>{};
final allTracks = <Track>[];
final list = File(config.path).readAsJsonSync() as List?;
if (list != null) {
for (int i = 0; i <= list.length - 1; i++) {
Expand All @@ -1114,12 +1122,14 @@ class Indexer {
);
final track = trExt.toTrack();
map[track] = trExt;
allTracks.add(track);
idsMap.addForce(trExt.youtubeID, track);
} catch (e) {
continue;
}
}
}
return map;
return (map, idsMap, allTracks);
}

static List<String> splitBySeparators(String? string, Iterable<String> separators, String fallback, Iterable<String> blacklist) {
Expand Down
9 changes: 7 additions & 2 deletions lib/youtube/yt_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:playlist_manager/module/playlist_id.dart';
import 'package:share_plus/share_plus.dart';

import 'package:namida/class/video.dart';
import 'package:namida/controller/indexer_controller.dart';
import 'package:namida/controller/ffmpeg_controller.dart';
import 'package:namida/controller/miniplayer_controller.dart';
import 'package:namida/controller/navigator_controller.dart';
Expand Down Expand Up @@ -81,7 +82,9 @@ class YTUtils {
child: Icon(
Broken.video,
size: 15.0,
color: iconsColor?.withOpacity(VideoController.inst.getNVFromID(videoId).isNotEmpty ? 0.6 : 0.1),
color: iconsColor?.withOpacity(
VideoController.inst.getNVFromID(videoId).isNotEmpty ? 0.6 : 0.1,
),
),
),
const SizedBox(width: 4.0),
Expand All @@ -90,7 +93,9 @@ class YTUtils {
child: Icon(
Broken.audio_square,
size: 15.0,
color: iconsColor?.withOpacity(Player.inst.audioCacheMap[videoId] != null ? 0.6 : 0.1),
color: iconsColor?.withOpacity(
Player.inst.audioCacheMap[videoId] != null || Indexer.inst.allTracksMappedByYTID[videoId] != null ? 0.6 : 0.1,
),
),
),
],
Expand Down

0 comments on commit a669ad4

Please sign in to comment.