2

I want to continuously play music in my app on loop similar to many game apps available on the store.

However I am not sure when to initialize the music loop start and how to stop it. I created a class which contains the logic to start and stop the music.

Also My App Structure is like this

Main.dart

Wrapper.dart

(Here is where I did try initializing Audioplayer this is called to check login so a new instance of the player is created and the music overlaps)

>> Signin.dart

(If not signed in redirects here)

>> Home.dart

(If signed in redirects here)

class Music {
    AudioCache cache; 
    AudioPlayer player; 

    void _playFile() async{
      player = await cache.play('my_audio.mp3'); 
    }

    void _stopFile() {
      player?.stop(); 
    }

}
Teknoville
  • 459
  • 1
  • 7
  • 18

1 Answers1

1

I can see you have created a Music class. But that is not a singleton class. So, every time you are getting a new instance. What you need is a singleton class. You can implement something like this:

class Music {
  AudioPlayer player = AudioPlayer();
  AudioCache cache = AudioCache();

  Music._privateConstructor() {
    this.player.setVolume(0.5);
  }

  static final Music instance = Music._privateConstructor();

  Future playLoop(String filePath) async {
    player.stop();
    player = await cache.loop(filePath);
  }

  void stopLoop() {
    player?.stop();
  }
}

This guarantees that every time you gets the same instance.

Also, you need to manage the states properly as well.

AppLifecycleState

There are basically 4 types of states, these are:

  • resumed: The application is visible and responding to user input.

  • inactive: The application is in an inactive state and is not receiving user input.

  • paused: The application is not currently visible to the user, not responding user input, and running in the background.

  • detached: The application is still hosted on a flutter engine but is detached from any host views.

You can @override the didChangeAppLifecycleState() method.

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if ((state == AppLifecycleState.paused ||
            state == AppLifecycleState.detached ||
            state == AppLifecycleState.inactive) &&
        musicOn) {
      audio.stopLoop();
    } else if (state == AppLifecycleState.resumed && musicOn) {
      audio.playLoop("loop.mp3");
    }
  }

This prevents the overlap of music when you minimize and reopens apps.

sn-
  • 466
  • 1
  • 5
  • 15
  • Hi @sn- sorry did not see your answer and returned to this after a long time.So does the didChangeAppLifecycleState code have to be in all the different screens? – Teknoville Oct 26 '22 at 19:41
  • Hi Teknoville, did you figure out the question you asked about didChangeAppLigeCycleState needing to be in all the screens? – KingNOB Dec 06 '22 at 22:54