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

This plugin doesn't have events complete & error #4

Closed
cnttechio opened this issue Dec 10, 2019 · 15 comments
Closed

This plugin doesn't have events complete & error #4

cnttechio opened this issue Dec 10, 2019 · 15 comments
Assignees
Labels
1 backlog enhancement New feature or request
Projects

Comments

@cnttechio
Copy link

I just implement this plugin but i don't see function to catch event complete & error when playing audio.
Can you add features to this plugin ?

@ryanheise
Copy link
Owner

Hi @cnttechio

The play method returns a future which completes when playback completes which means you can simply await that future.

If a method fails, it should throw an exception, although this has so far been implemented only on the Android side. The iOS side does not yet handle the error cases.

Let me know if the above works for you on the Android side, and I will do more work on the iOS side.

@ryanheise ryanheise self-assigned this Dec 10, 2019
@cnttechio
Copy link
Author

Hi @ryanheise .

So cool, i got it, it working fine on the Android side. I will wait for you do more work on the iOS side.

Many thanks

@ariefwijaya
Copy link

@ryanheise How if we want to do some action after play method success ? where we gonna put the function since the play method await until paused or stop.

@ryanheise
Copy link
Owner

@ariefwijaya , almost all errors can be caught on the initial load (during setUrl) and the rest can be caught asynchronously during playback since the errors are also emitted on the stream. On iOS I've currently only implemented the first category of errors on setUrl but Android also reports asynchronous errors.

You should not expect play to fail immediately since the prior call to setUrl would have already started reading and buffering audio in order to at least determine the duration of the audio.

@ariefwijaya
Copy link

@ryanheise Okay, Thankyou for detail explanation. So, we can determine the play event will be failed or not in setUrl callback,

@Sauceee
Copy link

Sauceee commented Jun 14, 2020

@ryanheise I currently have also trouble to catch errors. Currently just testing on android. How do I catch asynchronous errors?

For example, if I play an url audio file and turn off the internet connection and do a seek after that, I only get the following in the console:

E/ExoPlayerImplInternal(11872): Source error E/ExoPlayerImplInternal(11872): UnknownHostException (no network) E/AudioPlayer(11872): TYPE_SOURCE: Unable to connect E/flutter (11872): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(0, com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect, null)

But I don't know how to catch it in my code. Could you give an advice, please? I cannot find an error attribute in any streams or methods.

Edit: Just tested further, AudioPlaybackState is still showing AudioPlaybackState.playing or AudioPlaybackState.paused and the play method also does not throw errors.

@ryanheise
Copy link
Owner

Hi @Sauceee

The Dart tutorial on streams may be helpful with regards to error handling: https://dart.dev/tutorials/language/streams

Edit: Just tested further, AudioPlaybackState is still showing AudioPlaybackState.playing or AudioPlaybackState.paused and the play method also does not throw errors.

Updating the playing state and also having play throw an exception both sound like good ideas. I'll consider them for the future.

@Sauceee
Copy link

Sauceee commented Jun 15, 2020

@ryanheise Thank you, that helped!

@na-si
Copy link

na-si commented Jul 14, 2020

@ryanheise I currently have also trouble to catch errors. Currently just testing on android. How do I catch asynchronous errors?

For example, if I play an url audio file and turn off the internet connection and do a seek after that, I only get the following in the console:

E/ExoPlayerImplInternal(11872): Source error E/ExoPlayerImplInternal(11872): UnknownHostException (no network) E/AudioPlayer(11872): TYPE_SOURCE: Unable to connect E/flutter (11872): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(0, com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect, null)

But I don't know how to catch it in my code. Could you give an advice, please? I cannot find an error attribute in any streams or methods.

Edit: Just tested further, AudioPlaybackState is still showing AudioPlaybackState.playing or AudioPlaybackState.paused and the play method also does not throw errors.

@Sauceee , Did you find any solution? Unfortunately, I have the same problem

