basharovV / musicat

A sleek desktop music player and tagger for offline music 🪕. With gapless playback, smart playlists, and a map view! Built with Svelte and Tauri
GNU General Public License v3.0
431 stars 26 forks source link

Initial Android support (WIP, basic features do not work) #27

Open puterproblems opened 4 weeks ago

puterproblems commented 4 weeks ago

Screenshot from 2024-10-20 12-35-53

I've been learning a lot about tauri from this adventure. Musicat now "runs" on Android, as in the UI renders and can be interacted with, however a non-starter that prevents this from being functional is tauri's lack of support for folder selection on mobile (see https://v2.tauri.app/plugin/dialog/#build-a-file-selector-dialog). As such, I don't know if playback works.

It was quite an journey, mostly due to the complexities of compiling so many different binaries for Android. Notably, reqwest's usage of openssl-sys as seen:

  1. https://stackoverflow.com/questions/78989130/why-when-trying-to-run-tauri-for-android-it-fails-because-openssl-was-not-found
  2. https://github.com/sfackler/rust-openssl/issues/2217
  3. https://stackoverflow.com/questions/78989130/why-when-trying-to-run-tauri-for-android-it-fails-because-openssl-was-not-found (This was the solution)

Turns out the "rustls-tls" feature of reqwest just works around this problem by not using openssl (see https://docs.rs/reqwest/latest/reqwest/#optional-features).

Secondly, cpal's usage of oboe was missing parts of the cpp standard library as seen:

  1. https://cjycode.com/flutter_rust_bridge/manual/troubleshooting#could-not-resolve-symbol-__cxa_pure_virtual-or-libc_shared-issues
  2. https://users.rust-lang.org/t/neon-electron-undefined-symbol-cxa-pure-virtual/21223
  3. https://github.com/RustAudio/cpal/issues/720
  4. https://github.com/RustAudio/cpal/issues/900
  5. Solution was cpal = { version = "0.15.3", default-features = false, features = ["oboe-shared-stdcxx"] }

These were the most frustrating as the error messages were most cryptic. (the second one was especially annoying as it was only see when running the app on an Android emulator).

Some additional miscellaneous issues include:

  1. No menus for settings and such
  2. No window decorations/resize events
  3. No miniplayer
  4. No logging (no such file or directory for log4rs.yml, TODO: Include as resource, preferred to use native logging impl like logcat but I'm not sure tauri supports that)

Some additional notes for getting up and running for Android:

  1. Start by following these instructions from tauri
  2. Add the NDK bins to your path: export export PATH="$PATH:$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/" or equivalent for your operating system.
  3. Run npm run tauri android build
  4. Create an Android Virtual Device (AVD), I'd recommend Google Pixel 7 Pro
  5. npm run tauri android dev is supposed to launch it, see if this works for you

If it doesn't (it only worked for me once), there are a few extra steps:

  1. Generate dummy key keytool -genkey -v -keystore key.keystore -alias key -keyalg RSA -validity 10000 (you don't have to fill any info except password like demodemo
  2. Sign your unsigned apk apksigner sign --ks key.keystore --out signed-app.apk src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release-unsigned.apk
  3. Launch the AVD from Android Studio
  4. adb install signed-app.apk
  5. Start the app from the AVD window

It's not exactly a simple process yet, but tauri still seems like the best solution for an easy to iterate cross-platform application. The complexities of rust building and linking for all the different platforms doesn't make it any easier (though it can make apps faster). I'll reference this in a pull request with the changes where we can discuss the feasibility of this (or feel free to disregard it, as it does create significant maintenance burden). I'm mostly doing this in preparation for creating my own app larger app with tauri and this has been a fairly interesting way to learn about the framework and maybe pre-solve some of the challenges I'll face.

Anyways, sorry for this beefy issue, if I had more time I'd make it shorter. FYI I'll probably just leave this issue be for a while to work on other things.

basharovV commented 3 weeks ago

That's amazing! Thanks for going down the rabbit hole :) Excited to see where Tauri takes mobile support, since it's fresh out of the oven with v2. Definitely gives a lot to think about in terms of compatibility/feature parity and how much of the codebase could be shared for a mobile version. I imagine some of the playback/metadata code can be reused as-is, while the UI would need an entirely separate layer for mobile to match OS look and feel.

I'm curious to see playback working as well, perhaps I can include a test mode that plays a bundled mp3.