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:
- 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.
- 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.
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.Visualizerrequiresandroid.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
PlaybackManagerALREADY attachesandroid.media.audiofx.EqualizerandLoudnessEnhancertoplayer.audioSessionId(service/PlaybackManager.kt:2065).So there is working in-repo precedent for
audiofxon a session id, andVisualizerattaches the same way, with the same constructor shape.It looks like a two-line addition to an existing pattern. It is not.
Equalizerneeds no permission and
Visualizerdoes. Anyone who pattern-matches offattachEqualizerwill find that out at runtime.The way that costs nothing
A Media3
AudioProcessorinserted into the ExoPlayer audio pipeline. It seesthe 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 worthbuilding.
An ambiguity that has to be resolved first
"Cool soundscapes" reads two ways and they are completely different projects:
Different scenes as the "themes." This is what "visualizer" normally means
and it is what the rest of this issue assumes.
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.