@ryanheise
Copy link
Owner

@nsilina If you you're just playing a simple audio file, not a stream, you can do this:

try {
  await audioPlayer.setUrl(....);
} catch (e) {
  ...
}

If you're playing a stream, errors can occur at any time after the initial loading, so you need to listen to errors on the stream (see the link I provided above if you need to learn more about streams).

@Sauceee
Copy link

Sauceee commented Jul 14, 2020

@nsilina Yes, with the link provided by @ryanheise I came up with the following implementation:

  @override
  Future<void> onStart(Map<String, dynamic> params) async {
    _playerStateSubscription = _audioPlayer.playbackStateStream
        .where((state) => state == AudioPlaybackState.completed)
        .listen((state) {
      _handlePlaybackCompleted();
    });

    _eventSubscription = _audioPlayer.playbackEventStream.listen((event) {
      var state = event.buffering ? AudioProcessingState.buffering : AudioProcessingState.ready;

      switch (event.state) {
        case AudioPlaybackState.paused:
          _setState(processingState: state, position: event.position);
          break;
        case AudioPlaybackState.playing:
          _setState(processingState: state, position: event.position);
          break;
        case AudioPlaybackState.connecting:
          _setState(processingState: AudioProcessingState.connecting);
          break;
        default:
          break;
      }
    }, onError: (e) async {
      if (e is PlatformException && e.code == "abort" && e.message == "Connection aborted") return;
      _error = true;

      if (_audioPlayer.playbackState != AudioPlaybackState.none) {
        await _audioPlayer.stop();
      }

      await _setState(processingState: AudioProcessingState.error);
    });
  }

@na-si
Copy link

na-si commented Jul 14, 2020

@Sauceee , thank you

@ryanheise
Copy link
Owner

Just to update on the iOS side of things, catching errors on the setUrl future has been working already for a while and is available in the current release.

As for handling asynchronous errors on the stream, this is also now implemented on the media-source branch. Issues on this branch are being tracked on #131 so if you discover any issues, please report there. Note that #131 bundles a significant number of features and therefore needs some testing. There is also a planned API change to watch out for in which I intend to make just_audio's state model more closely align with audio_service in terms of buffering.

I will close this issue, and will use #131 for tracking any bugs related to the media-source branch.

@parthghedia
Copy link

@nsilina Yes, with the link provided by @ryanheise I came up with the following implementation:

  @override
  Future<void> onStart(Map<String, dynamic> params) async {
    _playerStateSubscription = _audioPlayer.playbackStateStream
        .where((state) => state == AudioPlaybackState.completed)
        .listen((state) {
      _handlePlaybackCompleted();
    });

    _eventSubscription = _audioPlayer.playbackEventStream.listen((event) {
      var state = event.buffering ? AudioProcessingState.buffering : AudioProcessingState.ready;

      switch (event.state) {
        case AudioPlaybackState.paused:
          _setState(processingState: state, position: event.position);
          break;
        case AudioPlaybackState.playing:
          _setState(processingState: state, position: event.position);
          break;
        case AudioPlaybackState.connecting:
          _setState(processingState: AudioProcessingState.connecting);
          break;
        default:
          break;
      }
    }, onError: (e) async {
      if (e is PlatformException && e.code == "abort" && e.message == "Connection aborted") return;
      _error = true;

      if (_audioPlayer.playbackState != AudioPlaybackState.none) {
        await _audioPlayer.stop();
      }

      await _setState(processingState: AudioProcessingState.error);
    });
  }

@ryanheise @Sauceee when I try this await _setState(processingState: AudioProcessingState.error); it changes to error state for a brief moment and then switches back to AudioProcessingState.ready
What can I do for this?

@github-actions
Copy link

github-actions bot commented Nov 3, 2021

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with just_audio.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
1 backlog enhancement New feature or request
Projects
No open projects
just_audio
  
To do
Development

No branches or pull requests

6 participants