0

There is a weird bug that occurs when I try to play an audio file(.mp3) from assets, in iOS. I'm using audioplayers plugin for this. My task is to play an audio file (either from local storage or assets), after some delay, while the app is not in foreground, that is while the screen is locked or app in in recent tray. The problem is, when I try to play the audio file after any timer function when iPhone is locked (ex. after timer.delay, Future.delay, etc) the app doesn't plays it. The app plays it after unlocking the iPhone. Also a point is to be noted that EVERYTHING WORKS as intended in DEBUG version of the app, and NOT IN RELEASE version. One more thing, I have added background audio permission in info.plist, which is necessary for playing audio in background. In Android, everything is working fine. Also , I have tried the Audio_service plugin, but it didn't worked as well.

My dummy code for app is as follows:

class AudioTesting extends StatefulWidget {
  @override
  _AudioTestingState createState() => _AudioTestingState();
}

class _AudioTestingState extends State<AudioTesting> {

  @override
  void initState() {
  AudioPlayer _audioPlayer = AudioPlayer();
  AudioCache _audioCache = AudioCache();
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AudioServiceWidget(
      child: Scaffold(
        appBar: AppBar(
          title: Text('Testing Screen'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(onPressed: (){
                  Future.delayed(Duration(seconds: 5),(){
                    _audioCache.load('$test.mp3');
                    _audioPlayer = await _audioCache.play('$test.mp3');
                    //This doesnt works in release mode, but works in debug mode, when played in Locked state
                  });
              },
                child: Text('Future.delay func'),
              ),
              RaisedButton(onPressed: (){
                sleep(Duration(seconds: 5));
                _audioCache.load('$test.mp3');
                _audioPlayer = await _audioCache.play('$test.mp3');
                // This works completely fine in both version
              },
                child: Text('sleep func'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

You can reproduce this bug as follows:

  1. Copy paste the above code snippet.
  2. build a release version and deploy it on any physical iOS device.
  3. Click on the buttons and lock your iPhone.

In my case, I used iPhone 8 with iOS 14.4

Are there any possible alternative solutions that would let me play music in background, when triggered by some functions in iOS?

  • @RyanHeise I did report it in the Audioplayers plugin issue. The Author themself, don't know why or what is causing it, and is seeking out more info about it. So I tried posting it here so that I can at least gather some data. – Sarthak Kore Mar 19 '21 at 14:32
  • Apologies for misunderstanding your question. It's a limitation of iOS that you can't run timers in the background (although really short timers may work). This isn't a bug in audioplayers, it's just a property of iOS. What you can do instead is create a slient audio track of the desired duration and play that. On the Android side, audioplayers does not AFAIK implement background support. As such, it will seem to work at first, but without a service, Android may kill your process after a certain amount of time has elapsed in the background. – Ryan Heise Mar 19 '21 at 15:07

0 Answers0