Compare commits

..

No commits in common. "e1fa9efa14ef6a95d55a57089e9fccad1bb90d61" and "4b5108e54e4ff21dd561127e1d78d01578276174" have entirely different histories.

7 changed files with 67 additions and 63 deletions

1
android/.gitignore vendored
View File

@ -11,4 +11,3 @@ GeneratedPluginRegistrant.java
key.properties
**/*.keystore
**/*.jks
.kotlin

View File

@ -44,7 +44,7 @@ class SpotubeAudioLossyContainerQuality
@override
toString() {
return "${oneOptionalDecimalFormatter.format(bitrate / 1000)}kbps";
return "${oneOptionalDecimalFormatter.format(bitrate)}kbps";
}
}

View File

@ -52,10 +52,9 @@ class MetadataInstalledPluginItem extends HookConsumerWidget {
ref.watch(metadataPluginAuthenticatedProvider);
final isAudioSourceAuthenticatedSnapshot =
ref.watch(audioSourcePluginAuthenticatedProvider);
final isAuthenticated = (isDefaultMetadata &&
isMetadataAuthenticatedSnapshot.asData?.value == true) ||
(isDefaultAudioSource &&
isAudioSourceAuthenticatedSnapshot.asData?.value == true);
final isAuthenticated =
isMetadataAuthenticatedSnapshot.asData?.value == true ||
isAudioSourceAuthenticatedSnapshot.asData?.value == true;
final metadataUpdateAvailable =
ref.watch(metadataPluginUpdateCheckerProvider);

View File

@ -6,7 +6,6 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/provider/metadata_plugin/metadata_plugin_provider.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/services/metadata/metadata.dart';
part 'quality_presets.g.dart';
part 'quality_presets.freezed.dart';
@ -29,13 +28,9 @@ class AudioSourceAvailableQualityPresetsNotifier
extends Notifier<AudioSourcePresetsState> {
@override
build() {
final audioSourceSnapshot = ref.watch(audioSourcePluginProvider);
final audioSourceConfigSnapshot = ref.watch(
metadataPluginsProvider.select((data) =>
data.whenData((value) => value.defaultAudioSourcePluginConfig)),
);
ref.watch(audioSourcePluginProvider);
_initialize(audioSourceSnapshot, audioSourceConfigSnapshot);
_initialize();
listenSelf((previous, next) {
final isNewLossless =
@ -54,12 +49,12 @@ class AudioSourceAvailableQualityPresetsNotifier
return AudioSourcePresetsState();
}
void _initialize(
AsyncValue<MetadataPlugin?> audioSourceSnapshot,
AsyncValue<PluginConfiguration?> audioSourceConfigSnapshot,
) async {
audioSourceConfigSnapshot.whenData((audioSourceConfig) {
audioSourceSnapshot.whenData((audioSource) async {
void _initialize() async {
final audioSource = await ref.read(audioSourcePluginProvider.future);
final audioSourceConfig = await ref.read(
metadataPluginsProvider
.selectAsync((data) => data.defaultAudioSourcePluginConfig),
);
if (audioSource == null || audioSourceConfig == null) {
throw Exception("Dude wat?");
}
@ -68,18 +63,12 @@ class AudioSourceAvailableQualityPresetsNotifier
preferences.getString("audioSourceState-${audioSourceConfig.slug}");
if (persistedStateStr != null) {
state =
AudioSourcePresetsState.fromJson(jsonDecode(persistedStateStr))
.copyWith(
presets: audioSource.audioSource.supportedPresets,
);
state = AudioSourcePresetsState.fromJson(jsonDecode(persistedStateStr));
} else {
state = AudioSourcePresetsState(
presets: audioSource.audioSource.supportedPresets,
);
}
});
});
}
void setSelectedStreamingContainerIndex(int index) {

View File

@ -65,6 +65,6 @@ class AudioSourcePluginAuthenticatedNotifier extends AsyncNotifier<bool> {
}
final audioSourcePluginAuthenticatedProvider =
AsyncNotifierProvider<AudioSourcePluginAuthenticatedNotifier, bool>(
AudioSourcePluginAuthenticatedNotifier.new,
AsyncNotifierProvider<MetadataPluginAuthenticatedNotifier, bool>(
MetadataPluginAuthenticatedNotifier.new,
);

View File

@ -48,7 +48,7 @@ class ServerPlaybackRoutes {
return join(
await UserPreferencesNotifier.getMusicCacheDir(),
ServiceUtils.sanitizeFilename(
'${track.query.name} - ${track.query.artists.map((d) => d.name).join(",")} (${track.info.id}).${track.qualityPreset!.name}',
'${track.query.name} - ${track.query.artists.join(",")} (${track.info.id}).${track.qualityPreset!.name}',
),
);
}
@ -288,9 +288,7 @@ class ServerPlaybackRoutes {
imageBytes: imageBytes,
fileLength: fileLength,
),
).catchError((e, stackTrace) {
AppLogger.reportError(e, stackTrace);
});
);
}
return (bytes: bytes, response: res);

View File

@ -306,8 +306,6 @@ class SourcedTrack extends BasicSourcedTrack {
SpotubeAudioSourceContainerPreset preset,
int qualityIndex,
) {
if (sources.isEmpty) return null;
final quality = preset.qualities[qualityIndex];
final exactMatch = sources.firstWhereOrNull(
@ -319,7 +317,7 @@ class SourcedTrack extends BasicSourcedTrack {
source.bitDepth == quality.bitDepth;
} else {
return source.bitrate ==
(quality as SpotubeAudioLossyContainerQuality).bitrate;
(preset as SpotubeAudioLossyContainerQuality).bitrate;
}
},
);
@ -328,24 +326,45 @@ class SourcedTrack extends BasicSourcedTrack {
return exactMatch;
}
// Find the preset with closest quality to the supplied quality
return sources.where((source) {
return source.container == preset.name;
}).reduce((prev, curr) {
if (quality is SpotubeAudioLosslessContainerQuality) {
final prevDiff = ((prev.sampleRate ?? 0) - quality.sampleRate).abs() +
((prev.bitDepth ?? 0) - quality.bitDepth).abs();
final currDiff = ((curr.sampleRate ?? 0) - quality.sampleRate).abs() +
((curr.bitDepth ?? 0) - quality.bitDepth).abs();
return currDiff < prevDiff ? curr : prev;
} else {
final prevDiff = ((prev.bitrate ?? 0) -
(quality as SpotubeAudioLossyContainerQuality).bitrate)
.abs();
final currDiff = ((curr.bitrate ?? 0) - quality.bitrate).abs();
return currDiff < prevDiff ? curr : prev;
// Find the closest to preset
SpotubeAudioSourceStreamObject? closest;
for (final source in sources) {
if (source.container != preset.name) continue;
if (quality case SpotubeAudioLosslessContainerQuality()) {
final sourceBps = (source.bitDepth ?? 0) * (source.sampleRate ?? 0);
final qualityBps = quality.bitDepth * quality.sampleRate;
final closestBps =
(closest?.bitDepth ?? 0) * (closest?.sampleRate ?? 0);
if (sourceBps == qualityBps) {
closest = source;
break;
}
});
final closestDiff = (closestBps - qualityBps).abs();
final sourceDiff = (sourceBps - qualityBps).abs();
if (sourceDiff < closestDiff) {
closest = source;
}
} else {
final presetBitrate =
(preset as SpotubeAudioLossyContainerQuality).bitrate;
if (presetBitrate == source.bitrate) {
closest = source;
break;
}
final closestDiff = (closest?.bitrate ?? 0) - presetBitrate;
final sourceDiff = (source.bitrate ?? 0) - presetBitrate;
if (sourceDiff < closestDiff) {
closest = source;
}
}
}
return closest;
}
String? getUrlOfQuality(