Skip to content

feat(downloads): add format picker and custom download path#2871

Open
alltechdev wants to merge 15 commits intomainfrom
feat/downloads_path-format
Open

feat(downloads): add format picker and custom download path#2871
alltechdev wants to merge 15 commits intomainfrom
feat/downloads_path-format

Conversation

@alltechdev
Copy link
Contributor

@alltechdev alltechdev commented Feb 15, 2026

Summary

New Features

  • Add format picker dialog when downloading (shows bitrate/codec options)
  • Add custom download path support via SAF (Storage Access Framework)
  • Export downloads to user-selected folder with Artist/Title structure
  • Integrate Bento4 native library for M4A metadata embedding (cover art, title, artist, album, year)
  • Add "swap download" option to re-download with different quality
  • Show metadata badge on formats that support embedding (M4A 128kbps+)

Bug Fixes

  • Use downloadUri directly for playback to prevent format mismatch errors
  • Check targetItag before cache to respect user format selection
  • Fix URL cache expiry check (wrong comparison operator)
  • Reorder ExtractorsFactory: FragmentedMp4Extractor first for M4A files
  • Disable LTO for coverart native lib to fix CI linker issues

Technical

  • Add database schema migration for downloadUri tracking
  • Only embed metadata for M4A files >= 128kbps (low bitrate compatibility)

Test plan

  • Select custom download folder via Settings → Storage
  • Download a song and choose format (M4A or WebM)
  • Verify downloaded file has embedded metadata (M4A 128kbps+)
  • Test "swap download" to change quality
  • Verify playback uses downloaded file directly
  • Verify no format mismatch errors in logs
Screenshot_20260215-183858_com metrolist music debug Screenshot_20260215-183909_com metrolist music debug Screenshot_20260215-183924_com metrolist music debug Screenshot_20260215-183943_com metrolist music debug Screenshot_20260215-183957_com mixplorer

Bento4 m4a embeds:

Screenshot_20260216-125656_com.mixplorer.png

@alltechdev alltechdev changed the title fix(downloads): resolve format mismatch errors and improve playback feat(downloads): add format picker and custom download path Feb 15, 2026
@alltechdev alltechdev force-pushed the feat/downloads_path-format branch from cc6fadd to bac1c87 Compare February 16, 2026 01:25
@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

Just saying, guys, feel free to completely ignore this one 😁 I'm aware it's a ridiculous amount of code, I just really like the functionality, especially bento4.

@Zareeff
Copy link

Zareeff commented Feb 16, 2026

Just saying, guys, feel free to completely ignore this one 😁 I'm aware it's a ridiculous amount of code, I just really like the functionality, especially bento4.

Can you PLEASE tell me how long it took you to write almost 80k lines of code. I bet it was like hell to debug bugs.

@mostafaalagamy
Copy link
Member

I need to review 80,000 lines!!! 🤣

@alltechdev alltechdev force-pushed the feat/downloads_path-format branch from e57f717 to 8a6a5bc Compare February 16, 2026 14:11
@futurehits3-stack
Copy link

Give this man an award! This is awesome!

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

Just saying, guys, feel free to completely ignore this one 😁 I'm aware it's a ridiculous amount of code, I just really like the functionality, especially bento4.

Can you PLEASE tell me how long it took you to write almost 80k lines of code. I bet it was like hell to debug bugs.

I originally wrote this a while ago for a different app with AI assistance (80000 lines... haha). Just had to port it over.

I went slow, piece by piece, and put logging EVERYWHERE 😁. Probably a day or two until I was happy with it.

The main thing is making sure it the player doesnt get messed up by URL cache, that's the most annoying bit.

Try latest, I pushed a few fixes:

https://github.com/MetrolistGroup/Metrolist/actions/runs/22066983334/artifacts/5526986427

@futurehits3-stack
Copy link

Just tried your build that you linked and songs that are not downloaded are not working. Also downloading is stuck on loading.

Screenshot_20260216-101722 Screenshot_20260216-101911

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

Just tried your build that you linked and songs that are not downloaded are not working. Also downloading is stuck on loading.

I was afraid of this. It has a database migration.

@mostafaalagamy How can he go back?

Gimme a few I have an idea, need backwards compatibility.

@mostafaalagamy
Copy link
Member

How can he go back?

He can only go back after modifying the backup file!

