mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-12-06 07:29:42 +00:00
Compare commits
No commits in common. "e1fa9efa14ef6a95d55a57089e9fccad1bb90d61" and "4b5108e54e4ff21dd561127e1d78d01578276174" have entirely different histories.
e1fa9efa14
...
4b5108e54e
1
android/.gitignore
vendored
1
android/.gitignore
vendored
@ -11,4 +11,3 @@ GeneratedPluginRegistrant.java
|
|||||||
key.properties
|
key.properties
|
||||||
**/*.keystore
|
**/*.keystore
|
||||||
**/*.jks
|
**/*.jks
|
||||||
.kotlin
|
|
||||||
@ -44,7 +44,7 @@ class SpotubeAudioLossyContainerQuality
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
toString() {
|
toString() {
|
||||||
return "${oneOptionalDecimalFormatter.format(bitrate / 1000)}kbps";
|
return "${oneOptionalDecimalFormatter.format(bitrate)}kbps";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,10 +52,9 @@ class MetadataInstalledPluginItem extends HookConsumerWidget {
|
|||||||
ref.watch(metadataPluginAuthenticatedProvider);
|
ref.watch(metadataPluginAuthenticatedProvider);
|
||||||
final isAudioSourceAuthenticatedSnapshot =
|
final isAudioSourceAuthenticatedSnapshot =
|
||||||
ref.watch(audioSourcePluginAuthenticatedProvider);
|
ref.watch(audioSourcePluginAuthenticatedProvider);
|
||||||
final isAuthenticated = (isDefaultMetadata &&
|
final isAuthenticated =
|
||||||
isMetadataAuthenticatedSnapshot.asData?.value == true) ||
|
isMetadataAuthenticatedSnapshot.asData?.value == true ||
|
||||||
(isDefaultAudioSource &&
|
isAudioSourceAuthenticatedSnapshot.asData?.value == true;
|
||||||
isAudioSourceAuthenticatedSnapshot.asData?.value == true);
|
|
||||||
|
|
||||||
final metadataUpdateAvailable =
|
final metadataUpdateAvailable =
|
||||||
ref.watch(metadataPluginUpdateCheckerProvider);
|
ref.watch(metadataPluginUpdateCheckerProvider);
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||||||
import 'package:spotube/models/metadata/metadata.dart';
|
import 'package:spotube/models/metadata/metadata.dart';
|
||||||
import 'package:spotube/provider/metadata_plugin/metadata_plugin_provider.dart';
|
import 'package:spotube/provider/metadata_plugin/metadata_plugin_provider.dart';
|
||||||
import 'package:spotube/services/audio_player/audio_player.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.g.dart';
|
||||||
part 'quality_presets.freezed.dart';
|
part 'quality_presets.freezed.dart';
|
||||||
@ -29,13 +28,9 @@ class AudioSourceAvailableQualityPresetsNotifier
|
|||||||
extends Notifier<AudioSourcePresetsState> {
|
extends Notifier<AudioSourcePresetsState> {
|
||||||
@override
|
@override
|
||||||
build() {
|
build() {
|
||||||
final audioSourceSnapshot = ref.watch(audioSourcePluginProvider);
|
ref.watch(audioSourcePluginProvider);
|
||||||
final audioSourceConfigSnapshot = ref.watch(
|
|
||||||
metadataPluginsProvider.select((data) =>
|
|
||||||
data.whenData((value) => value.defaultAudioSourcePluginConfig)),
|
|
||||||
);
|
|
||||||
|
|
||||||
_initialize(audioSourceSnapshot, audioSourceConfigSnapshot);
|
_initialize();
|
||||||
|
|
||||||
listenSelf((previous, next) {
|
listenSelf((previous, next) {
|
||||||
final isNewLossless =
|
final isNewLossless =
|
||||||
@ -54,32 +49,26 @@ class AudioSourceAvailableQualityPresetsNotifier
|
|||||||
return AudioSourcePresetsState();
|
return AudioSourcePresetsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initialize(
|
void _initialize() async {
|
||||||
AsyncValue<MetadataPlugin?> audioSourceSnapshot,
|
final audioSource = await ref.read(audioSourcePluginProvider.future);
|
||||||
AsyncValue<PluginConfiguration?> audioSourceConfigSnapshot,
|
final audioSourceConfig = await ref.read(
|
||||||
) async {
|
metadataPluginsProvider
|
||||||
audioSourceConfigSnapshot.whenData((audioSourceConfig) {
|
.selectAsync((data) => data.defaultAudioSourcePluginConfig),
|
||||||
audioSourceSnapshot.whenData((audioSource) async {
|
);
|
||||||
if (audioSource == null || audioSourceConfig == null) {
|
if (audioSource == null || audioSourceConfig == null) {
|
||||||
throw Exception("Dude wat?");
|
throw Exception("Dude wat?");
|
||||||
}
|
}
|
||||||
final preferences = await SharedPreferences.getInstance();
|
final preferences = await SharedPreferences.getInstance();
|
||||||
final persistedStateStr =
|
final persistedStateStr =
|
||||||
preferences.getString("audioSourceState-${audioSourceConfig.slug}");
|
preferences.getString("audioSourceState-${audioSourceConfig.slug}");
|
||||||
|
|
||||||
if (persistedStateStr != null) {
|
if (persistedStateStr != null) {
|
||||||
state =
|
state = AudioSourcePresetsState.fromJson(jsonDecode(persistedStateStr));
|
||||||
AudioSourcePresetsState.fromJson(jsonDecode(persistedStateStr))
|
} else {
|
||||||
.copyWith(
|
state = AudioSourcePresetsState(
|
||||||
presets: audioSource.audioSource.supportedPresets,
|
presets: audioSource.audioSource.supportedPresets,
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
state = AudioSourcePresetsState(
|
|
||||||
presets: audioSource.audioSource.supportedPresets,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSelectedStreamingContainerIndex(int index) {
|
void setSelectedStreamingContainerIndex(int index) {
|
||||||
|
|||||||
@ -65,6 +65,6 @@ class AudioSourcePluginAuthenticatedNotifier extends AsyncNotifier<bool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final audioSourcePluginAuthenticatedProvider =
|
final audioSourcePluginAuthenticatedProvider =
|
||||||
AsyncNotifierProvider<AudioSourcePluginAuthenticatedNotifier, bool>(
|
AsyncNotifierProvider<MetadataPluginAuthenticatedNotifier, bool>(
|
||||||
AudioSourcePluginAuthenticatedNotifier.new,
|
MetadataPluginAuthenticatedNotifier.new,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -48,7 +48,7 @@ class ServerPlaybackRoutes {
|
|||||||
return join(
|
return join(
|
||||||
await UserPreferencesNotifier.getMusicCacheDir(),
|
await UserPreferencesNotifier.getMusicCacheDir(),
|
||||||
ServiceUtils.sanitizeFilename(
|
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,
|
imageBytes: imageBytes,
|
||||||
fileLength: fileLength,
|
fileLength: fileLength,
|
||||||
),
|
),
|
||||||
).catchError((e, stackTrace) {
|
);
|
||||||
AppLogger.reportError(e, stackTrace);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bytes: bytes, response: res);
|
return (bytes: bytes, response: res);
|
||||||
|
|||||||
@ -306,8 +306,6 @@ class SourcedTrack extends BasicSourcedTrack {
|
|||||||
SpotubeAudioSourceContainerPreset preset,
|
SpotubeAudioSourceContainerPreset preset,
|
||||||
int qualityIndex,
|
int qualityIndex,
|
||||||
) {
|
) {
|
||||||
if (sources.isEmpty) return null;
|
|
||||||
|
|
||||||
final quality = preset.qualities[qualityIndex];
|
final quality = preset.qualities[qualityIndex];
|
||||||
|
|
||||||
final exactMatch = sources.firstWhereOrNull(
|
final exactMatch = sources.firstWhereOrNull(
|
||||||
@ -319,7 +317,7 @@ class SourcedTrack extends BasicSourcedTrack {
|
|||||||
source.bitDepth == quality.bitDepth;
|
source.bitDepth == quality.bitDepth;
|
||||||
} else {
|
} else {
|
||||||
return source.bitrate ==
|
return source.bitrate ==
|
||||||
(quality as SpotubeAudioLossyContainerQuality).bitrate;
|
(preset as SpotubeAudioLossyContainerQuality).bitrate;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -328,24 +326,45 @@ class SourcedTrack extends BasicSourcedTrack {
|
|||||||
return exactMatch;
|
return exactMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the preset with closest quality to the supplied quality
|
// Find the closest to preset
|
||||||
return sources.where((source) {
|
SpotubeAudioSourceStreamObject? closest;
|
||||||
return source.container == preset.name;
|
for (final source in sources) {
|
||||||
}).reduce((prev, curr) {
|
if (source.container != preset.name) continue;
|
||||||
if (quality is SpotubeAudioLosslessContainerQuality) {
|
|
||||||
final prevDiff = ((prev.sampleRate ?? 0) - quality.sampleRate).abs() +
|
if (quality case SpotubeAudioLosslessContainerQuality()) {
|
||||||
((prev.bitDepth ?? 0) - quality.bitDepth).abs();
|
final sourceBps = (source.bitDepth ?? 0) * (source.sampleRate ?? 0);
|
||||||
final currDiff = ((curr.sampleRate ?? 0) - quality.sampleRate).abs() +
|
final qualityBps = quality.bitDepth * quality.sampleRate;
|
||||||
((curr.bitDepth ?? 0) - quality.bitDepth).abs();
|
final closestBps =
|
||||||
return currDiff < prevDiff ? curr : prev;
|
(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 {
|
} else {
|
||||||
final prevDiff = ((prev.bitrate ?? 0) -
|
final presetBitrate =
|
||||||
(quality as SpotubeAudioLossyContainerQuality).bitrate)
|
(preset as SpotubeAudioLossyContainerQuality).bitrate;
|
||||||
.abs();
|
if (presetBitrate == source.bitrate) {
|
||||||
final currDiff = ((curr.bitrate ?? 0) - quality.bitrate).abs();
|
closest = source;
|
||||||
return currDiff < prevDiff ? curr : prev;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final closestDiff = (closest?.bitrate ?? 0) - presetBitrate;
|
||||||
|
final sourceDiff = (source.bitrate ?? 0) - presetBitrate;
|
||||||
|
|
||||||
|
if (sourceDiff < closestDiff) {
|
||||||
|
closest = source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getUrlOfQuality(
|
String? getUrlOfQuality(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user