Skip to content

Commit 352b86e

Browse files
committed
chore: fix info extraction from description and make it optional
1 parent 3f524ab commit 352b86e

File tree

4 files changed

+29
-7
lines changed

4 files changed

+29
-7
lines changed

lib/controller/settings.youtube.dart

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class _YoutubeSettings with SettingsFileWriter {
1717
final youtubeStyleMiniplayer = true.obs;
1818
final preferNewComments = false.obs;
1919
final autoExtractVideoTagsFromInfo = true.obs;
20+
final fallbackExtractInfoDescription = true.obs;
2021
final isAudioOnlyMode = false.obs;
2122
final rememberAudioOnly = false.obs;
2223
final topComments = true.obs;
@@ -44,6 +45,7 @@ class _YoutubeSettings with SettingsFileWriter {
4445
bool? rememberAudioOnly,
4546
bool? topComments,
4647
bool? autoExtractVideoTagsFromInfo,
48+
bool? fallbackExtractInfoDescription,
4749
OnYoutubeLinkOpenAction? onYoutubeLinkOpen,
4850
YTSeekActionMode? tapToSeek,
4951
YTSeekActionMode? dragToSeek,
@@ -67,6 +69,7 @@ class _YoutubeSettings with SettingsFileWriter {
6769
if (rememberAudioOnly != null) this.rememberAudioOnly.value = rememberAudioOnly;
6870
if (topComments != null) this.topComments.value = topComments;
6971
if (autoExtractVideoTagsFromInfo != null) this.autoExtractVideoTagsFromInfo.value = autoExtractVideoTagsFromInfo;
72+
if (fallbackExtractInfoDescription != null) this.fallbackExtractInfoDescription.value = fallbackExtractInfoDescription;
7073
if (onYoutubeLinkOpen != null) this.onYoutubeLinkOpen.value = onYoutubeLinkOpen;
7174
if (tapToSeek != null) this.tapToSeek.value = tapToSeek;
7275
if (dragToSeek != null) this.dragToSeek.value = dragToSeek;
@@ -104,6 +107,7 @@ class _YoutubeSettings with SettingsFileWriter {
104107
youtubeStyleMiniplayer.value = json['youtubeStyleMiniplayer'] ?? youtubeStyleMiniplayer.value;
105108
preferNewComments.value = json['preferNewComments'] ?? preferNewComments.value;
106109
autoExtractVideoTagsFromInfo.value = json['autoExtractVideoTagsFromInfo'] ?? autoExtractVideoTagsFromInfo.value;
110+
fallbackExtractInfoDescription.value = json['fallbackExtractInfoDescription'] ?? fallbackExtractInfoDescription.value;
107111
rememberAudioOnly.value = json['rememberAudioOnly'] ?? rememberAudioOnly.value;
108112
if (rememberAudioOnly.value) isAudioOnlyMode.value = json['isAudioOnlyMode'] ?? isAudioOnlyMode.value;
109113
topComments.value = json['topComments'] ?? topComments.value;
@@ -142,6 +146,7 @@ class _YoutubeSettings with SettingsFileWriter {
142146
'youtubeStyleMiniplayer': youtubeStyleMiniplayer.value,
143147
'preferNewComments': preferNewComments.value,
144148
'autoExtractVideoTagsFromInfo': autoExtractVideoTagsFromInfo.value,
149+
'fallbackExtractInfoDescription': fallbackExtractInfoDescription.value,
145150
'isAudioOnlyMode': isAudioOnlyMode.value,
146151
'rememberAudioOnly': rememberAudioOnly.value,
147152
'topComments': topComments.value,

lib/ui/widgets/settings/youtube_settings.dart

+10
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,16 @@ class __YTFlagsOptionsState extends State<_YTFlagsOptions> {
608608
onChanged: (isTrue) => setState(() => settings.youtube.save(markVideoWatched: !isTrue)),
609609
title: 'mark_video_watched'.toUpperCase(),
610610
),
611+
CustomSwitchListTile(
612+
leading: StackedIcon(
613+
baseIcon: Broken.document_text_1,
614+
secondaryIcon: Broken.export_1,
615+
secondaryIconSize: 12.0,
616+
),
617+
value: settings.youtube.fallbackExtractInfoDescription.value,
618+
onChanged: (isTrue) => setState(() => settings.youtube.save(fallbackExtractInfoDescription: !isTrue)),
619+
title: 'try_extract_tags_info_from_description'.toUpperCase(),
620+
),
611621
CustomListTile(
612622
icon: Broken.cpu,
613623
title: 'innertube_client'.toUpperCase(),

lib/youtube/controller/yt_filename_rebuilder.dart

+13-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class _YtFilenameRebuilder {
55

66
final paramRegex = RegExp(r'%\((\w+)\)s');
77

8+
bool get fallbackExtractInfoFromDescription => settings.youtube.fallbackExtractInfoDescription.value;
9+
810
String? rebuildFilenameWithDecodedParams(
911
String filenameEncoded,
1012
String videoId,
@@ -109,8 +111,10 @@ class _YtFilenameRebuilder {
109111
final fulltitle = pageResult?.videoInfo?.title ?? videoItem?.title ?? streams?.info?.title;
110112
final splitted = fulltitle?.splitArtistAndTitle();
111113

112-
final possibleExtracted = _extractArtistTitleFromDescriptionIfNecessary(splitted, (infos) => infos.$2?.keepFeatKeywordsOnly(), streams, pageResult, videoItem);
113-
if (possibleExtracted != null) return possibleExtracted;
114+
if (fallbackExtractInfoFromDescription) {
115+
final possibleExtracted = _extractArtistTitleFromDescriptionIfNecessary(splitted, (infos) => infos.$2?.keepFeatKeywordsOnly(), streams, pageResult, videoItem);
116+
if (possibleExtracted != null) return possibleExtracted;
117+
}
114118

115119
return splitted?.$2?.keepFeatKeywordsOnly() ?? streams?.info?.title ?? fulltitle;
116120
}(),
@@ -120,8 +124,10 @@ class _YtFilenameRebuilder {
120124

121125
if (fulltitle != null) {
122126
final splitted = fulltitle.splitArtistAndTitle();
123-
final possibleExtracted = _extractArtistTitleFromDescriptionIfNecessary(splitted, (infos) => infos.$1, streams, pageResult, videoItem);
124-
if (possibleExtracted != null) return possibleExtracted;
127+
if (fallbackExtractInfoFromDescription) {
128+
final possibleExtracted = _extractArtistTitleFromDescriptionIfNecessary(splitted, (infos) => infos.$1, streams, pageResult, videoItem);
129+
if (possibleExtracted != null) return possibleExtracted;
130+
}
125131
final String? artist = splitted.$1;
126132
if (artist != null) return artist;
127133
} else {
@@ -203,10 +209,11 @@ class _YtFilenameRebuilder {
203209
final description = _getDescription(streams, pageResult, videoItem);
204210
if (description != null) {
205211
final title = info?.$2?.splitFirst('(').splitFirst('[');
206-
final regex = title == null ? RegExp('(song|info|details)\\W+(.+)', caseSensitive: false) : RegExp('(song|info|details)?\\W+(.+$title.+)', caseSensitive: false);
212+
final regex = title == null ? RegExp('^\\W*(song|info|details)(.*)', caseSensitive: false) : RegExp('^\\W*(song|info|details)?(.*$title.*)', caseSensitive: false);
207213
final regexArtist = RegExp('artist:(.*)', caseSensitive: false);
208214
final regexTitle = RegExp('title:(.*)', caseSensitive: false);
209-
for (final line in description.split('\n')) {
215+
for (String line in description.split('\n')) {
216+
line = line.replaceFirst(RegExp('Nightcore\\W*', caseSensitive: false), '');
210217
final m = regex.firstMatch(line);
211218
try {
212219
var infosLine = m?.group(2)?.splitArtistAndTitle();

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: namida
22
description: A Beautiful and Feature-rich Music Player, With YouTube & Video Support Built in Flutter
33
publish_to: "none"
4-
version: 4.6.47-beta+241103030
4+
version: 4.6.48-beta+241103030
55

66
environment:
77
sdk: ">=3.4.0 <4.0.0"

0 commit comments

Comments
 (0)