play method

StreamSubscription<void> play(
  1. AudioSource music, {
  2. Duration fade = Duration.zero,
})

Plays the provided music looped with the specified fade.

Stopping the music means canceling the returned StreamSubscription.

Implementation

StreamSubscription<void> play(
  AudioSource music, {
  Duration fade = Duration.zero,
}) {
  Log.debug('play($music)', '$runtimeType');

  StreamController? controller = _players[music];
  StreamSubscription? playback;

  if (controller == null) {
    ja.AudioPlayer? jaPlayer;
    Timer? timer;

    controller = StreamController.broadcast(
      onListen: () async {
        if (PlatformUtils.isWeb) {
          playback?.cancel();
          playback = WebUtils.play(
            '${music.direct}?${Pubspec.ref}',
            loop: true,
          ).listen((_) {});

          return;
        }

        try {
          jaPlayer = ja.AudioPlayer();
        } catch (e) {
          // If [Player] isn't available on the current platform, this throws
          // a `null check operator used on a null value`.
          if (e is! TypeError) {
            Log.error(
              'Failed to initialize `Player`: ${e.toString()}',
              '$runtimeType',
            );
          }
        }

        await jaPlayer?.setAudioSource(music.source);
        await jaPlayer?.setLoopMode(ja.LoopMode.all);
        await jaPlayer?.play();

        if (fade != Duration.zero) {
          await jaPlayer?.setVolume(0);

          timer = Timer.periodic(
            Duration(microseconds: fade.inMicroseconds ~/ 10),
            (timer) async {
              if (timer.tick > 9) {
                timer.cancel();
              } else {
                await jaPlayer?.setVolume((timer.tick + 1) / 10);
              }
            },
          );
        }
      },
      onCancel: () async {
        if (PlatformUtils.isWeb) {
          playback?.cancel();
          return;
        }

        _players.remove(music);
        timer?.cancel();

        Future<void>? dispose = jaPlayer?.dispose();
        jaPlayer = null;
        await dispose;
      },
    );

    _players[music] = controller;
  }

  return controller.stream.listen((_) {});
}