diff --git a/lib/models/database/tables/history.dart b/lib/models/database/tables/history.dart index 2faeba9a..f074e248 100644 --- a/lib/models/database/tables/history.dart +++ b/lib/models/database/tables/history.dart @@ -16,12 +16,16 @@ class HistoryTable extends Table { } extension HistoryItemParseExtension on HistoryTableData { - SpotubeSimplePlaylistObject? get playlist => type == HistoryEntryType.playlist - ? SpotubeSimplePlaylistObject.fromJson(data) - : null; - SpotubeSimpleAlbumObject? get album => type == HistoryEntryType.album - ? SpotubeSimpleAlbumObject.fromJson(data) - : null; + SpotubeSimplePlaylistObject? get playlist => + type == HistoryEntryType.playlist && !data.containsKey("external_urls") + ? SpotubeSimplePlaylistObject.fromJson(data) + : null; + SpotubeSimpleAlbumObject? get album => + type == HistoryEntryType.album && !data.containsKey("external_urls") + ? SpotubeSimpleAlbumObject.fromJson(data) + : null; SpotubeTrackObject? get track => - type == HistoryEntryType.track ? SpotubeTrackObject.fromJson(data) : null; + type == HistoryEntryType.track && !data.containsKey("external_urls") + ? SpotubeTrackObject.fromJson(data) + : null; } diff --git a/lib/services/sourced_track/sourced_track.dart b/lib/services/sourced_track/sourced_track.dart index f8caa38d..3e218bad 100644 --- a/lib/services/sourced_track/sourced_track.dart +++ b/lib/services/sourced_track/sourced_track.dart @@ -149,25 +149,48 @@ abstract class SourcedTrack extends BasicSourcedTrack { return getUrlOfCodec(codec); } + /// Returns the URL of the track based on the codec and quality preferences. + /// If an exact match is not found, it will return the closest match based on + /// the user's audio quality preference. + /// + /// If no sources match the codec, it will return the first or last source + /// based on the user's audio quality preference. String getUrlOfCodec(SourceCodecs codec) { final preferences = ref.read(userPreferencesProvider); - return sources - .firstWhereOrNull( - (source) => - source.codec == codec && - source.quality == preferences.audioQuality, - ) - ?.url ?? - // fallback to the first available source of the same codec - sources.firstWhereOrNull((source) => source.codec == codec)?.url ?? - // fallback to the first available source of any codec - sources - .firstWhereOrNull( - (source) => source.quality == preferences.audioQuality) - ?.url ?? - // fallback to the first available source - sources.first.url; + final exactMatch = sources.firstWhereOrNull( + (source) => + source.codec == codec && source.quality == preferences.audioQuality, + ); + + if (exactMatch != null) { + return exactMatch.url; + } + + final sameCodecSources = sources + .where((source) => source.codec == codec) + .toList() + .sorted((a, b) { + final aDiff = (a.quality.index - preferences.audioQuality.index).abs(); + final bDiff = (b.quality.index - preferences.audioQuality.index).abs(); + return aDiff != bDiff ? aDiff - bDiff : a.quality.index - b.quality.index; + }).toList(); + + if (sameCodecSources.isNotEmpty) { + return preferences.audioQuality != SourceQualities.low + ? sameCodecSources.first.url + : sameCodecSources.last.url; + } + + final fallbackSource = sources.sorted((a, b) { + final aDiff = (a.quality.index - preferences.audioQuality.index).abs(); + final bDiff = (b.quality.index - preferences.audioQuality.index).abs(); + return aDiff != bDiff ? aDiff - bDiff : a.quality.index - b.quality.index; + }); + + return preferences.audioQuality != SourceQualities.low + ? fallbackSource.first.url + : fallbackSource.last.url; } SourceCodecs get codec { diff --git a/lib/services/sourced_track/sources/youtube.dart b/lib/services/sourced_track/sources/youtube.dart index 925a48e2..0e494b89 100644 --- a/lib/services/sourced_track/sources/youtube.dart +++ b/lib/services/sourced_track/sources/youtube.dart @@ -95,17 +95,6 @@ class YoutubeSourcedTrack extends SourcedTrack { } static List toTrackSources(StreamManifest manifest) { - var m4a = manifest.audioOnly - .where((audio) => audio.codec.mimeType == "audio/mp4") - .sortByBitrate(); - - var weba = manifest.audioOnly - .where((audio) => audio.codec.mimeType == "audio/webm") - .sortByBitrate(); - - m4a = m4a.isEmpty ? weba.toList() : m4a; - weba = weba.isEmpty ? m4a.toList() : weba; - return manifest.audioOnly.map((streamInfo) { return TrackSource( url: streamInfo.url.toString(), diff --git a/pubspec.lock b/pubspec.lock index 0347baf5..3cc1d962 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1209,7 +1209,7 @@ packages: description: path: "." ref: main - resolved-ref: "1aa924281d2dbe09aab27d8c2de1cffc853b0d16" + resolved-ref: eeb574c3fac0da07ba93c9d972b7eb38960538d2 url: "https://github.com/KRTirtho/hetu_spotube_plugin.git" source: git version: "0.0.1"