@alltechdev
Copy link
Contributor Author

How can he go back?

He can only go back after modifying the backup file!

I will add backwards compatibility for old downloads.

@alltechdev
Copy link
Contributor Author

@futurehits3-stack just pushed, wait a few minutes for new build and let me know if solved

@futurehits3-stack
Copy link

@alltechdev I got you.

@alltechdev
Copy link
Contributor Author

@futurehits3-stack
Copy link

futurehits3-stack commented Feb 16, 2026

Nope the fix unfortunately didn't work. Downloading doesn't work also. @alltechdev

Screenshot_20260216-104609

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

Nope the fix unfortunately didn't work. Downloading doesn't work also. @alltechdev

You mean downloading an already downloaded song with previous builds right?

@futurehits3-stack
Copy link

So if I go to my library tab and go my downloads, everything works. But if I go to my homepage and click on a downloaded song it doesn't works.

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

So if I go to my library tab and go my downloads, everything works. But if I go to my homepage and click on a downloaded song it doesn't works.

When not playing directly from downloaded in Library tab:

Error immediately?
Spin forever?
Try to stream instead of playing cached?

And again, only for old downloads, correct?

I just tried reproducing the bug. I installed official 13.0.0 debug, downloaded multiple tracks and albums, then installed this PR build on top. All working fine.

@futurehits3-stack
Copy link

futurehits3-stack commented Feb 16, 2026

@alltechdev did you do something? All the songs on my homepage are working again and I can download songs. The app is back to working without any problems so far.

Screenshot_20260216-112536 Screenshot_20260216-112543

@alltechdev
Copy link
Contributor Author

@alltechdev did you do something? All the songs on my homepage are working again and I can download songs. The app is back to working without any problems so far.

That's latest build. All should be good when updating from old.

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

To anybody who will test this build, please backup everything from the old app in case you will want to downgrade again. Thanks.

@futurehits3-stack
Copy link

futurehits3-stack commented Feb 16, 2026

@alltechdev just updated and everything is working! Good shit my dude.

Edit: I didn't try to downgrade to the main app. I'm currently running this latest test build. But, everything is working for me.

@futurehits3-stack
Copy link

futurehits3-stack commented Feb 16, 2026

@alltechdev I just downgraded to the official release to see what would happen. And I got this error.
Screenshot_20260216-115449

Metrolist Crash Report.txt

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

@alltechdev I just downgraded to the official release to see what would happen. And I got this error.

Yep. That's what I was saying before. Would need to clear data of app to downgrade.

@futurehits3-stack
Copy link

futurehits3-stack commented Feb 16, 2026

@alltechdev uninstalled everything and cleared the cache. Everything works again. I'm currently running the main app. Hopefully we can get your features that you added. The new download option is awesome because I get to keep the songs forever.

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

@alltechdev uninstalled everything and cleared the cache. Everything works again. I'm currently running the main app. Hopefully we can get your features that you added. The new download option is awesome because I get to keep the songs forever.

You also get all metadata and coverart embedded automatically if you choose m4a download :)

Thanks for testing!

@futurehits3-stack
Copy link

Yup that's what I chose every time. I appreciate your work and you're welcome.
Screenshot_20260216-121708

@futurehits3-stack
Copy link

I do want to say if you choose to download the full album it didn't allow me to download.m4a it downloaded .webm. @alltechdev

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

I do want to say if you choose to download the full album it didn't allow me to download.m4a it downloaded .webm. @alltechdev

You must have not been on latest.

Album download:

Screenshot_20260216-122430_com.metrolist.music.debug.png

Added here:

2f1a2fc

@futurehits3-stack
Copy link

futurehits3-stack commented Feb 16, 2026

On individual songs I got the option to download.m4a but when I go to an album to download all the songs it downloaded .webm and didn't get the option menu. I might redownload later when I have time to check it out if you added it.

@adrielGGmotion
Copy link
Contributor

Crazy! We can discard "local music" if we add this one?

@alltechdev
Copy link
Contributor Author

alltechdev commented Feb 16, 2026

Crazy! We can discard "local music" if we add this one?

Didn't think about that. Is that a wanted feature?

Would definitely need some modification.

@adrielGGmotion
Copy link
Contributor

Crazy! We can discard "local music" if we add this one?

