Skip to content

Android: app crashes in background with media_kit (audio crackling then force-close) #1

Description

@elias001011

Description

When Sonora is playing music and the app goes to the background (screen off or another app in foreground), after 1-5 minutes the audio starts crackling/faltering and then the app crashes completely — losing the notification, the foreground service, and the entire queue state.

This does NOT happen with Musify (https://github.com/gokadzev/Musify), which uses the same audio_service structure but a different audio engine.

Version: 1.6.0+38
Device: Multiple Android devices tested


Root Cause Analysis

After comparing Sonora's code with Musify's, the critical difference is in the audio playback engine:

Aspect Sonora Musify
Audio engine media_kit (libmpv) just_audio (ExoPlayer)
Native libs media_kit_libs_video ❌ Not used
audio_service ✅ Yes ✅ Yes
androidStopForegroundOnPause false false

Why media_kit causes the crash

media_kit is a video-first library built on libmpv. On Android, even when used solely for audio playback (no VideoController), libmpv still:

  1. Allocates native resources tied to the Flutter rendering surface
  2. When the app goes to background, Android destroys/detaches this surface
  3. libmpv keeps trying to decode without a valid surface → audio crackling
  4. Native crash takes down the entire process (including the audio_service foreground service)

just_audio (used by Musify) doesn't have this problem because it uses Android's native ExoPlayer, which:

  • Is audio-only — no rendering surface needed
  • Handles audio focus correctly
  • Is significantly lighter on memory
  • Is designed for background playback from the ground up

Steps to Reproduce

  1. Install Sonora on any Android device (release build)
  2. Start playing any song
  3. Minimize the app or turn off the screen
  4. Wait 1-5 minutes
  5. Observed: audio starts crackling/faltering, then the app crashes

Proposed Solutions

Option A (Recommended — definitive): Replace audio engine with just_audio

Keep media_kit_video exclusively for the video player widget (when the user watches a music video) and use just_audio for audio-only playback in SonoraAudioHandler.

Files that would need to change:

  1. pubspec.yaml — Add just_audio and just_audio_background
  2. lib/presentation/features/player/audio_handler.dart — Replace Player (media_kit) with AudioPlayer (just_audio)
  3. lib/presentation/features/player/audio_equalizer_handler.dart — Adapt equalizer for just_audio
  4. lib/presentation/providers/video_player_provider.dart — Keep media_kit_video isolated for video only

Option B (Quick mitigation — palliative): Reduce cache size + configure audio attributes

In audio_handler.dart, the current cache settings are very aggressive:

await playerPlatform.setProperty('demuxer-max-bytes', '104857600');  // 100MB
await playerPlatform.setProperty('demuxer-max-back-bytes', '52428800'); // 50MB

100MB cache is excessively large for a background audio app on resource-constrained Android devices. Reducing to:

await playerPlatform.setProperty('demuxer-max-bytes', '20971520');     // 20MB
await playerPlatform.setProperty('demuxer-max-back-bytes', '10485760'); // 10MB

And adding audio stream configuration to keep playback alive in background:

await playerPlatform.setProperty('audio-stream-silence', 'yes');

Option C: Offer a user-facing toggle in Settings

Add a "Background stability mode" toggle in Settings → Playback that:

  • Reduces cache from 100MB → 20MB
  • Disables heavy features (crossfade, lookahead preloading)
  • Warns the user about potential trade-offs in transition smoothness

Additional Notes

  • androidStopForegroundOnPause is already false
  • AndroidManifest already has FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PLAYBACK, WAKE_LOCK
  • androidNotificationOngoing is false — setting it to true might help keep the service alive

References

Metadata

Metadata

Assignees

Labels

improvementPerformance improvements

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions