Skip to content

Releases: Yefee8/mufify

Mufify 1.0.3

Choose a tag to compare

@Yefee8 Yefee8 released this 04 Aug 13:36

An offline-only music player for Android. Plays the files a streaming service
will not — FLAC, ALAC, and whatever else is already on the phone — and shows you
what they actually are.

Install

Download mufify-1.0.3.apk below and open it on the phone. Android will ask
you to allow installing from this source; that is expected for an APK that did
not come from a store.

Upgrading from any earlier build works in place — this one's version code is
higher, so nothing needs uninstalling.

Since 1.0.2

A Bluetooth remote can change tracks. Play and pause worked from a headset
or a car; next and previous did nothing at all. The cause was not in this app:
expo-audio, the playback library, removes all four track-navigation commands
from its media session before anything can connect to it. That is a fair
decision for a library whose player holds one file and has never heard of a
queue — Mufify's queue lives in its own code, which is where shuffle, repeat
and the play/skip rule are. The commands are now restored, announced to the
app, and answered there. docs/adr/017 is the whole account, including the
part where the first patched build came out byte-identical because Expo ships
that library precompiled.

A slightly shorter gap between tracks, on some devices. Worth being precise
about, because it is not fixed: end of one track to first audio of the next
measured 72–79 ms before and 46–55 ms after on an emulator, and 285–314 ms
before against 269–292 ms after on a real phone. Almost all of that is inside
the playback library's own path for swapping files — measured, including a
preloading attempt that changed nothing, which is how we know it is not the
disk. Closing it properly means the queue moving into the audio engine, and the
one API expo-audio offers for that cannot drive a lock screen, so it would
cost the notification and background playback. Not a trade worth making today.

What it does

  • Playback of local files, lossless first-class, with background playback,
    lock-screen and notification controls, and a persistent queue.
  • Five shuffle algorithms, each explained where you pick it.
  • Local playlists with drag-reorder and cover mosaics, plus liked songs.
  • On-device listening statistics by week, month and year — top tracks,
    artists, albums and playlists, with a Wrapped summary.
  • The technical truth of a file on a monospaced spec strip: container,
    sample rate, bit depth, bitrate, channels, size.
  • Turkish and English, dark and light.
  • A statistics switch, if you would rather it kept no history. Turning it
    off stops new writes and leaves what is already recorded alone.
  • An animation speed setting — Normal, Fast, or Instant.

No network, and it is enforced

There is no network layer. Not a disabled one, not one behind a setting.

This release ships without the INTERNET permissionplugins/withOfflineOnly.js
strips it from the release manifest, so a change that introduces a network call
does not fail review, it fails to work. Check it yourself:

aapt2 dump permissions mufify-1.0.3.apk | grep INTERNET   # prints nothing

ACCESS_NETWORK_STATE does survive, pulled in by a dependency. It cannot open a
connection — that needs INTERNET, which is absent — but Android renders it as
"view network connections", so it is worth naming rather than leaving you to
find it.

Worth knowing

  • Signed with a debug key. Fine for sideloading, not fine for the Play
    Store. It also means a future Play-signed build cannot replace this one
    without uninstalling first.
  • The APK is universal — every ABI in one file, which is why it is ~128 MB. What
    gets installed is a fraction of that.
  • minSdkVersion 26 (Android 8.0), targets 36.
  • No favourite button in the media notification: expo-audio does not expose
    MediaSession custom actions. The reasoning and the options are in
    docs/adr/015.

Mufify 1.0.2

Choose a tag to compare

@Yefee8 Yefee8 released this 04 Aug 05:59

An offline-only music player for Android. Plays the files a streaming service
will not — FLAC, ALAC, and whatever else is already on the phone — and shows you
what they actually are.

Install

Download mufify-1.0.2.apk below and open it on the phone. Android will ask
you to allow installing from this source; that is expected for an APK that did
not come from a store.

Upgrading from any earlier build works in place — this one's version code is
higher, so nothing needs uninstalling.

Since 1.0.1

The tab bar no longer draws over the queue. 1.0.1 claimed this fix and did
not deliver it, which is worth saying plainly.

The first two attempts were built on a wrong reading. Android sorts sibling
views by Z before it uses the drawing order zIndex produces, so the obvious
suspect was react-navigation's bottom bar, which carries an elevation of its
own. It was not that. Patching that elevation to zero in react-navigation's own
stylesheet — so the value definitely reached the bar — changed nothing, and
neither did giving the sheets an elevation above it.

What is actually happening, on Android 10 and not on Android 16 with the same
build: leaf views from underneath the queue composite in front of it, while
their own backgrounds stay correctly behind. Removing the tab bar entirely
showed it was never about the tab bar — a row of the library list came through
in its place.

So the queue now gets its own window rather than a higher number. The
compositor keeps windows apart, and nothing in the app's window can reach into
another one. The two elevation changes have been reverted; a wrong explanation
in the code is worse than no change at all.

What it does

  • Playback of local files, lossless first-class, with background playback,
    lock-screen and notification controls, and a persistent queue.
  • Five shuffle algorithms, each explained where you pick it.
  • Local playlists with drag-reorder and cover mosaics, plus liked songs.
  • On-device listening statistics by week, month and year — top tracks,
    artists, albums and playlists, with a Wrapped summary.
  • The technical truth of a file on a monospaced spec strip: container,
    sample rate, bit depth, bitrate, channels, size.
  • Turkish and English, dark and light.
  • A statistics switch, if you would rather it kept no history. Turning it
    off stops new writes and leaves what is already recorded alone.
  • An animation speed setting — Normal, Fast, or Instant.

No network, and it is enforced

There is no network layer. Not a disabled one, not one behind a setting.

This release ships without the INTERNET permissionplugins/withOfflineOnly.js
strips it from the release manifest, so a change that introduces a network call
does not fail review, it fails to work. Check it yourself:

aapt2 dump permissions mufify-1.0.2.apk | grep INTERNET   # prints nothing

ACCESS_NETWORK_STATE does survive, pulled in by a dependency. It cannot open a
connection — that needs INTERNET, which is absent — but Android renders it as
"view network connections", so it is worth naming rather than leaving you to
find it.

Worth knowing

  • Signed with a debug key. Fine for sideloading, not fine for the Play
    Store. It also means a future Play-signed build cannot replace this one
    without uninstalling first.
  • The APK is universal — every ABI in one file, which is why it is ~128 MB. What
    gets installed is a fraction of that.
  • minSdkVersion 26 (Android 8.0), targets 36.
  • No favourite button in the media notification: expo-audio does not expose
    MediaSession custom actions. The reasoning and the options are in
    docs/adr/015.

Mufify 1.0.1

Choose a tag to compare

@Yefee8 Yefee8 released this 03 Aug 20:15

An offline-only music player for Android. Plays the files a streaming service
will not — FLAC, ALAC, and whatever else is already on the phone — and shows you
what they actually are.

Install

Download mufify-1.0.1.apk below and open it on the phone. Android will ask
you to allow installing from this source; that is expected for an APK that did
not come from a store.

Upgrading from 1.0.0 or 0.1.0 works in place — this build's version code is
higher, so nothing needs uninstalling.

Since 1.0.0

One fix, which is the whole point of this release.

The tab bar no longer draws over the queue. Open the queue and the four tab
icons sat on top of its rows. The app's own stacking order was not the problem —
it had the queue at the top and still does. zIndex is simply not the whole
story on Android: Z is sorted first and the order zIndex produces is only the
tie-break, so anything the platform elevates outranks a surface the layout puts
above it. react-navigation's bottom bar ships an elevation of its own, and that
was enough.

Two changes, because one of them should not have to be right on its own. The
bar gives up its elevation — it is a surface, not something floating over one —
and the full-screen sheets now carry Z rather than only a zIndex, so the
stacking order the app declares is the one Android draws.

What it does

  • Playback of local files, lossless first-class, with background playback,
    lock-screen and notification controls, and a persistent queue.
  • Five shuffle algorithms, each explained where you pick it.
  • Local playlists with drag-reorder and cover mosaics, plus liked songs.
  • On-device listening statistics by week, month and year — top tracks,
    artists, albums and playlists, with a Wrapped summary.
  • The technical truth of a file on a monospaced spec strip: container,
    sample rate, bit depth, bitrate, channels, size.
  • Turkish and English, dark and light.
  • A statistics switch, if you would rather it kept no history. Turning it
    off stops new writes and leaves what is already recorded alone.
  • An animation speed setting — Normal, Fast, or Instant.

No network, and it is enforced

There is no network layer. Not a disabled one, not one behind a setting.

This release ships without the INTERNET permissionplugins/withOfflineOnly.js
strips it from the release manifest, so a change that introduces a network call
does not fail review, it fails to work. Check it yourself:

aapt2 dump permissions mufify-1.0.1.apk | grep INTERNET   # prints nothing

ACCESS_NETWORK_STATE does survive, pulled in by a dependency. It cannot open a
connection — that needs INTERNET, which is absent — but Android renders it as
"view network connections", so it is worth naming rather than leaving you to
find it.

Worth knowing

  • Signed with a debug key. Fine for sideloading, not fine for the Play
    Store. It also means a future Play-signed build cannot replace this one
    without uninstalling first.
  • The APK is universal — every ABI in one file, which is why it is ~128 MB. What
    gets installed is a fraction of that.
  • minSdkVersion 26 (Android 8.0), targets 36.
  • No favourite button in the media notification: expo-audio does not expose
    MediaSession custom actions. The reasoning and the options are in
    docs/adr/015.

Mufify 1.0.0

Choose a tag to compare

@Yefee8 Yefee8 released this 03 Aug 18:29

An offline-only music player for Android. Plays the files a streaming service
will not — FLAC, ALAC, and whatever else is already on the phone — and shows you
what they actually are.

Install

Download mufify-1.0.0.apk below and open it on the phone. Android will ask
you to allow installing from this source; that is expected for an APK that did
not come from a store.

Upgrading from 0.1.0 works in place — this build's version code is higher, so
nothing needs uninstalling.

What it does

  • Playback of local files, lossless first-class, with background playback,
    lock-screen and notification controls, and a persistent queue.
  • Five shuffle algorithms, each explained where you pick it.
  • Local playlists with drag-reorder and cover mosaics, plus liked songs.
  • On-device listening statistics by week, month and year — top tracks,
    artists, albums and playlists, with a Wrapped summary.
  • The technical truth of a file on a monospaced spec strip: container,
    sample rate, bit depth, bitrate, channels, size.
  • Turkish and English, dark and light.
  • A statistics switch, if you would rather it kept no history. Turning it
    off stops new writes and leaves what is already recorded alone.
  • An animation speed setting — Normal, Fast, or Instant.

Since 0.1.0

  • The app has its own icon and splash screen.
  • Importing a folder indexes that folder, instead of adding it and then
    sweeping the entire device.
  • Pull-to-refresh is gone from the library. It ran a full rescan — a minute
    of work started by the gesture people make to get back to the top of a list.
    Scanning is the button that says what it costs.
  • Now Playing no longer draws through the queue. Two stacked full-screen
    sheets were compositing in the wrong order, which put the spec strip and the
    track duration in front of the queue's rows and turned the rows behind them
    black.
  • Bottom sheets clear the navigation bar. The long-press actions and the
    track-info sheet had their last row behind the system buttons.
  • Played entries in the queue are dimmed once, rather than three different
    ways that read as a shadow.
  • The queue opens with the same tuned spring as Now Playing, and its rows are
    ready before the sheet finishes arriving.
  • The media notification carries artist and album, and the app's own artwork
    placeholder when a track has no cover.
  • A listen is counted against the duration the player reports, not the one the
    scanner stored. A track MediaStore had not finished reading counted as no
    plays at all.

No network, and it is enforced

There is no network layer. Not a disabled one, not one behind a setting.

This release ships without the INTERNET permissionplugins/withOfflineOnly.js
strips it from the release manifest, so a change that introduces a network call
does not fail review, it fails to work. Check it yourself:

aapt2 dump permissions mufify-1.0.0.apk | grep INTERNET   # prints nothing

ACCESS_NETWORK_STATE does survive, pulled in by a dependency. It cannot open a
connection — that needs INTERNET, which is absent — but Android renders it as
"view network connections", so it is worth naming rather than leaving you to
find it.

Worth knowing

  • Signed with a debug key. Fine for sideloading, not fine for the Play
    Store. It also means a future Play-signed build cannot replace this one
    without uninstalling first.
  • The APK is universal — every ABI in one file, which is why it is ~128 MB. What
    gets installed is a fraction of that.
  • minSdkVersion 26 (Android 8.0), targets 36.
  • No favourite button in the media notification: expo-audio does not expose
    MediaSession custom actions. The reasoning and the options are in
    docs/adr/015.

Mufify 0.1.0

Choose a tag to compare

@Yefee8 Yefee8 released this 03 Aug 14:02

An offline-only music player for Android. Plays the files a streaming service
will not — FLAC, ALAC, and whatever else is already on the phone — and shows you
what they actually are.

Install

Download mufify-0.1.0.apk below and open it on the phone. Android will ask
you to allow installing from this source; that is expected for an APK that did
not come from a store.

On MIUI / HyperOS, adb install -r also works and updates in place without
losing your library. If it refuses with INSTALL_FAILED_USER_RESTRICTED, push
the file to the device and open it from Files instead.

What is in it

  • Playback of local files, lossless first-class, with background playback,
    lock-screen and notification controls, and a persistent queue.
  • Five shuffle algorithms, each explained where you pick it.
  • Local playlists with drag-reorder and cover mosaics, plus liked songs.
  • On-device listening statistics by week, month and year — top tracks,
    artists, albums and playlists, with a Wrapped summary.
  • The technical truth of a file on a monospaced spec strip: container,
    sample rate, bit depth, bitrate, channels, size.
  • Turkish and English, dark and light, both switchable.
  • A statistics switch, if you would rather it did not keep history at all.
    Turning it off stops new writes and leaves what is already recorded alone.
  • An animation speed setting — Normal, Fast, or Instant.

No network, and it is enforced

There is no network layer. Not a disabled one, not one behind a setting.

This release ships without the INTERNET permissionplugins/withOfflineOnly.js
strips it from the release manifest, so a change that introduces a network call
does not fail review, it fails to work. You can check the APK yourself:

aapt2 dump permissions mufify-0.1.0.apk | grep INTERNET   # prints nothing

One permission does survive and is worth naming rather than leaving you to find
it: ACCESS_NETWORK_STATE, pulled in by a dependency. It cannot open a
connection — that needs INTERNET, which is absent — but Android renders it as
"view network connections".

Before you rely on this

  • Signed with a debug key. Fine for sideloading, not fine for the Play
    Store, and it means you cannot upgrade to a differently-signed build later
    without uninstalling first.
  • versionCode is 1.
  • The APK is universal — every ABI in one file, which is why it is ~128 MB. An
    install is a fraction of that.
  • minSdkVersion 26 (Android 8.0).

Known issues

  • On some MIUI devices the queue sheet's close chevron can flash and disappear.
    Three fixes have gone in for it and none could be reproduced on an emulator;
    the sheet still closes with the back button and by tapping outside the list.

Full documentation, including the architecture and every decision record, is in
the repository. Screenshots are in docs/screenshots.md.