skip to Main Content

I need an AudioPlayer in Flutter that, even if one sound is currently playing, if I play another one, the previous one cancels and the new one goes.

This works if I do this: audioPlayer.setReleaseMode(ReleaseMode.stop);

The problem is, if I play the same asset sound 2 times in a row, it doest work, the previous one needs to end before the audioplayer plays the second one, I need this asset to sound every time I press a button, so, If I spam buttons, the assets needs to play on every click

2

Answers


  1. To avoid multiple button presses triggering multiple sound loops, you can introduce a debounce mechanism that prevents rapid consecutive presses from triggering the sound repeatedly. Here’s an example of how you can implement it:

    import 'package:flutter/material.dart';
    import 'package:audioplayers/audioplayers.dart';
    
    class Debouncer {
      final Duration delay;
      Timer _timer;
    
      Debouncer({this.delay});
    
      void run(VoidCallback callback) {
        if (_timer != null) {
          _timer.cancel();
        }
        _timer = Timer(delay, callback);
      }
    }
    
    class MyAudioPlayer extends StatefulWidget {
      @override
      _MyAudioPlayerState createState() => _MyAudioPlayerState();
    }
    
    class _MyAudioPlayerState extends State<MyAudioPlayer> {
      AudioPlayer audioPlayer = AudioPlayer();
      Debouncer debouncer = Debouncer(delay: Duration(milliseconds: 500));
    
      void playSound(String assetPath) async {
        await audioPlayer.setReleaseMode(ReleaseMode.STOP);
        await audioPlayer.play(assetPath);
      }
    
      void handleButtonPress(String assetPath) {
        debouncer.run(() {
          playSound(assetPath);
        });
      }
    
      @override
      void dispose() {
        audioPlayer.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return RaisedButton(
          onPressed: () {
            handleButtonPress('assets/sound.mp3');
          },
          child: Text('Play Sound'),
        );
      }
    }

    In the code above, a Debouncer class is introduced to debounce the button presses. It takes a delay duration as an argument. When the run method is called, it cancels any existing timer and sets a new timer with the specified delay. The callback function provided to run will be executed only after the delay has elapsed without any subsequent button presses.

    In the _MyAudioPlayerState class, the Debouncer instance is created with a delay of 500 milliseconds. The handleButtonPress method is modified to use the debouncer’s run method, passing the playSound function as the callback.

    Login or Signup to reply.
  2. Use the assets_audio_player package.

    The code below will play a sound on every button click no matter how fast you spam it.

    ElevatedButton(
      onPressed: () {
        AssetsAudioPlayer.newPlayer().open(
          Audio('assets/sounds/pop_alert.mp3'),
          autoStart: true,
          showNotification: false, 
        );
      },
      child: const Text('Click Me!'),
    ),
    

    Extra tip:

    The trick to making button presses sound responsive is to remove as much "silence"
    as possible from the audio file. This requires a bit of audio editing. For example this is the waveform of the "pop_alert.mp3" file I used.

    before trim
    enter image description here

    We need to trim the audio clip to remove as much silence as possible so that the sound plays immediately when the button is pressed. You can use free online tools such as Free Audio Trimmer to achieve that.

    after trim
    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search