Didn't think about that. Is that a wanted feature?

Would definitely need some modification.

Many people request this feature, specially on reddit. Like right now someone just made another post asking about it: https://www.reddit.com/r/metrolist/s/ua1tlQY8DT

To keep the app mantainable my idea was basic support with no metadata matching. I think we should separate things, your pull request is incredible as it is already!

@alltechdev
Copy link
Contributor Author

Crazy! We can discard "local music" if we add this one?

Didn't think about that. Is that a wanted feature?

Would definitely need some modification.

Many people request this feature, specially on reddit. Like right now someone just made another post asking about it: https://www.reddit.com/r/metrolist/s/ua1tlQY8DT

To keep the app mantainable my idea was basic support with no metadata matching. I think we should separate things, your pull request is incredible as it is already!

Yeah.... I definitely don't want to touch this one 😁

@futurehits3-stack
Copy link

If they don't add this feature, I'm going to keep the APK and just load it up when I want to download songs on my internal storage. Just remember to backup before hand.

@mostafaalagamy mostafaalagamy changed the base branch from master to main February 18, 2026 22:50
alltechdev and others added 14 commits February 24, 2026 23:40
- Add format picker dialog when downloading songs (shows bitrate/codec)
- Add custom download path support via SAF (Storage Access Framework)
- Export downloads to user-selected folder with Artist/Title structure
- Integrate Bento4 native library for M4A metadata embedding (cover art, title, artist, album, year)
- Add "swap download" option to re-download with different quality
- Add database schema migration for downloadUri tracking
- Only embed metadata for M4A files >= 128kbps (low bitrate compatibility)
- Show metadata badge on format options that support embedding
- Use downloadUri directly for playback instead of ExoPlayer downloadCache
  to prevent format mismatch errors (MatroskaExtractor parsing M4A data)
- Check targetItag before cache in DownloadUtil to respect user format selection
- Clear playerCache when specific format requested to ensure fresh fetch
- Fix URL cache expiry check (was using wrong comparison operator)
- Reorder ExtractorsFactory: FragmentedMp4Extractor first for M4A files
- Add detailed logging for download and cache resolution debugging
- Move Bento4 library and JNI wrapper to metrolist-coverart-lib repository
- Replace embedded code with git submodule reference
- This reduces main repository size by ~77,000 lines
- Library can now be independently versioned and updated

Submodule: https://github.com/MetrolistGroup/metrolist-coverart-lib
- Embed album artist (aART) and track number (trkn) in M4A files
- Join all song artists for the Artist field (e.g., "Lady Gaga, Bruno Mars")
- Fetch missing metadata (year, album artist, track position) from YouTube
- Update native JNI and Kotlin wrapper signatures
…style

- Add header icon in circular container
- Add quality legend indicators (High/Medium/Low)
- Use card-based format items with radio buttons
- Add BEST badge for highest quality option
- Add + Metadata badge for M4A formats
- Improve visual hierarchy and spacing
…e build

- Add download format picker dialog to YouTubeSongMenu
- Add ProGuard keep rules for CoverArtNative JNI bindings
- Keep CoverArtEmbedder and DownloadExportHelper classes
- Add swap download option to YouTubeSongMenu
- Add download format picker dialog when downloading albums
- Add swap download option to re-download with different format
- Use buildList pattern for download menu items
Songs downloaded before the custom path feature was added don't have
downloadUri set. Add fallback to check ExoPlayer download cache for
these legacy downloads to ensure they still play after updating.
WebM audio files now export with .ogg extension for better compatibility
with offline music players. No quality loss - same Opus codec data,
just different container extension that's more widely recognized.
Extract full path from document URI (e.g., "Music/Metrolist" instead
of just "Metrolist") for clearer path display in storage settings.
- Update YTPlayerUtils to use new PoTokenGenerator.generateContentToken API
- Fix schema 34.json to include downloadUri field
@alltechdev alltechdev force-pushed the feat/downloads_path-format branch from 3764d36 to f400f91 Compare February 25, 2026 05:58
- Fix race condition in metadata embedding by making format storage synchronous
- Add artist relationship creation from player response for proper folder organization
- Add format picker dialog for playlist downloads (local and YouTube)
- Fix format fallback to prefer same codec type when exact itag unavailable
- Fix state updates happening on wrong thread in AlbumMenu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants