Skip to content

Visualizer: do NOT use audiofx.Visualizer, it needs RECORD_AUDIO #11

Description

@StaticHumStudio

The ask

A visualizer. Jeff's words: "cool soundscapes while you listen, different
themes."

Read this before writing any code: the obvious API is a trap

android.media.audiofx.Visualizer requires android.permission.RECORD_AUDIO.
Not optionally. The constructor throws without it.

The manifest currently declares seven permissions and not one is sensitive:
INTERNET, ACCESS_NETWORK_STATE, three FOREGROUND_SERVICE flavors, WAKE_LOCK,
POST_NOTIFICATIONS. Adding RECORD_AUDIO would put Microphone on the Play
listing, force a Data safety re-answer, and do it in an app whose single
loudest differentiator is a section literally headed NOTHING PHONES HOME with
the line "The Data safety section says no data collected because no data is
collected."

Shipping a microphone permission to power a pretty animation would be a
self-inflicted wound on the exact thing the whole relaunch is built on. Do not
do it.

The near-miss that makes this dangerous

PlaybackManager ALREADY attaches android.media.audiofx.Equalizer and
LoudnessEnhancer to player.audioSessionId (service/PlaybackManager.kt:2065).
So there is working in-repo precedent for audiofx on a session id, and
Visualizer attaches the same way, with the same constructor shape.

It looks like a two-line addition to an existing pattern. It is not. Equalizer
needs no permission and Visualizer does. Anyone who pattern-matches off
attachEqualizer will find that out at runtime.

The way that costs nothing

A Media3 AudioProcessor inserted into the ExoPlayer audio pipeline. It sees
the decoded PCM buffers directly on their way to the sink, gives you amplitude
or an FFT to whatever resolution you want, and needs no permission at all,
because you are reading your own playback rather than asking the system to tap
an output mix.

More work than Visualizer, and the only version of this feature worth
building.

An ambiguity that has to be resolved first

"Cool soundscapes" reads two ways and they are completely different projects:

  1. Visual. Reactive scenes in the Archive Beneath vein, driven by the audio.
    Different scenes as the "themes." This is what "visualizer" normally means
    and it is what the rest of this issue assumes.
  2. Audio. Ambient layers (rain, fireplace, a room tone) mixed UNDER the
    book. That is not a visualizer at all, it is a second player instance and a
    mix bus, plus licensing for whatever audio ships, plus its own settings and
    its own interaction with the sleep timer.

Jeff, which one? If it is both, they are two issues, and the audio one is
substantially more work than it sounds.

Battery, which is not a footnote here

A full-screen animated visualizer costs very differently in an audiobook app
than in a music app. Music is three minutes. An audiobook session is hours, and
often at night. A visualizer that runs whenever audio plays will show up in
Android's battery attribution and in reviews.

Hard rule for whatever gets built: render only while the screen is on AND the
player screen is foregrounded. Never while the screen is off, never from the
service, never behind the notification.

Gating

Clean unlock candidate. Pure character, zero access impact, nobody is locked out
of their own data by not having it. Fits the paywall rule exactly.

Post-2.1.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions