Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAF-based music loading #322

Open
OxygenCobalt opened this issue Jan 12, 2023 · 13 comments
Open

SAF-based music loading #322

OxygenCobalt opened this issue Jan 12, 2023 · 13 comments
Assignees
Labels
blocked Currently blocked by another task complex This is a complex addition that will take some time enhancement New feature or request music Related to music loading

Comments

@OxygenCobalt
Copy link
Owner

OxygenCobalt commented Jan 12, 2023

Bypass MediaStore entirely and just iterate through a Document Tree Uri provided by the user.

Related links: 1 2 3 4

More or less, the new user flow would be something like:

  • After installation, app starts with an onboarding flow that first asks for permissions.
  • Once permissions are granted, app asks for the user to open a directory using the system file picker.
  • Once this is done, the app does the typical music loading process, except with the child files of the given directory instead of MediaStore. Still uses ExoPlayer first, followed by the system metadata extractor. Cache system remains.

More or less, this addition would really just make Auxio create it's own, more sensible variant of MediaStore that should have maximum device compatibility.

Benefits:

  • This should pick up all music files in the given directory, compared to the often stale MediaStore database.
  • Should make directory-based images (see: Arbitrary Images for Artists #68 and Covers based on music library (cover.jpg) #104) easier since there's no need for an O(n^2) query algorithm with the image database. I can just travel the directory structure manually.
  • Deleting files using SAF is seemingly much more reliable than through MediaStore, even in stupid scoped storage edge cases like SD Cards.
  • Should theoretically roll the Music folders and Ignore non-music settings into the onboarding configuration, which makes that part of the app much simpler.

Drawbacks:

  • I don't really know how Automatic Rescanning could work with this, if at all. It probably will still be roughly the same, just swap out MediaStore with the user directories.

I actually think this is what the big proprietary music players like Musicolet and Poweramp do. Seems vaguely possible if I continue thinking about it. Definitely non-priority right now since MediaStore currently works ok. Will probably group with the big service rework in perhaps another major version.

@OxygenCobalt OxygenCobalt added enhancement New feature or request music Related to music loading complex This is a complex addition that will take some time maybe Uncertain if this will be done and removed maybe Uncertain if this will be done labels Jan 12, 2023
@OxygenCobalt OxygenCobalt self-assigned this Jan 12, 2023
@OxygenCobalt
Copy link
Owner Author

OxygenCobalt commented Jan 14, 2023

More stuff about this:

  • This addition possibly jeopardizes the "fast" album cover option, which would basically force me to implement Covers based on music library (cover.jpg) #104.
  • Doing this theoretically enables cuesheet files, although I don't expect to support these since they break the entirety of Auxio's playback model.

@KraXen72
Copy link

intersting. the only thing is, upon rewriting big things like this or custom metadata parser (you already did), i would consider doing a small amount of extra work and releasing these systems as a library.
it's very cool that you got to a point where the metadata parser can fully replace mediastore for metadata and is wayy more sensible & reliable, but unless you publish it as a library, other devs making something that tries to read music metadata on android will have to either use MediaStore, extract the system from this app and modify it make sure it somehow works + they lose all automatic bug fixes by doing this, or re-implement it themselves.

for example, musicolet has a pretty good metadata parser+editor implementation but it's not open source and it's not published as a library, so no one else can use it.

@OxygenCobalt
Copy link
Owner Author

intersting. the only thing is, upon rewriting big things like this or custom metadata parser (you already did), i would consider doing a small amount of extra work and releasing these systems as a library.

I am thinking about trying to split off the module, but it's really tied up with the rest of this app and would require a lot of internal reworks.

@OxygenCobalt
Copy link
Owner Author

OxygenCobalt commented Jan 14, 2023

Another thing this may enable: LRC file support that plays along with scoped storage. Other reasons why I don't want lyrics still apply though.

@OxygenCobalt
Copy link
Owner Author

OxygenCobalt commented Feb 20, 2023

Bad news: According to google/ExoPlayer#10706, duration parsing is actually not supported by ExoPlayer and is unlikely to be "properly" supported even if implemented. I would likely have to give up and bundle a tagging library (like TagLib because it seems pretty quick) if I were to do this. FFMpeg may also be considered, but that would require obscene amounts of work on my end vendoring the extension, patching in multi-value tags, and figuring out how to plug it into the extractor framework. Not really sure where to go from here.

@OxygenCobalt OxygenCobalt added the blocked Currently blocked by another task label Feb 20, 2023
@OxygenCobalt
Copy link
Owner Author

Okay, maybe it's not entirely impossible. Again, just requires more patches, and there will remain edge cases where I am forced to fall back to android's metadata (example: VBR MP3 with no Xing header).

@OxygenCobalt
Copy link
Owner Author

More information I've learned about this:

  • I would likely no longer need to request any storage permissions if I were to add this.
  • Since this does result in the system file picker from being opened, you'd be unable to load directories like Download from Android 11 onward. But that doesn't really matter since nobody keeps their music there anyway.

@Cwpute
Copy link

Cwpute commented Oct 24, 2023

I'm not sure if this is relevant, but i've found an old opensource app called Camera Roll which has an option in its settings to bypass MediaStore by using something they call MediaRetriever…
The app is old (2019) but maybe it can be somewhat salvaged to achieve our goal ?

After some more research, i've come across this repository for something called MediaRetriver, from around the same time, and which seems to achieve kind of the same goal: https://github.com/jiajunhui/MediaRetriever

@Cwpute
Copy link

Cwpute commented Oct 24, 2023

Welp, would you look at this: SAF Media Scanner
witha few edits here and there it should be pretty usable.

@OxygenCobalt
Copy link
Owner Author

OxygenCobalt commented Oct 24, 2023

I'm not sure if this is relevant, but i've found an old opensource app called Camera Roll which has an option in its settings to bypass MediaStore by using something they call MediaRetriever…
The app is old (2019) but maybe it can be somewhat salvaged to achieve our goal ?

After some more research, i've come across this repository for something called MediaRetriver, from around the same time, and which seems to achieve kind of the same goal: https://github.com/jiajunhui/MediaRetriever

Not even remotely similar, actually. Your camera app is referring to MediaMetadataRetriever, which is android's metadata extractor and is largely terrible. I would be using it for this, but only as a fallback. This library is just a standard component library, and a super old one at that.

Welp, would you look at this: SAF Media Scanner witha few edits here and there it should be pretty usable.

I don't use third-party libraries. That project in particular uses a completely different database schema, music interpretation, and tagging system. Loading with SAF is actually dead simple, I got ChatGPT to write half of it a few months back and I could write the rest in an afternoon. The issue is the down-stream impacts that I have to mitigate, and the fact that this is super low priority since MediaStore works okay for now. I need to reach playlist feature parity and gapless playback before I focus on this in any capacity.

@Cwpute
Copy link

Cwpute commented Oct 24, 2023

Yeah, as i thought, most of it ended up being irrelevant 😄 thanks for taking the time to answer anyway.
Since i saw this issue with a good bunch of comments from you, and knowing this was something that some other audio players would have wanted, i got curious and figured i could do some research on my own. Well ! should have researched harder.

@OxygenCobalt
Copy link
Owner Author

OxygenCobalt commented Oct 24, 2023

That's fine. This isn't really a "How do I do it" problem as much as it is "How do I integrate it" problem, so researching it won't yield too much.

@OxygenCobalt
Copy link
Owner Author

OxygenCobalt commented Jan 21, 2024

Planning to do this alongside the now-prioritized #327 in a 3.5.0 or 4.0.0 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Currently blocked by another task complex This is a complex addition that will take some time enhancement New feature or request music Related to music loading
Projects
Status: Music Loader Rework
Development

No branches or pull requests

3 participants