Skip to content

Commit

Permalink
chore: various tweaks & fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Mar 4, 2024
1 parent 060dcb8 commit 09301ec
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 80 deletions.
22 changes: 8 additions & 14 deletions lib/base/audio_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:io';

import 'package:audio_service/audio_service.dart';
import 'package:basic_audio_handler/basic_audio_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:get/get_utils/src/extensions/num_extensions.dart';
Expand Down Expand Up @@ -184,8 +183,6 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
// ==============================================================================================
// ================================== QueueManager Overriden ====================================

Color? latestExtractedColor;

@override
void onIndexChanged(int newIndex, Q newItem) async {
refreshNotification(newItem);
Expand All @@ -196,16 +193,7 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
},
youtubeID: (finalItem) async {
settings.player.save(lastPlayedIndices: {LibraryCategory.youtube: newIndex});
final image = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: finalItem.id);
if (image != null && finalItem == currentItem) {
// -- only extract if same item is still playing, i.e. user didn't skip.
final color = await CurrentColor.inst.extractPaletteFromImage(image.path, paletteSaveDirectory: Directory(AppDirs.YT_PALETTES), useIsolate: true);
if (color != null && finalItem == currentItem) {
// -- only update if same item is still playing, i.e. user didn't skip.
CurrentColor.inst.updatePlayerColorFromColor(color.color);
latestExtractedColor = color.color;
}
}
await CurrentColor.inst.updatePlayerColorFromYoutubeID(finalItem);
},
);
}
Expand Down Expand Up @@ -485,7 +473,13 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
final initialVideo = await VideoController.inst.updateCurrentVideo(tr, returnEarly: true);

// -- generating artwork in case it wasnt, to be displayed in notification
Indexer.inst.getArtwork(imagePath: tr.pathToImage, compressed: false).then((value) => refreshNotification());
File(tr.pathToImage).exists().then((exists) {
// -- we check if it exists to avoid refreshing notification redundently.
// -- otherwise `getArtwork` already handles duplications.
if (!exists) {
Indexer.inst.getArtwork(imagePath: tr.pathToImage, compressed: false, checkFileFirst: false).then((value) => refreshNotification());
}
});

