Skip to content

Commit

Permalink
chore: force video thumbnails obtained by url to be saved in "YTThumb…
Browse files Browse the repository at this point in the history
…nails"

instead of "YTThumbnails Channels" which is for links (channels/playlists/etc)
- this fixes missing notification artwork for these videos
  • Loading branch information
MSOB7YY committed Jul 19, 2024
1 parent a1136c3 commit 8df7c75
Show file tree
Hide file tree
Showing 14 changed files with 62 additions and 26 deletions.
7 changes: 4 additions & 3 deletions lib/base/audio_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import 'package:namida/youtube/controller/youtube_controller.dart';
import 'package:namida/youtube/controller/youtube_history_controller.dart';
import 'package:namida/youtube/controller/youtube_info_controller.dart';
import 'package:namida/youtube/controller/youtube_playlist_controller.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';
import 'package:namida/youtube/yt_utils.dart';

class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
Expand Down Expand Up @@ -898,7 +899,7 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {

Duration? duration = streamsResult?.audioStreams.firstOrNull?.duration;
_ytNotificationVideoInfo = streamsResult?.info;
_ytNotificationVideoThumbnail = item.getThumbnailSync(temp: false);
_ytNotificationVideoThumbnail = item.getThumbnailSync(temp: false, type: ThumbnailType.video);

bool checkInterrupted({bool refreshNoti = true}) {
final curr = currentItem.value;
Expand Down Expand Up @@ -936,8 +937,8 @@ class NamidaAudioVideoHandler<Q extends Playable> extends BasicAudioHandler<Q> {
onInfoOrThumbObtained(info: _ytNotificationVideoInfo, thumbnail: _ytNotificationVideoThumbnail);

if (_ytNotificationVideoThumbnail == null) {
ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: item.id).then((thumbFile) {
thumbFile ??= item.getThumbnailSync(temp: true);
ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: item.id, type: ThumbnailType.video).then((thumbFile) {
thumbFile ??= item.getThumbnailSync(temp: true, type: ThumbnailType.video);
if (thumbFile != null) onInfoOrThumbObtained(thumbnail: thumbFile);
});
}
Expand Down
6 changes: 4 additions & 2 deletions lib/controller/current_color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ 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:flutter/scheduler.dart';

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

Expand All @@ -21,6 +22,7 @@ import 'package:namida/core/constants.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/utils.dart';
import 'package:namida/youtube/class/youtube_id.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';

Color get playerStaticColor => namida.isDarkMode ? playerStaticColorDark : playerStaticColorLight;
Color get playerStaticColorLight => Color(settings.staticColor.valueR);
Expand Down Expand Up @@ -185,7 +187,7 @@ class CurrentColor {
getColorPalette: () async {
if (_colorsMapYTID[id] != null) return _colorsMapYTID[id]!;

final image = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: id);
final image = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: id, type: ThumbnailType.video);
if (image != null && stillPlaying()) {
final color = await CurrentColor.inst.extractPaletteFromImage(image.path, paletteSaveDirectory: Directory(AppDirs.YT_PALETTES), useIsolate: true);
if (color != null && stillPlaying()) {
Expand Down
3 changes: 2 additions & 1 deletion lib/controller/ffmpeg_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:namida/core/constants.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/utils.dart';
import 'package:namida/main.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';

class NamidaFFMPEG {
static NamidaFFMPEG get inst => _instance;
Expand Down Expand Up @@ -280,7 +281,7 @@ class NamidaFFMPEG {

File? cachedThumbnail;

cachedThumbnail = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: ytId);
cachedThumbnail = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: ytId, type: ThumbnailType.video);

if (cachedThumbnail == null) {
currentFailed++;
Expand Down
33 changes: 26 additions & 7 deletions lib/controller/thumbnail_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'dart:io';
import 'dart:isolate';

import 'package:flutter/material.dart';

import 'package:youtipie/class/thumbnail.dart';

import 'package:namida/base/ports_provider.dart';
Expand All @@ -14,6 +15,7 @@ import 'package:namida/controller/ffmpeg_controller.dart';
import 'package:namida/core/constants.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/youtube/controller/youtube_history_controller.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';

class ThumbnailManager {
static final ThumbnailManager inst = ThumbnailManager._internal();
Expand All @@ -35,13 +37,24 @@ class ThumbnailManager {
File? imageUrlToCacheFile({
required String? id,
required String? url,
required ThumbnailType type,
String? symlinkId,
bool isTemp = false,
}) {
final dirPrefix = isTemp ? 'temp/' : '';

if (id != null && id.isNotEmpty) {
return File("${AppDirs.YT_THUMBNAILS}$dirPrefix${symlinkId ?? '$id.png'}");
final goodId = id != null && id.isNotEmpty;
if (goodId || type == ThumbnailType.video) {
String? filename;
if (symlinkId != null) {
filename = symlinkId;
} else if (goodId) {
filename = '$id.png';
} else if (url != null) {
filename = url.splitLast('/').substring(0, 11); // custom urls like dAdjsaB_GKL_hqdefault.jpg
}
if (filename == null || filename.isEmpty) return null;
return File("${AppDirs.YT_THUMBNAILS}$dirPrefix$filename");
}
String? finalUrl = url;
final imageUrl = finalUrl?.split('i.ytimg.com/vi/');
Expand Down Expand Up @@ -74,9 +87,14 @@ class ThumbnailManager {
return fileExists ? file : null;
}

File? getYoutubeThumbnailFromCacheSync({String? id, String? customUrl, bool isTemp = false}) {
File? getYoutubeThumbnailFromCacheSync({
String? id,
String? customUrl,
bool isTemp = false,
required ThumbnailType type,
}) {
if (id == null && customUrl == null) return null;
final file = imageUrlToCacheFile(id: id, url: customUrl, isTemp: isTemp);
final file = imageUrlToCacheFile(id: id, url: customUrl, isTemp: isTemp, type: type);
if (file != null && file.existsSync()) return file;
return null;
}
Expand All @@ -86,18 +104,19 @@ class ThumbnailManager {
String? customUrl,
bool isImportantInCache = true,
String? symlinkId,
required ThumbnailType type,
}) async {
if (id == null && customUrl == null) return null;

final isTemp = isImportantInCache ? false : true;

final file = imageUrlToCacheFile(id: id, url: customUrl, isTemp: isTemp);
final file = imageUrlToCacheFile(id: id, url: customUrl, isTemp: isTemp, type: type);
if (file == null) return null;
if (file.existsSync()) return file;

if (symlinkId != null) {
try {
final symlinkfile = imageUrlToCacheFile(id: id, url: customUrl, symlinkId: symlinkId, isTemp: isTemp);
final symlinkfile = imageUrlToCacheFile(id: id, url: customUrl, symlinkId: symlinkId, isTemp: isTemp, type: type);
if (symlinkfile != null && symlinkfile.existsSync()) {
final targetFilePath = Link.fromUri(symlinkfile.uri).targetSync();
final targetFile = File(targetFilePath);
Expand Down Expand Up @@ -132,7 +151,7 @@ class ThumbnailManager {
}
final bool lowerResYTID = isTemp;

final file = imageUrlToCacheFile(id: videoId, url: null, isTemp: isTemp);
final file = imageUrlToCacheFile(id: videoId, url: null, isTemp: isTemp, type: ThumbnailType.video);
if (file == null) return null;
final downloaded = await _getYoutubeThumbnail(
itemId: videoId,
Expand Down
4 changes: 3 additions & 1 deletion lib/controller/video_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';

import 'package:youtipie/class/streams/video_stream.dart';
import 'package:youtipie/class/streams/video_streams_result.dart';

Expand All @@ -24,6 +25,7 @@ import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/ui/widgets/video_widget.dart';
import 'package:namida/youtube/controller/youtube_controller.dart';
import 'package:namida/youtube/controller/youtube_info_controller.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';

class NamidaVideoWidget extends StatelessWidget {
final bool enableControls;
Expand Down Expand Up @@ -287,7 +289,7 @@ class VideoController {
// saving video thumbnail
final id = erabaretaVideo?.ytID;
if (id != null) {
ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: id);
ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: id, type: ThumbnailType.video);
}

return erabaretaVideo;
Expand Down
1 change: 1 addition & 0 deletions lib/core/namida_converter_ext.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';

import 'package:flutter/material.dart';

import 'package:history_manager/history_manager.dart';
import 'package:path/path.dart' as p;
import 'package:youtipie/class/result_wrapper/playlist_result_base.dart';
Expand Down
7 changes: 3 additions & 4 deletions lib/ui/widgets/library/track_tile.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:flutter/material.dart';

import 'package:namida/core/utils.dart';

import 'package:namida/class/track.dart';
import 'package:namida/controller/current_color.dart';
import 'package:namida/controller/player_controller.dart';
Expand All @@ -13,10 +11,11 @@ import 'package:namida/core/enums.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/icon_fonts/broken_icons.dart';
import 'package:namida/core/namida_converter_ext.dart';
import 'package:namida/ui/widgets/artwork.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/core/utils.dart';
import 'package:namida/ui/dialogs/common_dialogs.dart';
import 'package:namida/ui/dialogs/track_info_dialog.dart';
import 'package:namida/ui/widgets/artwork.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';

class TrackTile extends StatelessWidget {
final int index;
Expand Down
5 changes: 3 additions & 2 deletions lib/youtube/class/youtube_id.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:namida/class/track.dart';
import 'package:namida/class/video.dart';
import 'package:namida/controller/thumbnail_manager.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';

class YoutubeID implements Playable, ItemWithDate {
final String id;
Expand Down Expand Up @@ -61,8 +62,8 @@ class YoutubeID implements Playable, ItemWithDate {
}

extension YoutubeIDUtils on YoutubeID {
File? getThumbnailSync({required bool temp}) {
return ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(id: id, isTemp: temp);
File? getThumbnailSync({required bool temp, required ThumbnailType type}) {
return ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(id: id, isTemp: temp, type: type);
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/youtube/controller/youtube_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:namida/youtube/class/youtube_item_download_config.dart';
import 'package:namida/youtube/controller/parallel_downloads_controller.dart';
import 'package:namida/youtube/controller/youtube_info_controller.dart';
import 'package:namida/youtube/controller/youtube_ongoing_finished_downloads.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';
import 'package:namida/youtube/yt_utils.dart';

class _YTNotificationDataHolder {
Expand All @@ -38,7 +39,7 @@ class _YTNotificationDataHolder {
}

File? imageCallback(DownloadTaskVideoId videoId) {
return _imagesLookupTemp[videoId] ??= ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(id: videoId.videoId);
return _imagesLookupTemp[videoId] ??= ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(id: videoId.videoId, type: ThumbnailType.video);
}

void clearAll() {
Expand Down Expand Up @@ -645,6 +646,7 @@ class YoutubeController {
final thumbnailFile = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(
id: videoID.videoId,
isImportantInCache: true,
type: ThumbnailType.video,
);
await YTUtils.writeAudioMetadata(
videoId: videoID.videoId,
Expand Down
3 changes: 2 additions & 1 deletion lib/youtube/functions/video_listens_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import 'package:namida/core/constants.dart';
import 'package:namida/core/dimensions.dart';
import 'package:namida/ui/dialogs/track_listens_dialog.dart';
import 'package:namida/youtube/controller/youtube_history_controller.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';
import 'package:namida/youtube/yt_utils.dart';

void showVideoListensDialog(String videoId, {List<int> datesOfListen = const [], Color? colorScheme}) async {
showListensDialog(
datesOfListen: datesOfListen.isNotEmpty ? datesOfListen : YoutubeHistoryController.inst.topTracksMapListens.value[videoId] ?? [],
colorScheme: colorScheme,
colorSchemeFunction: () async {
final image = ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(id: videoId);
final image = ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(id: videoId, type: ThumbnailType.video);
if (image != null) {
final color = await CurrentColor.inst.extractPaletteFromImage(image.path, paletteSaveDirectory: Directory(AppDirs.YT_PALETTES), useIsolate: true);
return color?.color;
Expand Down
5 changes: 3 additions & 2 deletions lib/youtube/pages/yt_channel_subpage.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';

import 'package:flutter/material.dart';

import 'package:jiffy/jiffy.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
Expand All @@ -10,6 +11,7 @@ import 'package:youtipie/class/result_wrapper/list_wrapper_base.dart';
import 'package:youtipie/class/stream_info_item/stream_info_item.dart';
import 'package:youtipie/class/thumbnail.dart';
import 'package:youtipie/class/youtipie_feed/channel_info_item.dart';
import 'package:youtipie/core/extensions.dart';

import 'package:namida/base/pull_to_refresh.dart';
import 'package:namida/base/youtube_channel_controller.dart';
Expand All @@ -32,7 +34,6 @@ import 'package:namida/youtube/widgets/yt_subscribe_buttons.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';
import 'package:namida/youtube/widgets/yt_video_card.dart';
import 'package:namida/youtube/widgets/yt_videos_actions_bar.dart';
import 'package:youtipie/core/extensions.dart';

class YTChannelSubpage extends StatefulWidget with NamidaRouteWidget {
@override
Expand Down Expand Up @@ -101,7 +102,7 @@ class _YTChannelSubpageState extends YoutubeChannelController<YTChannelSubpage>
}

File? _getThumbFileForCache(String url, {required bool temp}) {
return ThumbnailManager.inst.imageUrlToCacheFile(id: null, url: url, isTemp: temp);
return ThumbnailManager.inst.imageUrlToCacheFile(id: null, url: url, isTemp: temp, type: ThumbnailType.channel);
}

void _onImageTap({
Expand Down
4 changes: 4 additions & 0 deletions lib/youtube/widgets/yt_thumbnail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,14 @@ class _YoutubeThumbnailState extends State<YoutubeThumbnail> with LoadingItemsDe
id: videoId,
customUrl: widget.customUrl,
isTemp: false,
type: widget.type,
);
if (res == null && (!widget.isImportantInCache || widget.preferLowerRes)) {
res = ThumbnailManager.inst.getYoutubeThumbnailFromCacheSync(
id: videoId,
customUrl: widget.customUrl,
isTemp: true,
type: widget.type,
);
}

Expand All @@ -140,6 +142,7 @@ class _YoutubeThumbnailState extends State<YoutubeThumbnail> with LoadingItemsDe
res = await ThumbnailManager.inst.getYoutubeThumbnailAndCache(
id: videoId,
isImportantInCache: true,
type: widget.type,
);
} else {
res = await ThumbnailManager.inst.getLowResYoutubeVideoThumbnail(videoId);
Expand All @@ -150,6 +153,7 @@ class _YoutubeThumbnailState extends State<YoutubeThumbnail> with LoadingItemsDe
customUrl: widget.customUrl,
symlinkId: widget.urlSymLinkId,
isImportantInCache: widget.isImportantInCache,
type: widget.type,
);
}
}
Expand Down
4 changes: 3 additions & 1 deletion lib/youtube/yt_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:io';

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

import 'package:history_manager/history_manager.dart';
import 'package:intl/intl.dart';
import 'package:playlist_manager/module/playlist_id.dart';
Expand Down Expand Up @@ -37,6 +38,7 @@ import 'package:namida/youtube/functions/download_sheet.dart';
import 'package:namida/youtube/functions/video_listens_dialog.dart';
import 'package:namida/youtube/pages/yt_channel_subpage.dart';
import 'package:namida/youtube/pages/yt_history_page.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';

class YTUtils {
static void expandMiniplayer() {
Expand Down Expand Up @@ -319,7 +321,7 @@ class YTUtils {
required File? thumbnailFile,
required Map<String, String?> tagsMap,
}) async {
final thumbnail = thumbnailFile ?? await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: videoId);
final thumbnail = thumbnailFile ?? await ThumbnailManager.inst.getYoutubeThumbnailAndCache(id: videoId, type: ThumbnailType.video);
if (thumbnail != null) {
await NamidaFFMPEG.inst.editAudioThumbnail(audioPath: audioFile.path, thumbnailPath: thumbnail.path);
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: namida
description: A Beautiful and Feature-rich Music Player, With YouTube & Video Support Built in Flutter
publish_to: "none"
version: 3.4.8-beta+240719197
version: 3.4.9-beta+240719207

environment:
sdk: ">=3.4.0 <4.0.0"
Expand Down

0 comments on commit 8df7c75

Please sign in to comment.