2

My implementation loops in the foreground. It also works in the background. The issue is it does NOT loop in the background. The issue happens only on iOS physical device (not on Simulator, nor Android).

I'm using https://pub.dev/packages/audioplayers plugin since https://pub.dev/packages/just_audio was giving me all sorts of troubles especially with badly done audio caching which in the end always made every audio delay in the beginning of a track which was a no go for my case.

This is my audio_player_handler.dart file:

import 'package:ambee2/models/animations/light_animation.dart';
import 'package:audio_service/audio_service.dart';
import 'package:flutter/material.dart';
// import 'package:just_audio/just_audio.dart';
import 'package:audioplayers/audioplayers.dart';

class AudioPlayerHandler extends BaseAudioHandler {
  final _player = AudioPlayer();

  AudioPlayerHandler() {
    //set the audio to repeat itself once it's done
    _player.setReleaseMode(ReleaseMode.LOOP);
  }

  Future<void> setUrl(String url) async => await _player.setUrl(url);

  Future<void> playUrl(String url, double volumeValue) => _player.play(url, volume: volumeValue);

  Future<void> resume() => _player.resume();

  @override
  Future<void> pause() => _player.pause();

  @override
  Future<void> stop() => _player.stop();

  Future<void> setVolume(double newValue) => _player.setVolume(newValue);
}

I also have objects called: LightAnimation that has a property audioHandler defined like this:

class LightAnimation {
  AudioPlayerHandler audioHandler = AudioPlayerHandler();

  LightAnimation({
    this.audioUrl,
  });
}

Then I just access from a different part of my codebase like this:

await lightAnimation.audioHandler.playUrl(lightAnimation.audioUrl, volumeSetValue);

Is my implementation wrong or is it just bug on a package side (https://pub.dev/packages/audioplayers)?

Tomas Baran
  • 1,570
  • 2
  • 20
  • 37
  • So your question is whether it is a bug on audio_service or on audioplayers? You already reported the bug on audio_service and the author confirmed that it was not an audio_service bug. You might want to update your question accordingly to focus it as a question about audioplayers specifically. – Ryan Heise Dec 09 '21 at 05:20
  • Ryan, if you are sure, my problem is in my implementation, would you please be so kind and tell me and others what's wrong with my implementation. Or even better, how to do it correctly — how to set up background looping correctly. In any case, this should be a pretty good sign there is a part about it missing in the documentation. – Tomas Baran Dec 16 '21 at 20:43
  • 1
    @TomasBaran, if you run the example in the `just_audio_background` plugin (https://pub.dev/packages/just_audio_background), which uses `just_audio` and `audio_service` under the hood, you will notice that the repeat mode DOES work on iOS device in the background. So the problem is either with your implementation (not shown in the code you posted) or in `audioplayers`. – Michele Volpato Dec 17 '21 at 13:13
  • Please check this https://denis-korovitskii.medium.com/flutter-demo-audioplayers-on-background-via-audio-service-c95d65c90ae1 – Ahmed Raza Dec 22 '21 at 11:26
  • @AhmedRaza thanks! I've seen this article, however it's outdated. It uses many deprecated stuff that is not aplicable any more. On top of that it discusses how to implement background which I already have and it works great. What does NOT work is the loop in the background which is NOT addressed at all in the article. – Tomas Baran Dec 22 '21 at 13:49
  • It looks like it's a bug on the plugin's side: https://github.com/bluefireteam/audioplayers/issues/1038 From doing more research, there are multiple duplicate issues that address the same problem. Unfortunately, these issues have been hanging for almost two years and the author has NOT commented on them at all. What is even worse, I cannot use any other package: First I tried `just_audio` plugin but their buffer doesn't work well, whereas `audioplayers` buffer works great. – Tomas Baran Dec 22 '21 at 13:52

2 Answers2

1

In my case it worked in IOS background physical devices. I followed this tutorial by Suragch. Check out his final repo.

In audio_handler.dart

@override
Future<void> setRepeatMode(AudioServiceRepeatMode repeatMode) async {
    switch (repeatMode) {
      case AudioServiceRepeatMode.none:
        _player.setLoopMode(LoopMode.off);
        break;
      case AudioServiceRepeatMode.one:
        _player.setLoopMode(LoopMode.one);
        break;
      case AudioServiceRepeatMode.group:
      case AudioServiceRepeatMode.all:
        _player.setLoopMode(LoopMode.all);
        break;
    }
  }

In page_manager.dart

  void repeat() {
    repeatButtonNotifier.nextState();
    final repeatMode = repeatButtonNotifier.value;
    switch (repeatMode) {
      case RepeatState.off:
        _audioHandler.setRepeatMode(AudioServiceRepeatMode.none);
        break;
      case RepeatState.repeatSong:
        _audioHandler.setRepeatMode(AudioServiceRepeatMode.one);
        break;
      case RepeatState.repeatPlaylist:
        _audioHandler.setRepeatMode(AudioServiceRepeatMode.all);
        break;
}

You can customize repeat() as your needs.

_audioHandler.setRepeatMode(AudioServiceRepeatMode.one)
XiaoHui
  • 53
  • 6
  • What plugin are you using? Are you using https://pub.dev/packages/audioplayers? I'm asking because `audioplayers` plugin does not have `setRepeatMode` method. – Tomas Baran Jan 13 '22 at 13:21
  • @TomasBaran I am using [pub.dev/packages/just_audio](https://pub.dev/packages/just_audio). It provides such function. – XiaoHui Jan 15 '22 at 10:22
  • Thanks, however https://pub.dev/packages/just_audio was giving me all sorts of troubles especially with badly done audio caching which in the end always made every audio delay in the beginning of a track which was a no go for my case. – Tomas Baran Jan 16 '22 at 11:32
0

I am not an expert of audioplayers, but you can try to add the override

@override
  Future<void> setRepeatMode(AudioServiceRepeatMode repeatMode) async {
    var releaseMode = ReleaseMode.LOOP;
    switch(repeatMode) {
       ...
       // update releaseMode here
    }
    await _player.setReleaseMode(releaseMode);
}

But I doubt this will solve the problem.

Michele Volpato
  • 700
  • 6
  • 14