Future<Duration?> setPls() async {
final dur = await setSource(
Expand Down
71 changes: 55 additions & 16 deletions lib/controller/current_color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';

import 'package:get/get.dart';
import 'package:queue/queue.dart' as qs;
import 'package:palette_generator/palette_generator.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:queue/queue.dart' as qs;

import 'package:namida/class/color_m.dart';
import 'package:namida/class/track.dart';
import 'package:namida/controller/indexer_controller.dart';
import 'package:namida/controller/player_controller.dart';
import 'package:namida/controller/settings_controller.dart';
import 'package:namida/controller/thumbnail_manager.dart';
import 'package:namida/core/constants.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/youtube/class/youtube_id.dart';

Color get playerStaticColor => Get.isDarkMode ? playerStaticColorDark : playerStaticColorLight;
Color get playerStaticColorLight => Color(settings.staticColor.value);
Expand Down Expand Up @@ -55,7 +56,8 @@ class CurrentColor {

final isGeneratingAllColorPalettes = false.obs;

final colorsMap = <String, NamidaColor>{};
final _colorsMap = <String, NamidaColor>{};
final _colorsMapYTID = <String, NamidaColor>{};

Timer? _colorsSwitchTimer;
void switchColorPalettes(bool isPlaying) {
Expand Down Expand Up @@ -140,11 +142,55 @@ class CurrentColor {
}

Future<void> updatePlayerColorFromTrack(Selectable? track, int? index, {bool updateIndexOnly = false}) async {
if (!updateIndexOnly && track != null && (settings.autoColor.value || settings.forceMiniplayerTrackColor.value)) {
if (!updateIndexOnly && track != null) {
await _updatePlayerColorFromItem(
getColorPalette: () async => await getTrackColors(track.track),
stillPlaying: () => track.track == Player.inst.nowPlayingTrack,
);
}
if (track != null) {
currentPlayingTrack.value = null; // nullifying to re-assign safely if subtype has changed
currentPlayingTrack.value = track;
}
if (index != null) {
currentPlayingIndex.value = index;
}
}

Future<void> updatePlayerColorFromYoutubeID(YoutubeID ytIdItem) async {
final id = ytIdItem.id;
if (id == '') return;

// -- only extract if same item is still playing, i.e. user didn't skip.
bool stillPlaying() => ytIdItem.id == Player.inst.nowPlayingVideoID?.id;

await _updatePlayerColorFromItem(
getColorPalette: () async {
if (_colorsMapYTID[id] != null) return _colorsMapYTID[id]!;

final image = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: id);
if (image != null && stillPlaying()) {
final color = await CurrentColor.inst.extractPaletteFromImage(image.path, paletteSaveDirectory: Directory(AppDirs.YT_PALETTES), useIsolate: true);
if (color != null && stillPlaying()) {
_colorsMapYTID[id] = color; // saving in memory
return color;
}
}
return null;
},
stillPlaying: stillPlaying,
);
}

Future<void> _updatePlayerColorFromItem({
required Future<NamidaColor?> Function() getColorPalette,
required bool Function() stillPlaying,
}) async {
if (settings.autoColor.value || settings.forceMiniplayerTrackColor.value) {
NamidaColor? namidaColor;

final trColors = await getTrackColors(track.track);
if (track.track != Player.inst.nowPlayingTrack) return; // -- check current track
final trColors = await getColorPalette();
if (trColors == null || !stillPlaying()) return; // -- check current item
_namidaColorMiniplayer.value = trColors.color;

if (settings.autoColor.value) {
Expand All @@ -161,13 +207,6 @@ class CurrentColor {
}
}
}
if (track != null) {
currentPlayingTrack.value = null; // nullifying to re-assign safely if subtype has changed
currentPlayingTrack.value = track;
}
if (index != null) {
currentPlayingIndex.value = index;
}
}

void resetCurrentPlayingTrack() {
Expand Down Expand Up @@ -205,7 +244,7 @@ class CurrentColor {

final filename = settings.groupArtworksByAlbum.value ? track.albumIdentifier : track.filename;

final valInMap = colorsMap[filename];
final valInMap = _colorsMap[filename];
if (!forceReCheck && valInMap != null) {
return maybeDelightned(valInMap);
}
Expand Down Expand Up @@ -384,7 +423,7 @@ class CurrentColor {
}

void _updateInColorMap(String filenameWoExt, NamidaColor? nc) {
if (nc != null) colorsMap[filenameWoExt] = nc;
if (nc != null) _colorsMap[filenameWoExt] = nc;
if (filenameWoExt == Player.inst.nowPlayingTrack.path.getFilename) {
updatePlayerColorFromTrack(Player.inst.nowPlayingTrack, null);
}
Expand Down
3 changes: 0 additions & 3 deletions lib/controller/player_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:io';

import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:newpipeextractor_dart/newpipeextractor_dart.dart';
Expand Down Expand Up @@ -100,8 +99,6 @@ class Player {

int get sleepingTrackIndex => sleepAfterTracks + currentIndex - 1;

Color? get latestExtractedColor => _audioHandler.latestExtractedColor;

// -- error playing track
void cancelPlayErrorSkipTimer() => _audioHandler.cancelPlayErrorSkipTimer();
int get playErrorRemainingSecondsToSkip => _audioHandler.playErrorRemainingSecondsToSkip;
Expand Down
25 changes: 16 additions & 9 deletions lib/controller/thumbnail_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,21 @@ class ThumbnailManager {
String? channelUrlOrID,
bool isImportantInCache = true,
FutureOr<void> Function()? beforeFetchingFromInternet,
void Function(Uint8List? bytes)? bytesIfWontWriteToFile,
bool hqChannelImage = false,
}) async {
if (id == null && channelUrlOrID == null) return null;

void trySavingLastAccessed(File? file) async {
final time = isImportantInCache ? DateTime.now() : DateTime(1970);
try {
if (file != null && await file.exists()) await file.setLastAccessed(time);
} catch (_) {}
void updateLastAccessed(File? file) async {
await file?.setLastAccessed(DateTime.now()).catchError((_) {});
}

final file = imageUrlToCacheFile(id: id, url: channelUrlOrID);
if (file == null) return null;

if (file.existsSync() == true) {
_printie('Downloading Thumbnail Already Exists');
trySavingLastAccessed(file);
if (isImportantInCache) updateLastAccessed(file);
return file;
}

Expand All @@ -137,8 +135,16 @@ class ThumbnailManager {
if (res != null) channelUrlOrID = res;
}

final bytes = await getYoutubeThumbnailAsBytes(youtubeId: id, url: channelUrlOrID, keepInMemory: false);
final bytes = await getYoutubeThumbnailAsBytes(
youtubeId: id,
url: channelUrlOrID,
keepInMemory: isImportantInCache ? false : true, // important in cache will write to file so we dont need to keep in memory
);
_printie('Downloading Thumbnail Finished with ${bytes?.length} bytes');
if (!isImportantInCache) {
bytesIfWontWriteToFile?.call(bytes);
return null;
}

final savedFileFuture = id != null
? saveThumbnailToStorage(
Expand All @@ -153,8 +159,9 @@ class ThumbnailManager {
bytes: bytes,
);

savedFileFuture.then(trySavingLastAccessed);
return savedFileFuture;
final savedFile = await savedFileFuture;
updateLastAccessed(savedFile);
return savedFile;
}

void closeThumbnailClients(List<String?> links) {
Expand Down
22 changes: 10 additions & 12 deletions lib/packages/miniplayer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -516,15 +516,13 @@ class NamidaMiniPlayerYoutubeID extends StatelessWidget {
localVideos: YoutubeController.inst.currentCachedQualities,
streamVideos: YoutubeController.inst.currentYTQualities,
onLocalVideoTap: (item, video) async {
if (!Player.inst.videoInitialized) {
Player.inst.onItemPlayYoutubeIDSetQuality(
stream: null,
cachedFile: File(video.path),
videoItem: video,
useCache: true,
videoId: Player.inst.nowPlayingVideoID?.id ?? '',
);
}
Player.inst.onItemPlayYoutubeIDSetQuality(
stream: null,
cachedFile: File(video.path),
videoItem: video,
useCache: true,
videoId: Player.inst.nowPlayingVideoID?.id ?? '',
);
},
onStreamVideoTap: (item, videoId, stream, cacheFile) async {
Player.inst.onItemPlayYoutubeIDSetQuality(
Expand Down Expand Up @@ -745,15 +743,15 @@ class _YoutubeIDImage extends StatelessWidget {

@override
Widget build(BuildContext context) {
final width = context.width;
return YoutubeThumbnail(
key: Key(video.id),
videoId: video.id,
width: context.width,
height: context.width * 9 / 16,
width: width,
height: settings.forceSquaredTrackThumbnail.value ? width : width * 9 / 16,
isImportantInCache: true,
compressed: false,
preferLowerRes: false,
forceSquared: settings.forceSquaredTrackThumbnail.value,
borderRadius: 6.0 + 10.0 * cp,
boxShadow: [
BoxShadow(
Expand Down
31 changes: 16 additions & 15 deletions lib/ui/widgets/settings/playback_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,24 +308,25 @@ class PlaybackSettings extends SettingSubpageProvider {
),
),
),
getItemWrapper(
key: _PlaybackSettingsKeys.displayArtworkOnLockscreen,
child: Obx(
() => CustomSwitchListTile(
bgColor: getBgColor(_PlaybackSettingsKeys.displayArtworkOnLockscreen),
title: lang.DISPLAY_ARTWORK_ON_LOCKSCREEN,
leading: const StackedIcon(
baseIcon: Broken.gallery,
secondaryIcon: Broken.lock_circle,
if (kSdkVersion < 33)
getItemWrapper(
key: _PlaybackSettingsKeys.displayArtworkOnLockscreen,
child: Obx(
() => CustomSwitchListTile(
bgColor: getBgColor(_PlaybackSettingsKeys.displayArtworkOnLockscreen),
title: lang.DISPLAY_ARTWORK_ON_LOCKSCREEN,
leading: const StackedIcon(
baseIcon: Broken.gallery,
secondaryIcon: Broken.lock_circle,
),
value: settings.player.lockscreenArtwork.value,
onChanged: (val) {
settings.player.save(lockscreenArtwork: !val);
AudioService.setLockScreenArtwork(!val).then((_) => Player.inst.refreshNotification());
},
),
value: settings.player.lockscreenArtwork.value,
onChanged: (val) {
settings.player.save(lockscreenArtwork: !val);
AudioService.setLockScreenArtwork(!val);
},
),
),
),
getItemWrapper(
key: _PlaybackSettingsKeys.killPlayerAfterDismissing,
child: Obx(
Expand Down
14 changes: 7 additions & 7 deletions lib/ui/widgets/settings/theme_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ class ThemeSetting extends SettingSubpageProvider {
_ThemeSettingsKeys.language: [lang.LANGUAGE],
};

Future<void> _refreshColorCurrentTrack() async {
if (Player.inst.currentQueueYoutube.isNotEmpty && Player.inst.latestExtractedColor != null) {
CurrentColor.inst.updatePlayerColorFromColor(Player.inst.latestExtractedColor!);
Future<void> _refreshColorCurrentPlayingItem() async {
if (Player.inst.nowPlayingVideoID != null) {
await CurrentColor.inst.updatePlayerColorFromYoutubeID(Player.inst.nowPlayingVideoID!);
} else {
await CurrentColor.inst.updatePlayerColorFromTrack(Player.inst.nowPlayingTWD, null);
}
Expand Down Expand Up @@ -208,7 +208,7 @@ class ThemeSetting extends SettingSubpageProvider {
if (isTrue) {
CurrentColor.inst.updatePlayerColorFromColor(playerStaticColor);
} else {
await _refreshColorCurrentTrack();
await _refreshColorCurrentPlayingItem();
}
},
),
Expand All @@ -228,7 +228,7 @@ class ThemeSetting extends SettingSubpageProvider {
onChanged: (isTrue) async {
settings.save(pickColorsFromDeviceWallpaper: !isTrue);

await _refreshColorCurrentTrack();
await _refreshColorCurrentPlayingItem();
},
),
),
Expand All @@ -244,7 +244,7 @@ class ThemeSetting extends SettingSubpageProvider {
value: settings.forceMiniplayerTrackColor.value,
onChanged: (isTrue) async {
settings.save(forceMiniplayerTrackColor: !isTrue);
await _refreshColorCurrentTrack();
await _refreshColorCurrentPlayingItem();
},
),
),
Expand All @@ -260,7 +260,7 @@ class ThemeSetting extends SettingSubpageProvider {
value: settings.pitchBlack.value,
onChanged: (isTrue) async {
settings.save(pitchBlack: !isTrue);
await _refreshColorCurrentTrack();
await _refreshColorCurrentPlayingItem();
},
),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/widgets/video_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ class NamidaVideoControlsState extends State<NamidaVideoControls> with TickerPro
title: element.resolution ?? '',
subtitle: sizeInBytes == null ? '' : " • ${sizeInBytes.fileSizeFormatted}",
onPlay: (isSelected) {
if (!isSelected) {
if (!isSelected || !Player.inst.videoInitialized) {
Player.inst.onItemPlayYoutubeIDSetQuality(
stream: element,
cachedFile: null,
Expand Down
Loading

0 comments on commit 09301ec

Please sign in to comment.