From dd29c3e1a60e2db6ea4051c463072330008a2520 Mon Sep 17 00:00:00 2001 From: snylonue Date: Mon, 22 Apr 2024 22:51:42 +0800 Subject: [PATCH 1/6] use anni-player Basically a wrapper of anni-playback with additional functionality. --- lib/native/api/player.dart | 23 +- lib/native/frb_generated.dart | 182 ++++- lib/services/path.dart | 1 + lib/services/playback/playback_service.dart | 61 +- rust/Cargo.lock | 716 +++++++++++++++++++- rust/Cargo.toml | 8 +- rust/src/api/player.rs | 28 +- rust/src/frb_generated.rs | 197 +++++- 8 files changed, 1099 insertions(+), 117 deletions(-) diff --git a/lib/native/api/player.dart b/lib/native/api/player.dart index 18d7f25b..dde3620b 100644 --- a/lib/native/api/player.dart +++ b/lib/native/api/player.dart @@ -24,11 +24,26 @@ class AnnixPlayer extends RustOpaque { RustLib.instance.api.rust_arc_decrement_strong_count_AnnixPlayerPtr, ); + Future addProvider( + {required String url, + required String auth, + required int priority, + dynamic hint}) => + RustLib.instance.api.annixPlayerAddProvider( + that: this, url: url, auth: auth, priority: priority, hint: hint); + + Future clearProvider({dynamic hint}) => + RustLib.instance.api.annixPlayerClearProvider(that: this, hint: hint); + bool isPlaying({dynamic hint}) => RustLib.instance.api.annixPlayerIsPlaying(that: this, hint: hint); - factory AnnixPlayer({dynamic hint}) => - RustLib.instance.api.annixPlayerNew(hint: hint); + factory AnnixPlayer({required String cachePath, dynamic hint}) => + RustLib.instance.api.annixPlayerNew(cachePath: cachePath, hint: hint); + + Future open({required String identifier, dynamic hint}) => + RustLib.instance.api + .annixPlayerOpen(that: this, identifier: identifier, hint: hint); Future openFile({required String path, dynamic hint}) => RustLib.instance.api @@ -50,6 +65,10 @@ class AnnixPlayer extends RustOpaque { RustLib.instance.api .annixPlayerSeek(that: this, position: position, hint: hint); + Future setTrack({required String identifier, dynamic hint}) => + RustLib.instance.api + .annixPlayerSetTrack(that: this, identifier: identifier, hint: hint); + Future setVolume({required double volume, dynamic hint}) => RustLib.instance.api .annixPlayerSetVolume(that: this, volume: volume, hint: hint); diff --git a/lib/native/frb_generated.dart b/lib/native/frb_generated.dart index 69dad968..5fc6f61e 100644 --- a/lib/native/frb_generated.dart +++ b/lib/native/frb_generated.dart @@ -57,7 +57,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.0.0-dev.32'; @override - int get rustContentHash => -247829632; + int get rustContentHash => -1027124093; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -73,9 +73,22 @@ abstract class RustLibApi extends BaseApi { Future updateNetworkStatus({required bool isOnline, dynamic hint}); + Future annixPlayerAddProvider( + {required AnnixPlayer that, + required String url, + required String auth, + required int priority, + dynamic hint}); + + Future annixPlayerClearProvider( + {required AnnixPlayer that, dynamic hint}); + bool annixPlayerIsPlaying({required AnnixPlayer that, dynamic hint}); - AnnixPlayer annixPlayerNew({dynamic hint}); + AnnixPlayer annixPlayerNew({required String cachePath, dynamic hint}); + + Future annixPlayerOpen( + {required AnnixPlayer that, required String identifier, dynamic hint}); Future annixPlayerOpenFile( {required AnnixPlayer that, required String path, dynamic hint}); @@ -93,6 +106,9 @@ abstract class RustLibApi extends BaseApi { Future annixPlayerSeek( {required AnnixPlayer that, required int position, dynamic hint}); + Future annixPlayerSetTrack( + {required AnnixPlayer that, required String identifier, dynamic hint}); + Future annixPlayerSetVolume( {required AnnixPlayer that, required double volume, dynamic hint}); @@ -235,6 +251,67 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["isOnline"], ); + @override + Future annixPlayerAddProvider( + {required AnnixPlayer that, + required String url, + required String auth, + required int priority, + dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( + that, serializer); + sse_encode_String(url, serializer); + sse_encode_String(auth, serializer); + sse_encode_i_32(priority, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 13, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: kAnnixPlayerAddProviderConstMeta, + argValues: [that, url, auth, priority], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kAnnixPlayerAddProviderConstMeta => const TaskConstMeta( + debugName: "AnnixPlayer_add_provider", + argNames: ["that", "url", "auth", "priority"], + ); + + @override + Future annixPlayerClearProvider( + {required AnnixPlayer that, dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( + that, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 14, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: kAnnixPlayerClearProviderConstMeta, + argValues: [that], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kAnnixPlayerClearProviderConstMeta => const TaskConstMeta( + debugName: "AnnixPlayer_clear_provider", + argNames: ["that"], + ); + @override bool annixPlayerIsPlaying({required AnnixPlayer that, dynamic hint}) { return handler.executeSync(SyncTask( @@ -242,7 +319,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( that, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 10)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 12)!; }, codec: SseCodec( decodeSuccessData: sse_decode_bool, @@ -261,10 +338,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - AnnixPlayer annixPlayerNew({dynamic hint}) { + AnnixPlayer annixPlayerNew({required String cachePath, dynamic hint}) { return handler.executeSync(SyncTask( callFfi: () { final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_String(cachePath, serializer); return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 3)!; }, codec: SseCodec( @@ -273,7 +351,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeErrorData: null, ), constMeta: kAnnixPlayerNewConstMeta, - argValues: [], + argValues: [cachePath], apiImpl: this, hint: hint, )); @@ -281,7 +359,35 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { TaskConstMeta get kAnnixPlayerNewConstMeta => const TaskConstMeta( debugName: "AnnixPlayer_new", - argNames: [], + argNames: ["cachePath"], + ); + + @override + Future annixPlayerOpen( + {required AnnixPlayer that, required String identifier, dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( + that, serializer); + sse_encode_String(identifier, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 7, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kAnnixPlayerOpenConstMeta, + argValues: [that, identifier], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kAnnixPlayerOpenConstMeta => const TaskConstMeta( + debugName: "AnnixPlayer_open", + argNames: ["that", "identifier"], ); @override @@ -375,7 +481,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer); sse_encode_StreamSink_player_state_event_Sse(stream, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 11, port: port_); + funcId: 15, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -406,7 +512,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer); sse_encode_StreamSink_progress_state_Sse(stream, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 12, port: port_); + funcId: 16, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -435,7 +541,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer); sse_encode_u_64(position, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 9, port: port_); + funcId: 11, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -453,6 +559,34 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["that", "position"], ); + @override + Future annixPlayerSetTrack( + {required AnnixPlayer that, required String identifier, dynamic hint}) { + return handler.executeNormal(NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( + that, serializer); + sse_encode_String(identifier, serializer); + pdeCallFfi(generalizedFrbRustBinding, serializer, + funcId: 8, port: port_); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kAnnixPlayerSetTrackConstMeta, + argValues: [that, identifier], + apiImpl: this, + hint: hint, + )); + } + + TaskConstMeta get kAnnixPlayerSetTrackConstMeta => const TaskConstMeta( + debugName: "AnnixPlayer_set_track", + argNames: ["that", "identifier"], + ); + @override Future annixPlayerSetVolume( {required AnnixPlayer that, required double volume, dynamic hint}) { @@ -463,7 +597,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer); sse_encode_f_32(volume, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 7, port: port_); + funcId: 9, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -489,7 +623,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( that, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 8, port: port_); + funcId: 10, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -516,7 +650,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_box_autoadd_local_db(that, serializer); sse_encode_Uuid(albumId, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 19, port: port_); + funcId: 23, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -547,7 +681,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_String(tag, serializer); sse_encode_bool(recursive, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 20, port: port_); + funcId: 24, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_list_Uuid, @@ -572,7 +706,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_box_autoadd_local_db(that, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 21, port: port_); + funcId: 25, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_list_tag_item, @@ -597,7 +731,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_String(path, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 18, port: port_); + funcId: 22, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_local_db, @@ -624,7 +758,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_box_autoadd_local_store(that, serializer); sse_encode_opt_String(category, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 25, port: port_); + funcId: 29, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -655,7 +789,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_String(category, serializer); sse_encode_String(key, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 24, port: port_); + funcId: 28, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -688,7 +822,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_String(key, serializer); sse_encode_String(value, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, - funcId: 23, port: port_); + funcId: 27, port: port_); }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -712,7 +846,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { callFfi: () { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_String(root, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 22)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 26)!; }, codec: SseCodec( decodeSuccessData: sse_decode_local_store, @@ -740,7 +874,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_box_autoadd_native_preference_store(that, serializer); sse_encode_String(key, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 14)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 18)!; }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -765,7 +899,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { callFfi: () { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_String(root, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 13)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 17)!; }, codec: SseCodec( decodeSuccessData: sse_decode_native_preference_store, @@ -793,7 +927,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_box_autoadd_native_preference_store(that, serializer); sse_encode_String(key, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 16)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 20)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -822,7 +956,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_box_autoadd_native_preference_store(that, serializer); sse_encode_String(prefix, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 17)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 21)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -853,7 +987,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_box_autoadd_native_preference_store(that, serializer); sse_encode_String(key, serializer); sse_encode_String(value, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 15)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 19)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, diff --git a/lib/services/path.dart b/lib/services/path.dart index f2570f1a..663d6227 100644 --- a/lib/services/path.dart +++ b/lib/services/path.dart @@ -41,4 +41,5 @@ class PathService { String localDbPath() => p.join(PathService.dataRoot, 'local.db'); String audioCachePath() => p.join(PathService.storageRoot, 'audio'); +String playerCachePath() => p.join(PathService.storageRoot, 'audio_cache'); String coverCachePath() => p.join(PathService.storageRoot, 'cover'); diff --git a/lib/services/playback/playback_service.dart b/lib/services/playback/playback_service.dart index 71b84f07..185f4172 100644 --- a/lib/services/playback/playback_service.dart +++ b/lib/services/playback/playback_service.dart @@ -7,6 +7,7 @@ import 'package:annix/services/annil/annil.dart'; import 'package:annix/services/anniv/anniv.dart'; import 'package:annix/services/anniv/anniv_model.dart'; import 'package:annix/services/metadata/metadata_model.dart'; +import 'package:annix/services/path.dart'; import 'package:annix/services/playback/playback.dart'; import 'package:annix/native/api/player.dart'; import 'package:annix/ui/widgets/utils/property_value_notifier.dart'; @@ -41,7 +42,7 @@ void playFullList({ } class PlaybackService extends ChangeNotifier { - static final AnnixPlayer player = AnnixPlayer(); + static final AnnixPlayer player = AnnixPlayer(cachePath: playerCachePath()); // TODO: cache this map static final PropertyValueNotifier> durationMap = @@ -128,6 +129,16 @@ class PlaybackService extends ChangeNotifier { WidgetsBinding.instance.addPostFrameCallback((final _) => play(reload: true, setSourceOnly: true, trackPlayback: false)); + + final db = ref.read(localDatabaseProvider); + final annilServersStream = db.sortedAnnilServers().watch(); + annilServersStream.listen((servers) { + PlaybackService.player.clearProvider(); + for (final server in servers) { + PlaybackService.player.addProvider( + url: server.url, auth: server.token, priority: server.priority); + } + }); } Future play({ @@ -166,7 +177,6 @@ class PlaybackService extends ChangeNotifier { await stop(); return; } - final currentIndex = playingIndex!; // stop previous playback FLog.trace(text: 'Start playing'); @@ -183,47 +193,18 @@ class PlaybackService extends ChangeNotifier { ); } } + await PlaybackService.player + .setTrack(identifier: source.identifier.toString()); - final toPlayId = source.id; - if (!source.preloaded) { - // current track is not preloaded, buffering - playerStatus = PlayerStatus.buffering; - notifyListeners(); - } - - // preload the next track - if (queue.length > currentIndex + 1) { - queue[currentIndex + 1].preload(ref); - } - - try { - source.preload(ref); - // wait for audio file to download and play it - source.setOnPlayer(PlaybackService.player); - if (setSourceOnly) { - loadedAndPaused = true; - } else { - await PlaybackService.player.play(); - } - } catch (e) { - if (e is AudioCancelledError) { - return; - } - - // TODO: tell user why paused - FLog.error(text: 'Failed to play', exception: e); - await pause(); + if (setSourceOnly) { + loadedAndPaused = true; + playerStatus = PlayerStatus.paused; + } else { + await PlaybackService.player.play(); + playerStatus = PlayerStatus.playing; } - // when playback starts, set state to playing - if (playing.id == toPlayId && playerStatus == PlayerStatus.buffering) { - if (setSourceOnly) { - playerStatus = PlayerStatus.paused; - } else { - playerStatus = PlayerStatus.playing; - } - notifyListeners(); - } + notifyListeners(); } Future pause() async { diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 23fc4326..87ecfea4 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -77,6 +77,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_log-sys" version = "0.3.1" @@ -90,11 +96,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f" dependencies = [ "android_log-sys", - "env_logger", + "env_logger 0.10.1", "log", "once_cell", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anni-artist" version = "0.1.1" @@ -121,10 +136,44 @@ dependencies = [ "thiserror", ] +[[package]] +name = "anni-common" +version = "0.1.4" +source = "git+https://github.com/ProjectAnni/anni#9207e60bb864bc4a924f1d313454504c0c61f3b7" +dependencies = [ + "anni-artist", + "byteorder", + "chardetng", + "encoding_rs", + "log", + "once_cell", + "path-absolutize", + "pathdiff", + "regex", + "serde", + "serde_json", + "thiserror", + "trash", +] + +[[package]] +name = "anni-flac" +version = "0.2.2" +source = "git+https://github.com/ProjectAnni/anni#9207e60bb864bc4a924f1d313454504c0c61f3b7" +dependencies = [ + "async-trait", + "byteorder", + "hex", + "image", + "log", + "thiserror", + "tokio", +] + [[package]] name = "anni-playback" version = "0.1.0" -source = "git+https://github.com/ProjectAnni/anni#9207e60bb864bc4a924f1d313454504c0c61f3b7" +source = "git+https://github.com/ProjectAnni/anni?rev=9207e60#9207e60bb864bc4a924f1d313454504c0c61f3b7" dependencies = [ "anyhow", "arrayvec", @@ -137,8 +186,44 @@ dependencies = [ "rangemap", "reqwest", "rubato", - "symphonia", - "symphonia-core", + "symphonia 0.5.2", + "symphonia-core 0.5.2", +] + +[[package]] +name = "anni-player" +version = "0.1.0" +source = "git+https://github.com/snylonue/anni-player?rev=4218e2c#4218e2ce74cbc2d51c65159577fdf2bc9a0dd586" +dependencies = [ + "anni-playback", + "anni-provider", + "anyhow", + "env_logger 0.10.1", + "log", + "once_cell", + "reqwest", + "symphonia 0.5.4", + "uuid", +] + +[[package]] +name = "anni-provider" +version = "0.3.0" +source = "git+https://github.com/ProjectAnni/anni#9207e60bb864bc4a924f1d313454504c0c61f3b7" +dependencies = [ + "anni-common 0.1.4 (git+https://github.com/ProjectAnni/anni)", + "anni-flac", + "async-trait", + "dashmap 5.5.3", + "futures", + "log", + "lru", + "parking_lot", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "uuid", ] [[package]] @@ -148,7 +233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0d76f32d2c9f30c0b756bf09776904170881369cd6b2bf664a21987f616cb1f" dependencies = [ "anni-artist", - "anni-common", + "anni-common 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.9.3", "log", "once_cell", @@ -164,6 +249,54 @@ dependencies = [ "uuid", ] +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.75" @@ -179,6 +312,17 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-trait" +version = "0.1.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atomic" version = "0.5.3" @@ -250,6 +394,12 @@ dependencies = [ "syn", ] +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -334,6 +484,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets 0.52.4", +] + [[package]] name = "clang-sys" version = "1.7.0" @@ -354,6 +516,18 @@ dependencies = [ "cc", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "combine" version = "4.6.6" @@ -430,7 +604,16 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows", + "windows 0.54.0", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", ] [[package]] @@ -489,6 +672,12 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "dart-sys-fork" version = "4.1.1" @@ -508,6 +697,19 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "dasp_frame" version = "0.11.0" @@ -561,14 +763,40 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ + "humantime", + "is-terminal", "log", "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", ] [[package]] @@ -577,6 +805,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -589,6 +833,34 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "flutter_rust_bridge" version = "2.0.0-dev.32" @@ -743,6 +1015,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.28.1" @@ -774,6 +1056,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -845,6 +1137,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.28" @@ -883,6 +1181,29 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.5.0" @@ -893,6 +1214,24 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -919,6 +1258,17 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "itertools" version = "0.12.1" @@ -965,6 +1315,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.69" @@ -986,6 +1345,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.150" @@ -1013,12 +1378,31 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.3", +] + [[package]] name = "mach2" version = "0.4.2" @@ -1028,6 +1412,15 @@ dependencies = [ "libc", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.6.4" @@ -1053,6 +1446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -1174,6 +1568,15 @@ dependencies = [ "syn", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "object" version = "0.32.1" @@ -1219,10 +1622,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8343ce955f18e7e68c0207dd0ea776ec453035685395ababd2ea651c569728b3" dependencies = [ "cc", - "dashmap", + "dashmap 4.0.2", "log", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "path-absolutize" version = "3.1.1" @@ -1271,6 +1697,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1304,6 +1743,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + [[package]] name = "quote" version = "1.0.33" @@ -1349,6 +1797,26 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "realfft" version = "3.3.0" @@ -1358,6 +1826,15 @@ dependencies = [ "rustfft", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.10.2" @@ -1476,10 +1953,12 @@ name = "rust_lib_annix" version = "0.1.0" dependencies = [ "anni-playback", + "anni-player", "anni-repo", "anyhow", "cpal", "crossbeam", + "env_logger 0.11.2", "flutter_rust_bridge", "log", "once_cell", @@ -1561,6 +2040,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sct" version = "0.7.1" @@ -1639,6 +2124,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.9" @@ -1669,6 +2160,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "strength_reduce" @@ -1682,11 +2176,25 @@ version = "0.5.2" source = "git+https://github.com/erikas-taroza/Symphonia?branch=mp4-opus-improvements#bb1314974788c1f0b74e7876fa644bf070a23e37" dependencies = [ "lazy_static", - "symphonia-bundle-flac", - "symphonia-codec-aac", - "symphonia-core", - "symphonia-format-ogg", - "symphonia-metadata", + "symphonia-bundle-flac 0.5.2", + "symphonia-codec-aac 0.5.2", + "symphonia-core 0.5.2", + "symphonia-format-ogg 0.5.2", + "symphonia-metadata 0.5.2", +] + +[[package]] +name = "symphonia" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" +dependencies = [ + "lazy_static", + "symphonia-bundle-flac 0.5.4", + "symphonia-codec-aac 0.5.4", + "symphonia-core 0.5.4", + "symphonia-format-ogg 0.5.4", + "symphonia-metadata 0.5.4", ] [[package]] @@ -1695,9 +2203,21 @@ version = "0.5.2" source = "git+https://github.com/erikas-taroza/Symphonia?branch=mp4-opus-improvements#bb1314974788c1f0b74e7876fa644bf070a23e37" dependencies = [ "log", - "symphonia-core", - "symphonia-metadata", - "symphonia-utils-xiph", + "symphonia-core 0.5.2", + "symphonia-metadata 0.5.2", + "symphonia-utils-xiph 0.5.2", +] + +[[package]] +name = "symphonia-bundle-flac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97" +dependencies = [ + "log", + "symphonia-core 0.5.4", + "symphonia-metadata 0.5.4", + "symphonia-utils-xiph 0.5.4", ] [[package]] @@ -1707,7 +2227,18 @@ source = "git+https://github.com/erikas-taroza/Symphonia?branch=mp4-opus-improve dependencies = [ "lazy_static", "log", - "symphonia-core", + "symphonia-core 0.5.2", +] + +[[package]] +name = "symphonia-codec-aac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbf25b545ad0d3ee3e891ea643ad115aff4ca92f6aec472086b957a58522f70" +dependencies = [ + "lazy_static", + "log", + "symphonia-core 0.5.4", ] [[package]] @@ -1722,15 +2253,40 @@ dependencies = [ "log", ] +[[package]] +name = "symphonia-core" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + [[package]] name = "symphonia-format-ogg" version = "0.5.2" source = "git+https://github.com/erikas-taroza/Symphonia?branch=mp4-opus-improvements#bb1314974788c1f0b74e7876fa644bf070a23e37" dependencies = [ "log", - "symphonia-core", - "symphonia-metadata", - "symphonia-utils-xiph", + "symphonia-core 0.5.2", + "symphonia-metadata 0.5.2", + "symphonia-utils-xiph 0.5.2", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931" +dependencies = [ + "log", + "symphonia-core 0.5.4", + "symphonia-metadata 0.5.4", + "symphonia-utils-xiph 0.5.4", ] [[package]] @@ -1741,7 +2297,19 @@ dependencies = [ "encoding_rs", "lazy_static", "log", - "symphonia-core", + "symphonia-core 0.5.2", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core 0.5.4", ] [[package]] @@ -1749,8 +2317,18 @@ name = "symphonia-utils-xiph" version = "0.5.2" source = "git+https://github.com/erikas-taroza/Symphonia?branch=mp4-opus-improvements#bb1314974788c1f0b74e7876fa644bf070a23e37" dependencies = [ - "symphonia-core", - "symphonia-metadata", + "symphonia-core 0.5.2", + "symphonia-metadata 0.5.2", +] + +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe" +dependencies = [ + "symphonia-core 0.5.4", + "symphonia-metadata 0.5.4", ] [[package]] @@ -1791,6 +2369,15 @@ dependencies = [ "libc", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.55" @@ -1820,6 +2407,17 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1861,6 +2459,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -1869,6 +2478,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -1955,6 +2565,22 @@ dependencies = [ "strength_reduce", ] +[[package]] +name = "trash" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c658458d46d9d5a153a3b5cdd88d8579ad50d4fb85d53961e4526c8fc7c55a57" +dependencies = [ + "chrono", + "libc", + "log", + "objc", + "once_cell", + "scopeguard", + "url", + "windows 0.44.0", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -1999,6 +2625,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uuid" version = "1.7.0" @@ -2128,6 +2760,12 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "winapi" version = "0.3.9" @@ -2159,13 +2797,31 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows" version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ - "windows-core", + "windows-core 0.54.0", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ "windows-targets 0.52.4", ] @@ -2424,3 +3080,17 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[patch.unused]] +name = "cpal" +version = "0.15.2" +source = "git+https://github.com/sidit77/cpal.git?branch=master#7e82d99bfaa8036cf6e7c7d214254014ad050139" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index f1eaddbb..53094d50 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -17,7 +17,13 @@ uuid = "1" crossbeam = { version = "0.8.2", features = ["crossbeam-channel"] } anyhow = "1.0.75" log = "0.4.20" +env_logger = "0.11" -anni-playback = { git = "https://github.com/ProjectAnni/anni" } +anni-playback = { git = "https://github.com/ProjectAnni/anni", rev = "9207e60" } +anni-player = { git = "https://github.com/snylonue/anni-player", rev = "4218e2c" } cpal = { version = "0.15.3", features = ["oboe-shared-stdcxx"] } rand = "0.8.5" + +[patch.crates-io] +cpal = { git = "https://github.com/sidit77/cpal.git", branch = "master" } + diff --git a/rust/src/api/player.rs b/rust/src/api/player.rs index 27391821..dad67945 100644 --- a/rust/src/api/player.rs +++ b/rust/src/api/player.rs @@ -4,10 +4,10 @@ use std::{ }; use anni_playback::types::PlayerEvent; +use anni_player::{AnniPlayer, TypedPriorityProvider}; use flutter_rust_bridge::{frb, RustOpaqueNom}; use crate::frb_generated::StreamSink; -use crate::player::player::Player; pub enum PlayerStateEvent { /// Started playing @@ -48,15 +48,15 @@ pub type StreamWrapper = Arc>>>>; #[frb(opaque)] pub struct AnnixPlayer { - player: Player, + player: AnniPlayer, _state: StreamWrapper, _progress: RustOpaqueNom>, } impl AnnixPlayer { #[frb(sync)] - pub fn new() -> AnnixPlayer { - let (player, receiver) = Player::new(); + pub fn new(cache_path: String) -> AnnixPlayer { + let (player, receiver) = AnniPlayer::new(TypedPriorityProvider::new(vec![]), cache_path.into()); let progress = Arc::new(OnceLock::new()); let player_state = Arc::new(OnceLock::new()); @@ -106,7 +106,15 @@ impl AnnixPlayer { } pub fn open_file(&self, path: String) -> anyhow::Result<()> { - self.player.open_file(path, false) + self.player.open_file(path) + } + + pub fn open(&self, identifier: String) -> anyhow::Result<()> { + self.player.open(identifier.parse()?) + } + + pub fn set_track(&self, identifier: String) -> anyhow::Result<()> { + self.player.set_track(identifier.parse()?) } pub fn set_volume(&self, volume: f32) { @@ -123,7 +131,15 @@ impl AnnixPlayer { #[frb(sync)] pub fn is_playing(&self) -> bool { - self.player.is_playing() + self.player.player.is_playing() + } + + pub fn add_provider(&self, url: String, auth: String, priority: i32) { + self.player.add_provider(url, auth, priority); + } + + pub fn clear_provider(&self) { + self.player.clear_provider(); } pub fn player_state_stream(&self, stream: StreamSink) { diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index c066654f..40c967a1 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -33,7 +33,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0-dev.32"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -247829632; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -1027124093; // Section: executor @@ -105,6 +105,84 @@ fn wire_update_network_status_impl( }, ) } +fn wire_AnnixPlayer_add_provider_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "AnnixPlayer_add_provider", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_url = ::sse_decode(&mut deserializer); + let api_auth = ::sse_decode(&mut deserializer); + let api_priority = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse((move || { + let api_that = api_that.rust_auto_opaque_decode_ref(); + Result::<_, ()>::Ok(crate::api::player::AnnixPlayer::add_provider( + &api_that, + api_url, + api_auth, + api_priority, + )) + })()) + } + }, + ) +} +fn wire_AnnixPlayer_clear_provider_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "AnnixPlayer_clear_provider", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse((move || { + let api_that = api_that.rust_auto_opaque_decode_ref(); + Result::<_, ()>::Ok(crate::api::player::AnnixPlayer::clear_provider(&api_that)) + })()) + } + }, + ) +} fn wire_AnnixPlayer_is_playing_impl( ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -158,13 +236,50 @@ fn wire_AnnixPlayer_new_impl( }; let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_cache_path = ::sse_decode(&mut deserializer); deserializer.end(); transform_result_sse((move || { - Result::<_, ()>::Ok(crate::api::player::AnnixPlayer::new()) + Result::<_, ()>::Ok(crate::api::player::AnnixPlayer::new(api_cache_path)) })()) }, ) } +fn wire_AnnixPlayer_open_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "AnnixPlayer_open", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_identifier = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse((move || { + let api_that = api_that.rust_auto_opaque_decode_ref(); + crate::api::player::AnnixPlayer::open(&api_that, api_identifier) + })()) + } + }, + ) +} fn wire_AnnixPlayer_open_file_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -392,6 +507,42 @@ fn wire_AnnixPlayer_seek_impl( }, ) } +fn wire_AnnixPlayer_set_track_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "AnnixPlayer_set_track", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_identifier = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| { + transform_result_sse((move || { + let api_that = api_that.rust_auto_opaque_decode_ref(); + crate::api::player::AnnixPlayer::set_track(&api_that, api_identifier) + })()) + } + }, + ) +} fn wire_AnnixPlayer_set_volume_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -1191,21 +1342,25 @@ fn pde_ffi_dispatcher_primary_impl( match func_id { 2 => wire_network_status_is_online_impl(port, ptr, rust_vec_len, data_len), 1 => wire_update_network_status_impl(port, ptr, rust_vec_len, data_len), + 13 => wire_AnnixPlayer_add_provider_impl(port, ptr, rust_vec_len, data_len), + 14 => wire_AnnixPlayer_clear_provider_impl(port, ptr, rust_vec_len, data_len), + 7 => wire_AnnixPlayer_open_impl(port, ptr, rust_vec_len, data_len), 6 => wire_AnnixPlayer_open_file_impl(port, ptr, rust_vec_len, data_len), 5 => wire_AnnixPlayer_pause_impl(port, ptr, rust_vec_len, data_len), 4 => wire_AnnixPlayer_play_impl(port, ptr, rust_vec_len, data_len), - 11 => wire_AnnixPlayer_player_state_stream_impl(port, ptr, rust_vec_len, data_len), - 12 => wire_AnnixPlayer_progress_stream_impl(port, ptr, rust_vec_len, data_len), - 9 => wire_AnnixPlayer_seek_impl(port, ptr, rust_vec_len, data_len), - 7 => wire_AnnixPlayer_set_volume_impl(port, ptr, rust_vec_len, data_len), - 8 => wire_AnnixPlayer_stop_impl(port, ptr, rust_vec_len, data_len), - 19 => wire_local_db_get_album_impl(port, ptr, rust_vec_len, data_len), - 20 => wire_local_db_get_albums_by_tag_impl(port, ptr, rust_vec_len, data_len), - 21 => wire_local_db_get_tags_impl(port, ptr, rust_vec_len, data_len), - 18 => wire_local_db_new_impl(port, ptr, rust_vec_len, data_len), - 25 => wire_local_store_clear_impl(port, ptr, rust_vec_len, data_len), - 24 => wire_local_store_get_impl(port, ptr, rust_vec_len, data_len), - 23 => wire_local_store_insert_impl(port, ptr, rust_vec_len, data_len), + 15 => wire_AnnixPlayer_player_state_stream_impl(port, ptr, rust_vec_len, data_len), + 16 => wire_AnnixPlayer_progress_stream_impl(port, ptr, rust_vec_len, data_len), + 11 => wire_AnnixPlayer_seek_impl(port, ptr, rust_vec_len, data_len), + 8 => wire_AnnixPlayer_set_track_impl(port, ptr, rust_vec_len, data_len), + 9 => wire_AnnixPlayer_set_volume_impl(port, ptr, rust_vec_len, data_len), + 10 => wire_AnnixPlayer_stop_impl(port, ptr, rust_vec_len, data_len), + 23 => wire_local_db_get_album_impl(port, ptr, rust_vec_len, data_len), + 24 => wire_local_db_get_albums_by_tag_impl(port, ptr, rust_vec_len, data_len), + 25 => wire_local_db_get_tags_impl(port, ptr, rust_vec_len, data_len), + 22 => wire_local_db_new_impl(port, ptr, rust_vec_len, data_len), + 29 => wire_local_store_clear_impl(port, ptr, rust_vec_len, data_len), + 28 => wire_local_store_get_impl(port, ptr, rust_vec_len, data_len), + 27 => wire_local_store_insert_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -1218,14 +1373,14 @@ fn pde_ffi_dispatcher_sync_impl( ) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { // Codec=Pde (Serialization + dispatch), see doc to use other codecs match func_id { - 10 => wire_AnnixPlayer_is_playing_impl(ptr, rust_vec_len, data_len), + 12 => wire_AnnixPlayer_is_playing_impl(ptr, rust_vec_len, data_len), 3 => wire_AnnixPlayer_new_impl(ptr, rust_vec_len, data_len), - 22 => wire_local_store_new_impl(ptr, rust_vec_len, data_len), - 14 => wire_native_preference_store_get_impl(ptr, rust_vec_len, data_len), - 13 => wire_native_preference_store_new_impl(ptr, rust_vec_len, data_len), - 16 => wire_native_preference_store_remove_impl(ptr, rust_vec_len, data_len), - 17 => wire_native_preference_store_remove_prefix_impl(ptr, rust_vec_len, data_len), - 15 => wire_native_preference_store_set_impl(ptr, rust_vec_len, data_len), + 26 => wire_local_store_new_impl(ptr, rust_vec_len, data_len), + 18 => wire_native_preference_store_get_impl(ptr, rust_vec_len, data_len), + 17 => wire_native_preference_store_new_impl(ptr, rust_vec_len, data_len), + 20 => wire_native_preference_store_remove_impl(ptr, rust_vec_len, data_len), + 21 => wire_native_preference_store_remove_prefix_impl(ptr, rust_vec_len, data_len), + 19 => wire_native_preference_store_set_impl(ptr, rust_vec_len, data_len), _ => unreachable!(), } } From f962744cfab7c5df8c711ab05c4c5464e814b896 Mon Sep 17 00:00:00 2001 From: snylonue Date: Mon, 6 May 2024 13:35:16 +0800 Subject: [PATCH 2/6] support quality selection --- lib/native/api/player.dart | 26 +- lib/native/frb_generated.dart | 49 +++- lib/native/frb_generated.io.dart | 9 + lib/native/frb_generated.web.dart | 9 + lib/services/playback/playback_service.dart | 21 +- rust/Cargo.lock | 300 ++++++++++---------- rust/Cargo.toml | 2 +- rust/src/api/player.rs | 24 +- rust/src/frb_generated.rs | 64 ++++- 9 files changed, 334 insertions(+), 170 deletions(-) diff --git a/lib/native/api/player.dart b/lib/native/api/player.dart index dde3620b..d9387d97 100644 --- a/lib/native/api/player.dart +++ b/lib/native/api/player.dart @@ -41,9 +41,12 @@ class AnnixPlayer extends RustOpaque { factory AnnixPlayer({required String cachePath, dynamic hint}) => RustLib.instance.api.annixPlayerNew(cachePath: cachePath, hint: hint); - Future open({required String identifier, dynamic hint}) => - RustLib.instance.api - .annixPlayerOpen(that: this, identifier: identifier, hint: hint); + Future open( + {required String identifier, + required AudioQuality quality, + dynamic hint}) => + RustLib.instance.api.annixPlayerOpen( + that: this, identifier: identifier, quality: quality, hint: hint); Future openFile({required String path, dynamic hint}) => RustLib.instance.api @@ -65,9 +68,12 @@ class AnnixPlayer extends RustOpaque { RustLib.instance.api .annixPlayerSeek(that: this, position: position, hint: hint); - Future setTrack({required String identifier, dynamic hint}) => - RustLib.instance.api - .annixPlayerSetTrack(that: this, identifier: identifier, hint: hint); + Future setTrack( + {required String identifier, + required AudioQuality quality, + dynamic hint}) => + RustLib.instance.api.annixPlayerSetTrack( + that: this, identifier: identifier, quality: quality, hint: hint); Future setVolume({required double volume, dynamic hint}) => RustLib.instance.api @@ -77,6 +83,14 @@ class AnnixPlayer extends RustOpaque { RustLib.instance.api.annixPlayerStop(that: this, hint: hint); } +enum AudioQuality { + low, + medium, + high, + lossless, + ; +} + enum PlayerStateEvent { /// Started playing play, diff --git a/lib/native/frb_generated.dart b/lib/native/frb_generated.dart index 5fc6f61e..c7d6a600 100644 --- a/lib/native/frb_generated.dart +++ b/lib/native/frb_generated.dart @@ -88,7 +88,10 @@ abstract class RustLibApi extends BaseApi { AnnixPlayer annixPlayerNew({required String cachePath, dynamic hint}); Future annixPlayerOpen( - {required AnnixPlayer that, required String identifier, dynamic hint}); + {required AnnixPlayer that, + required String identifier, + required AudioQuality quality, + dynamic hint}); Future annixPlayerOpenFile( {required AnnixPlayer that, required String path, dynamic hint}); @@ -107,7 +110,10 @@ abstract class RustLibApi extends BaseApi { {required AnnixPlayer that, required int position, dynamic hint}); Future annixPlayerSetTrack( - {required AnnixPlayer that, required String identifier, dynamic hint}); + {required AnnixPlayer that, + required String identifier, + required AudioQuality quality, + dynamic hint}); Future annixPlayerSetVolume( {required AnnixPlayer that, required double volume, dynamic hint}); @@ -364,13 +370,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @override Future annixPlayerOpen( - {required AnnixPlayer that, required String identifier, dynamic hint}) { + {required AnnixPlayer that, + required String identifier, + required AudioQuality quality, + dynamic hint}) { return handler.executeNormal(NormalTask( callFfi: (port_) { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( that, serializer); sse_encode_String(identifier, serializer); + sse_encode_audio_quality(quality, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 7, port: port_); }, @@ -379,7 +389,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeErrorData: sse_decode_AnyhowException, ), constMeta: kAnnixPlayerOpenConstMeta, - argValues: [that, identifier], + argValues: [that, identifier, quality], apiImpl: this, hint: hint, )); @@ -387,7 +397,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { TaskConstMeta get kAnnixPlayerOpenConstMeta => const TaskConstMeta( debugName: "AnnixPlayer_open", - argNames: ["that", "identifier"], + argNames: ["that", "identifier", "quality"], ); @override @@ -561,13 +571,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @override Future annixPlayerSetTrack( - {required AnnixPlayer that, required String identifier, dynamic hint}) { + {required AnnixPlayer that, + required String identifier, + required AudioQuality quality, + dynamic hint}) { return handler.executeNormal(NormalTask( callFfi: (port_) { final serializer = SseSerializer(generalizedFrbRustBinding); sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedrust_asyncRwLockAnnixPlayer( that, serializer); sse_encode_String(identifier, serializer); + sse_encode_audio_quality(quality, serializer); pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 8, port: port_); }, @@ -576,7 +590,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeErrorData: sse_decode_AnyhowException, ), constMeta: kAnnixPlayerSetTrackConstMeta, - argValues: [that, identifier], + argValues: [that, identifier, quality], apiImpl: this, hint: hint, )); @@ -584,7 +598,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { TaskConstMeta get kAnnixPlayerSetTrackConstMeta => const TaskConstMeta( debugName: "AnnixPlayer_set_track", - argNames: ["that", "identifier"], + argNames: ["that", "identifier", "quality"], ); @override @@ -1098,6 +1112,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return UuidValue.fromByteList(dco_decode_list_prim_u_8_strict(raw)); } + @protected + AudioQuality dco_decode_audio_quality(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return AudioQuality.values[raw as int]; + } + @protected bool dco_decode_bool(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -1343,6 +1363,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return UuidValue.fromByteList(inner); } + @protected + AudioQuality sse_decode_audio_quality(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + var inner = sse_decode_i_32(deserializer); + return AudioQuality.values[inner]; + } + @protected bool sse_decode_bool(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -1590,6 +1617,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_list_prim_u_8_strict(self.toBytes(), serializer); } + @protected + void sse_encode_audio_quality(AudioQuality self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_i_32(self.index, serializer); + } + @protected void sse_encode_bool(bool self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs diff --git a/lib/native/frb_generated.io.dart b/lib/native/frb_generated.io.dart index 5ee5e80c..f925d2d0 100644 --- a/lib/native/frb_generated.io.dart +++ b/lib/native/frb_generated.io.dart @@ -72,6 +72,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected UuidValue dco_decode_Uuid(dynamic raw); + @protected + AudioQuality dco_decode_audio_quality(dynamic raw); + @protected bool dco_decode_bool(dynamic raw); @@ -179,6 +182,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected UuidValue sse_decode_Uuid(SseDeserializer deserializer); + @protected + AudioQuality sse_decode_audio_quality(SseDeserializer deserializer); + @protected bool sse_decode_bool(SseDeserializer deserializer); @@ -288,6 +294,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_Uuid(UuidValue self, SseSerializer serializer); + @protected + void sse_encode_audio_quality(AudioQuality self, SseSerializer serializer); + @protected void sse_encode_bool(bool self, SseSerializer serializer); diff --git a/lib/native/frb_generated.web.dart b/lib/native/frb_generated.web.dart index ac2d7909..539c68d9 100644 --- a/lib/native/frb_generated.web.dart +++ b/lib/native/frb_generated.web.dart @@ -71,6 +71,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected UuidValue dco_decode_Uuid(dynamic raw); + @protected + AudioQuality dco_decode_audio_quality(dynamic raw); + @protected bool dco_decode_bool(dynamic raw); @@ -178,6 +181,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected UuidValue sse_decode_Uuid(SseDeserializer deserializer); + @protected + AudioQuality sse_decode_audio_quality(SseDeserializer deserializer); + @protected bool sse_decode_bool(SseDeserializer deserializer); @@ -287,6 +293,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_Uuid(UuidValue self, SseSerializer serializer); + @protected + void sse_encode_audio_quality(AudioQuality self, SseSerializer serializer); + @protected void sse_encode_bool(bool self, SseSerializer serializer); diff --git a/lib/services/playback/playback_service.dart b/lib/services/playback/playback_service.dart index 185f4172..cce33da8 100644 --- a/lib/services/playback/playback_service.dart +++ b/lib/services/playback/playback_service.dart @@ -10,6 +10,7 @@ import 'package:annix/services/metadata/metadata_model.dart'; import 'package:annix/services/path.dart'; import 'package:annix/services/playback/playback.dart'; import 'package:annix/native/api/player.dart'; +import 'package:annix/services/settings.dart'; import 'package:annix/ui/widgets/utils/property_value_notifier.dart'; import 'package:audio_session/audio_session.dart' hide AVAudioSessionCategory; import 'package:f_logs/f_logs.dart'; @@ -41,6 +42,19 @@ void playFullList({ ); } +AudioQuality fromQuality(PreferQuality q) { + switch (q) { + case PreferQuality.low: + return AudioQuality.low; + case PreferQuality.medium: + return AudioQuality.medium; + case PreferQuality.high: + return AudioQuality.high; + case PreferQuality.lossless: + return AudioQuality.lossless; + } +} + class PlaybackService extends ChangeNotifier { static final AnnixPlayer player = AnnixPlayer(cachePath: playerCachePath()); @@ -193,8 +207,11 @@ class PlaybackService extends ChangeNotifier { ); } } - await PlaybackService.player - .setTrack(identifier: source.identifier.toString()); + + final settings = ref.read(settingsProvider); + await PlaybackService.player.setTrack( + identifier: source.identifier.toString(), + quality: fromQuality(settings.defaultAudioQuality.value)); if (setSourceOnly) { loadedAndPaused = true; diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 87ecfea4..ff07ef15 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alsa" @@ -63,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37fe60779335388a88c01ac6c3be40304d1e349de3ada3b15f7808bb90fa9dce" dependencies = [ "alsa-sys", - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", ] @@ -96,7 +96,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f" dependencies = [ "android_log-sys", - "env_logger 0.10.1", + "env_logger 0.10.2", "log", "once_cell", ] @@ -193,12 +193,12 @@ dependencies = [ [[package]] name = "anni-player" version = "0.1.0" -source = "git+https://github.com/snylonue/anni-player?rev=4218e2c#4218e2ce74cbc2d51c65159577fdf2bc9a0dd586" +source = "git+https://github.com/snylonue/anni-player?rev=d1d6fe6#d1d6fe6ba190c4845eb5f8a525390d34011fc950" dependencies = [ "anni-playback", "anni-provider", "anyhow", - "env_logger 0.10.1", + "env_logger 0.10.2", "log", "once_cell", "reqwest", @@ -299,9 +299,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" dependencies = [ "backtrace", ] @@ -314,9 +314,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" -version = "0.1.76" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", @@ -349,15 +349,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -380,7 +380,7 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cexpr", "clang-sys", "itertools", @@ -408,9 +408,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "build-target" @@ -420,15 +420,15 @@ checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" @@ -438,18 +438,19 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -493,7 +494,7 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -530,9 +531,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -750,15 +751,15 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -775,9 +776,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -788,9 +789,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ "anstream", "anstyle", @@ -917,9 +918,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -932,9 +933,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -942,15 +943,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -959,15 +960,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -976,21 +977,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1006,9 +1007,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -1049,7 +1050,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.5", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1093,9 +1094,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1244,9 +1245,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1280,9 +1281,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" @@ -1308,9 +1309,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -1353,9 +1354,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" @@ -1364,7 +1365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -1390,9 +1391,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru" @@ -1423,9 +1424,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -1441,9 +1442,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", "simd-adler32", @@ -1466,7 +1467,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "jni-sys", "log", "ndk-sys", @@ -1579,9 +1580,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -1611,9 +1612,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oslog" @@ -1681,9 +1682,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1736,9 +1737,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -1754,9 +1755,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1837,9 +1838,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -1849,9 +1850,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1860,9 +1861,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" @@ -1958,7 +1959,7 @@ dependencies = [ "anyhow", "cpal", "crossbeam", - "env_logger 0.11.2", + "env_logger 0.11.3", "flutter_rust_bridge", "log", "once_cell", @@ -2058,18 +2059,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", @@ -2078,9 +2079,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.109" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -2141,9 +2142,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -2333,9 +2334,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -2380,18 +2381,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.55" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.55" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", @@ -2435,9 +2436,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -2512,7 +2513,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -2525,7 +2526,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "toml_datetime", "winnow", ] @@ -2633,9 +2634,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", "serde", @@ -2746,9 +2747,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2813,7 +2814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ "windows-core 0.54.0", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2822,7 +2823,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2832,16 +2833,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" dependencies = [ "windows-result", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "windows-result" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" +checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2868,7 +2869,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2903,17 +2904,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -2930,9 +2932,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -2948,9 +2950,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -2966,9 +2968,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -2984,9 +2992,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -3002,9 +3010,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -3020,9 +3028,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -3038,9 +3046,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 53094d50..0b5bb9c4 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -20,7 +20,7 @@ log = "0.4.20" env_logger = "0.11" anni-playback = { git = "https://github.com/ProjectAnni/anni", rev = "9207e60" } -anni-player = { git = "https://github.com/snylonue/anni-player", rev = "4218e2c" } +anni-player = { git = "https://github.com/snylonue/anni-player", rev = "d1d6fe6" } cpal = { version = "0.15.3", features = ["oboe-shared-stdcxx"] } rand = "0.8.5" diff --git a/rust/src/api/player.rs b/rust/src/api/player.rs index dad67945..bf9622d2 100644 --- a/rust/src/api/player.rs +++ b/rust/src/api/player.rs @@ -1,5 +1,7 @@ +pub use anni_player::provider::AudioQuality; + use std::{ - sync::{Arc, OnceLock, RwLock}, + sync::{Arc, Once, OnceLock, RwLock}, thread, }; @@ -46,6 +48,14 @@ fn update_player_state_stream( pub type StreamWrapper = Arc>>>>; +#[frb(mirror(AudioQuality))] +pub enum _AudioQuality { + Low, + Medium, + High, + Lossless, +} + #[frb(opaque)] pub struct AnnixPlayer { player: AnniPlayer, @@ -56,6 +66,10 @@ pub struct AnnixPlayer { impl AnnixPlayer { #[frb(sync)] pub fn new(cache_path: String) -> AnnixPlayer { + static LOGGER: Once = Once::new(); + + LOGGER.call_once(|| env_logger::init()); + let (player, receiver) = AnniPlayer::new(TypedPriorityProvider::new(vec![]), cache_path.into()); let progress = Arc::new(OnceLock::new()); let player_state = Arc::new(OnceLock::new()); @@ -109,12 +123,12 @@ impl AnnixPlayer { self.player.open_file(path) } - pub fn open(&self, identifier: String) -> anyhow::Result<()> { - self.player.open(identifier.parse()?) + pub fn open(&self, identifier: String, quality: AudioQuality) -> anyhow::Result<()> { + self.player.open(identifier.parse()?, quality) } - pub fn set_track(&self, identifier: String) -> anyhow::Result<()> { - self.player.set_track(identifier.parse()?) + pub fn set_track(&self, identifier: String, quality: AudioQuality) -> anyhow::Result<()> { + self.player.load(identifier.parse()?, quality) } pub fn set_volume(&self, volume: f32) { diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index 40c967a1..b5b3ac39 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -270,11 +270,12 @@ fn wire_AnnixPlayer_open_impl( flutter_rust_bridge::for_generated::rust_async::RwLock, >>::sse_decode(&mut deserializer); let api_identifier = ::sse_decode(&mut deserializer); + let api_quality = ::sse_decode(&mut deserializer); deserializer.end(); move |context| { transform_result_sse((move || { let api_that = api_that.rust_auto_opaque_decode_ref(); - crate::api::player::AnnixPlayer::open(&api_that, api_identifier) + crate::api::player::AnnixPlayer::open(&api_that, api_identifier, api_quality) })()) } }, @@ -533,11 +534,16 @@ fn wire_AnnixPlayer_set_track_impl( flutter_rust_bridge::for_generated::rust_async::RwLock, >>::sse_decode(&mut deserializer); let api_identifier = ::sse_decode(&mut deserializer); + let api_quality = ::sse_decode(&mut deserializer); deserializer.end(); move |context| { transform_result_sse((move || { let api_that = api_that.rust_auto_opaque_decode_ref(); - crate::api::player::AnnixPlayer::set_track(&api_that, api_identifier) + crate::api::player::AnnixPlayer::set_track( + &api_that, + api_identifier, + api_quality, + ) })()) } }, @@ -1152,6 +1158,20 @@ impl SseDecode for uuid::Uuid { } } +impl SseDecode for crate::api::player::AudioQuality { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return match inner { + 0 => crate::api::player::AudioQuality::Low, + 1 => crate::api::player::AudioQuality::Medium, + 2 => crate::api::player::AudioQuality::High, + 3 => crate::api::player::AudioQuality::Lossless, + _ => unreachable!("Invalid variant for AudioQuality: {}", inner), + }; + } +} + impl SseDecode for bool { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -1402,6 +1422,28 @@ impl flutter_rust_bridge::IntoIntoDart> for AnnixPlayer } } +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for FrbWrapper { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + match self.0 { + crate::api::player::AudioQuality::Low => 0.into_dart(), + crate::api::player::AudioQuality::Medium => 1.into_dart(), + crate::api::player::AudioQuality::High => 2.into_dart(), + crate::api::player::AudioQuality::Lossless => 3.into_dart(), + } + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for FrbWrapper +{ +} +impl flutter_rust_bridge::IntoIntoDart> + for crate::api::player::AudioQuality +{ + fn into_into_dart(self) -> FrbWrapper { + self.into() + } +} // Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for crate::api::simple::LocalDb { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { @@ -1609,6 +1651,24 @@ impl SseEncode for uuid::Uuid { } } +impl SseEncode for crate::api::player::AudioQuality { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode( + match self { + crate::api::player::AudioQuality::Low => 0, + crate::api::player::AudioQuality::Medium => 1, + crate::api::player::AudioQuality::High => 2, + crate::api::player::AudioQuality::Lossless => 3, + _ => { + unimplemented!(""); + } + }, + serializer, + ); + } +} + impl SseEncode for bool { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { From c015f177b48117cc2f0e893ad35a244f05c797e8 Mon Sep 17 00:00:00 2001 From: snylonue Date: Tue, 7 May 2024 22:20:42 +0800 Subject: [PATCH 3/6] remove player code --- rust/src/lib.rs | 1 - rust/src/player/mod.rs | 2 -- rust/src/player/player.rs | 33 --------------------------------- rust/src/player/playlist.rs | 0 4 files changed, 36 deletions(-) delete mode 100644 rust/src/player/mod.rs delete mode 100644 rust/src/player/player.rs delete mode 100644 rust/src/player/playlist.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 91bf8ce4..93606027 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,3 +1,2 @@ pub mod api; mod frb_generated; /* AUTO INJECTED BY flutter_rust_bridge. This line may not be accurate, and you can change it according to your needs. */ -mod player; diff --git a/rust/src/player/mod.rs b/rust/src/player/mod.rs deleted file mode 100644 index cd7fe427..00000000 --- a/rust/src/player/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod player; -pub mod playlist; diff --git a/rust/src/player/player.rs b/rust/src/player/player.rs deleted file mode 100644 index 1114a120..00000000 --- a/rust/src/player/player.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::{ops::Deref, sync::mpsc::Receiver, thread}; - -use anni_playback::{types::PlayerEvent, Controls, Decoder}; - -pub struct Player { - controls: Controls, -} - -impl Player { - pub fn new() -> (Player, Receiver) { - let (sender, receiver) = std::sync::mpsc::channel(); - let controls = Controls::new(sender); - let thread_killer = crossbeam::channel::unbounded(); - - thread::spawn({ - let controls = controls.clone(); - move || { - let decoder = Decoder::new(controls, thread_killer.1.clone()); - decoder.start(); - } - }); - - (Player { controls }, receiver) - } -} - -impl Deref for Player { - type Target = Controls; - - fn deref(&self) -> &Self::Target { - &self.controls - } -} diff --git a/rust/src/player/playlist.rs b/rust/src/player/playlist.rs deleted file mode 100644 index e69de29b..00000000 From 31035d398748db7128650c95e2ab8a15cd7c8846 Mon Sep 17 00:00:00 2001 From: snylonue Date: Fri, 19 Jul 2024 12:09:54 +0800 Subject: [PATCH 4/6] fix unused imports --- lib/services/playback/playback_service.dart | 1 - rust/src/api/player.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/services/playback/playback_service.dart b/lib/services/playback/playback_service.dart index ea7b1c97..cf7e3515 100644 --- a/lib/services/playback/playback_service.dart +++ b/lib/services/playback/playback_service.dart @@ -10,7 +10,6 @@ import 'package:annix/services/metadata/metadata_model.dart'; import 'package:annix/services/path.dart'; import 'package:annix/services/playback/playback.dart'; import 'package:annix/native/api/player.dart'; -import 'package:annix/services/settings.dart'; import 'package:annix/ui/widgets/utils/property_value_notifier.dart'; import 'package:audio_session/audio_session.dart' hide AVAudioSessionCategory; import 'package:f_logs/f_logs.dart'; diff --git a/rust/src/api/player.rs b/rust/src/api/player.rs index 625dd6b3..7362f60d 100644 --- a/rust/src/api/player.rs +++ b/rust/src/api/player.rs @@ -1,7 +1,7 @@ pub use anni_player::provider::AudioQuality; use std::{ - sync::{Arc, Once, OnceLock, RwLock}, + sync::{Arc, Once, OnceLock}, thread, }; From 84c7f82c84f1616f4e6991a0684fe91d405ad0d0 Mon Sep 17 00:00:00 2001 From: snylonue Date: Fri, 19 Jul 2024 13:51:12 +0800 Subject: [PATCH 5/6] await setPlayingIndex before playing otherwise player state is not correct when start playing, resulting in wrong track being played and duplicate disposal of tracks --- lib/services/playback/playback_service.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/services/playback/playback_service.dart b/lib/services/playback/playback_service.dart index cf7e3515..d76f60d5 100644 --- a/lib/services/playback/playback_service.dart +++ b/lib/services/playback/playback_service.dart @@ -256,13 +256,13 @@ class PlaybackService extends ChangeNotifier { case LoopMode.off: // to the next song / stop if (currentIndex > 0) { - setPlayingIndex(currentIndex - 1); + await setPlayingIndex(currentIndex - 1); await play(reload: true); } break; case LoopMode.all: // to the previous song / last song - setPlayingIndex((currentIndex > 0 ? currentIndex : queue.length) - 1); + await setPlayingIndex((currentIndex > 0 ? currentIndex : queue.length) - 1); await play(reload: true); break; case LoopMode.one: @@ -272,7 +272,7 @@ class PlaybackService extends ChangeNotifier { break; case LoopMode.random: // to a random song - setPlayingIndex(rng.nextInt(queue.length)); + await setPlayingIndex(rng.nextInt(queue.length)); await play(reload: true); break; } @@ -286,7 +286,7 @@ class PlaybackService extends ChangeNotifier { case LoopMode.off: // to the next song / stop if (currentIndex < queue.length - 1) { - setPlayingIndex(currentIndex + 1); + await setPlayingIndex(currentIndex + 1); await play(reload: true); } else { await stop(); @@ -294,7 +294,7 @@ class PlaybackService extends ChangeNotifier { break; case LoopMode.all: // to the next song / first song - setPlayingIndex((currentIndex + 1) % queue.length); + await setPlayingIndex((currentIndex + 1) % queue.length); await play(reload: true); break; case LoopMode.one: @@ -304,7 +304,7 @@ class PlaybackService extends ChangeNotifier { break; case LoopMode.random: // to a random song - setPlayingIndex(rng.nextInt(queue.length)); + await setPlayingIndex(rng.nextInt(queue.length)); await play(reload: true); break; } @@ -331,7 +331,7 @@ class PlaybackService extends ChangeNotifier { queue.removeAt(index); if (removeCurrentPlayingTrack) { - setPlayingIndex(index, notify: false); + await setPlayingIndex(index, notify: false); await play(reload: true); } notifyListeners(); @@ -343,7 +343,7 @@ class PlaybackService extends ChangeNotifier { final to = index % queue.length; if (to != playingIndex) { // index changed, set new audio source - setPlayingIndex(to); + await setPlayingIndex(to); await play(reload: true); } else { // index not changed, seek to start @@ -380,7 +380,7 @@ class PlaybackService extends ChangeNotifier { queue = songs; // 2. set playing index if (songs.isNotEmpty) { - setPlayingIndex(initialIndex % songs.length, reload: true, notify: false); + await setPlayingIndex(initialIndex % songs.length, reload: true, notify: false); } else { playing?.dispose(); playing = null; From 4f7a78158de3ab2cc0902159068dcc6232ebef1b Mon Sep 17 00:00:00 2001 From: snylonue Date: Fri, 19 Jul 2024 14:12:00 +0800 Subject: [PATCH 6/6] change cache location to reuse previous cache --- lib/services/path.dart | 1 - lib/services/playback/playback_service.dart | 2 +- rust/Cargo.lock | 2 +- rust/Cargo.toml | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/services/path.dart b/lib/services/path.dart index 663d6227..f2570f1a 100644 --- a/lib/services/path.dart +++ b/lib/services/path.dart @@ -41,5 +41,4 @@ class PathService { String localDbPath() => p.join(PathService.dataRoot, 'local.db'); String audioCachePath() => p.join(PathService.storageRoot, 'audio'); -String playerCachePath() => p.join(PathService.storageRoot, 'audio_cache'); String coverCachePath() => p.join(PathService.storageRoot, 'cover'); diff --git a/lib/services/playback/playback_service.dart b/lib/services/playback/playback_service.dart index d76f60d5..5c279a1d 100644 --- a/lib/services/playback/playback_service.dart +++ b/lib/services/playback/playback_service.dart @@ -55,7 +55,7 @@ AudioQuality fromQuality(PreferQuality q) { } class PlaybackService extends ChangeNotifier { - static final AnnixPlayer player = AnnixPlayer(cachePath: playerCachePath()); + static final AnnixPlayer player = AnnixPlayer(cachePath: audioCachePath()); // TODO: cache this map static final PropertyValueNotifier> durationMap = diff --git a/rust/Cargo.lock b/rust/Cargo.lock index fe03efb0..ceee33e5 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -200,7 +200,7 @@ dependencies = [ [[package]] name = "anni-player" version = "0.1.0" -source = "git+https://github.com/snylonue/anni-player?rev=d1d6fe6#d1d6fe6ba190c4845eb5f8a525390d34011fc950" +source = "git+https://github.com/snylonue/anni-player?rev=466a434#466a43494519b85ef45f878739e8f46fb8c06f86" dependencies = [ "anni-playback", "anni-provider", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index c7260265..4a2fc078 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -20,7 +20,7 @@ log = "0.4.20" env_logger = "0.11" anni-playback = { git = "https://github.com/ProjectAnni/anni", rev = "9207e60" } -anni-player = { git = "https://github.com/snylonue/anni-player", rev = "d1d6fe6" } +anni-player = { git = "https://github.com/snylonue/anni-player", rev = "466a434" } cpal = { version = "0.15.3", features = ["oboe-shared-stdcxx"] } rand = "0.8.5" material-colors = { version = "0.3.3", features = ["image"] }