Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PlayerMode.lowLatency and setReleaseMode don't work together (Android) #1489

Closed
2 tasks done
wujek-srujek opened this issue May 6, 2023 · 2 comments
Closed
2 tasks done
Labels
docs Concerning the documentation platform-android Affects the android platform

Comments

@wujek-srujek
Copy link
Contributor

wujek-srujek commented May 6, 2023

Checklist

  • I read the troubleshooting guide before raising this issue
  • I made sure that the issue I am raising doesn't already exist

Current bug behaviour

TL;DR
On Android, when both AudioPlayer.setPlayerMode(PlayerMode.lowLatency) and AudioPlayer.setReleaseMode(ReleaseMode.stop) are used for the same player, the sound is played only the first time. Please see the attached application.

Context: I have a simple app that prepares 2 players, with a different, very short sound (from assets) each, and it keeps them around and uses them whenever one of the sounds should be played, ideally with as little delay as possible. It is impossible for the same sound to overlap, but there can be an overlap between the two sounds, hence 2 players.

I want to use low latency on Android, but at the same time, I want to be able to play a sound with just AudioPlayer.resume() using the pre-initialized players. This seems not to work together - the sound is only played the first time. I suppose the reason is that low latency disables all streams, and the streams are necessary for the player to get the playback completion signal using onComplete, and reset the sound (otherwise the sound is at its end and resuming playback immediately finishes).

As a result, it seems to be impossible to do what I want. One option is to disable low latency (which would defeat its purpose), or use low latency, but then create a new player each time a sound should be played, introducing latency due to initialization (AudioPlayer.setSourceAsset and others are async calls that go through the whole MethodChannel magic).

I hope that you find my mistake in the snippet, or in my thinking, and come up with a working solution. But it is possible that this is the desired (or only possible) behavior, in which case I think documentation is lacking - e.g. here (https://github.com/bluefireteam/audioplayers/blob/main/getting_started.md?plain=1#L166) it mentions what gets disabled, and it doesn't mention the completion signal. If this bug gets classified as invalid, the docs could/should be updated.

Expected behaviour

I expect the same AudioPlayer instance to play the sound each time, with low latency.

Steps to reproduce

Run the snippet as you usually would. You will need to add a sound as assets/audio/short_sound.mp3, I link below to the one I'm using.

Code sample

Code sample
import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final player = await initPlayer();
  runApp(PlayerApp(player: player));
}

Future<AudioPlayer> initPlayer() async {
  final player = AudioPlayer();

  await Future.wait([
    player.setPlayerMode(PlayerMode.lowLatency),
    player.setSourceAsset('audio/short_sound.mp3'),
    player.setReleaseMode(ReleaseMode.stop),
  ]);

  return player;
}

class PlayerApp extends StatelessWidget {
  final AudioPlayer player;

  const PlayerApp({required this.player});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Center(
        child: ElevatedButton(
          onPressed: () async => player.resume(),
          child: const Text('Play'),
        ),
      ),
    );
  }
}

Affected platforms

Android

Platform details

Android 13, Pixel 7 Pro

The setting, according to the docs, is only relevant to Anroid.

AudioPlayers Version

4.0.1

Build mode

debug, release

Audio Files/URLs/Sources

https://www.zedge.net/ringtone/99a9a13c-2881-32ff-aa8b-84302fb3532c

Screenshots

No response

Logs

There are no relevant logs.

Related issues / more information

No response

Working on PR

no way

@Gustl22 Gustl22 added the platform-android Affects the android platform label May 7, 2023
@Gustl22
Copy link
Collaborator

Gustl22 commented Jul 25, 2023

You have to call stop before calling resume as in LowLatency mode, the player doesn't know when the sound finished, further there is no onComplete event available. So the user needs to stop the player, before be able to resume again.

@Gustl22 Gustl22 added docs Concerning the documentation and removed bug labels Jul 25, 2023
@wujek-srujek
Copy link
Contributor Author

I now call stop before resume and it works for me. I suppose this ticket can be closed?

@Gustl22 Gustl22 closed this as completed Sep 26, 2023
@Gustl22 Gustl22 mentioned this issue Nov 25, 2023
7 tasks
Gustl22 added a commit that referenced this issue Nov 25, 2023
# Description

Improve the documentation for:

- Getting started: 
  - Fix typos from #1678
  - Call stop in low latency, missing completion event (#1489)
  - Set prefix for AssetSource via AudioCache (#1620, #1639)
- Troubleshooting guide:
  - Verify audio format, e.g. with Aconvert
  - Change heading size of web-cors-policy
- Example:
  - README: How to setup example with `melos`, tab descriptions
- example.md: Add Simple (one-page) Example for pub.dev, see
https://dart.dev/tools/pub/package-layout#examples (#1616)
  - Showcase for using play in `addPostFrameCallback`

Closes #1650

Co-authored-by: Lukas Klingsbo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Concerning the documentation platform-android Affects the android platform
Projects
None yet
Development

No branches or pull requests

3 participants
@wujek-srujek @Gustl22 and others