2

I'm coding a small game with the Flutter Framework. I'm using audioplayers for the Sounds.

It works fine like this, when calling it for example 2 times a second. But whenn I call it more than 5 times and again in the next second at some point the sound has like a delay and then after a second or so all the sounds play at once :) That sounds weired.

I also tested the audioplayers example from github on my iphone. Repeating the sounds in low frequency is ok, but when I repeat clicking the button as fast as possible at some point it gets some delay and the same thing is happening.

Is there some way to stop the previous Sound before and then playing the next one or isnt this possible?

Or is there some other Idea how to deal with the sounds?

This is how I use it:

    AudioCache upgradeSound = new AudioCache();

    void playUpgradeSound() {
       _playUpgradeSound(upgradeSound);
    }

     void _playUpgradeSound(AudioCache ac) async{
        await ac.play('audio/upgr.mp3');
     }

Thank you very much in advance

spydon
  • 9,372
  • 6
  • 33
  • 63
midi
  • 3,128
  • 5
  • 30
  • 47

3 Answers3

3

I solve similar problem by having singleton class, and after first play I can get the state, and I can stop previous play.

  class Audio {
  static final playerCache = AudioCache();
  static AudioPlayer audioPlayer;

  static void play(String audioName) async {
    audioPlayer = await playerCache.play('$audioName.mp3');
  }

  static void stop() {
    audioPlayer.stop();
  }
}

...
                        child: IconButton(
                          onPressed: () {
                            try {
                              if (Audio.audioPlayer.state ==
                                  AudioPlayerState.PLAYING) {
                                Audio.stop();
                              } else {
                                Audio.play('bid');
                              }
                            } catch (e) {
                              Audio.play('bid');
                            }
                          },
...
Ox. S
  • 107
  • 1
  • 6
1

There is a line of code in its own documentation.

To use the low latency API, better for gaming sounds, use:

AudioPlayer audioPlayer = AudioPlayer(mode: PlayerMode.LOW_LATENCY);

In this mode the backend won't fire any duration or position updates. Also, it is not possible to use the seek method to set the audio a specific position. This mode is also not available on web.

I hope it is useful.

Community
  • 1
  • 1
Fatih Mert Doğancan
  • 1,016
  • 14
  • 21
  • Unrelated to this question, I replaced my seek(0) with stop(), resume() and it seems to work. Do you think that's that the best way to restart an already playing sample? – Paul Sumpner Apr 26 '22 at 04:18
0

Each audio player can only play the file it currently captures (As if he wants to write something down there) and prevents another audio player from capturing it. Therefore, if you want to click on the button five times per second and hear the simultaneous sound of all sounds and the after sound from the previous ones, you need five new audio players (hash table key:audioPlayer()), each of which plays its own file, each from its own folder (each will be copied to a temporary directory if the filename is the same). The audio player will not give access to the file until its sound is completed. Or you will have to do MyTableOfAudioplayers[i].dispose() breaking off every unfinished sound to stop playback and return open access to the file to other audio players. The problem is caused by the lack of access to the still-sounding file (OS error: file is busy by another process).

The result is either a memory leak of more than 1 GB and a small folder with 60 MB of audio files, or no memory leak at all (only 120 MB of RAM), but with a lot of temporary folders (for example 60 MB * 10).

And you can’t do .dispose() during playback, otherwise - a red or gray screen (a serious mistake, almost a crash). Also, if you do not .dispose(), but do .release(), then the Audio Player will no longer get access to its file, even if you try to return it to it. We need to create a new copy of the audio player, adding it to our audioPlayers hash table. This is how I understand what's going on. If there is a way to allow multiple processes to read the same file without leaking memory, then that WOULD BE the BEST solution.

  • And the solution turned out to be easier! You just need to stop a frequently sounded note. If we press a key quickly again, it stops sounding and starts sounding again. Here is the solution. Just had to add ___audioPlayersMap[kM]?.stop();. And just one hash table is enough! All RAM consumption is only 100 MB!!! It's just great! And no memory leak! – student student Apr 06 '23 at 08:15
  • Memory Leak was ONLY in Windows build. In Android build No memory leak At All. – student student Apr 06 '23 at 09:19