Update state before method channel calls complete.
This commit is contained in:
parent
b10583e8d6
commit
5e9a707e08
|
@ -115,9 +115,9 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||||
if (prepareResult != null) {
|
if (prepareResult != null) {
|
||||||
duration = player.getDuration();
|
duration = player.getDuration();
|
||||||
justConnected = true;
|
justConnected = true;
|
||||||
|
transition(PlaybackState.stopped);
|
||||||
prepareResult.success(duration);
|
prepareResult.success(duration);
|
||||||
prepareResult = null;
|
prepareResult = null;
|
||||||
transition(PlaybackState.stopped);
|
|
||||||
}
|
}
|
||||||
if (seekProcessed) {
|
if (seekProcessed) {
|
||||||
completeSeek();
|
completeSeek();
|
||||||
|
|
|
@ -92,7 +92,7 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.1.4"
|
version: "0.1.5"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -233,31 +233,60 @@ class AudioPlayer {
|
||||||
/// * [AudioPlaybackState.connecting]
|
/// * [AudioPlaybackState.connecting]
|
||||||
/// * [AudioPlaybackState.none]
|
/// * [AudioPlaybackState.none]
|
||||||
Future<void> play() async {
|
Future<void> play() async {
|
||||||
StreamSubscription subscription;
|
switch (playbackState) {
|
||||||
Completer completer = Completer();
|
case AudioPlaybackState.playing:
|
||||||
bool startedPlaying = false;
|
case AudioPlaybackState.stopped:
|
||||||
subscription = playbackStateStream.listen((state) {
|
case AudioPlaybackState.completed:
|
||||||
// TODO: It will be more reliable to let the platform
|
case AudioPlaybackState.paused:
|
||||||
// side wait for completion since events on the flutter
|
// Update local state immediately so that queries aren't surprised.
|
||||||
// side can lag behind the platform side.
|
_audioPlaybackEvent = _audioPlaybackEvent.copyWith(
|
||||||
if (startedPlaying &&
|
state: AudioPlaybackState.playing,
|
||||||
(state == AudioPlaybackState.paused ||
|
);
|
||||||
state == AudioPlaybackState.stopped ||
|
StreamSubscription subscription;
|
||||||
state == AudioPlaybackState.completed)) {
|
Completer completer = Completer();
|
||||||
subscription.cancel();
|
bool startedPlaying = false;
|
||||||
completer.complete();
|
subscription = playbackStateStream.listen((state) {
|
||||||
} else if (state == AudioPlaybackState.playing) {
|
// TODO: It will be more reliable to let the platform
|
||||||
startedPlaying = true;
|
// side wait for completion since events on the flutter
|
||||||
}
|
// side can lag behind the platform side.
|
||||||
});
|
if (startedPlaying &&
|
||||||
await _invokeMethod('play');
|
(state == AudioPlaybackState.paused ||
|
||||||
await completer.future;
|
state == AudioPlaybackState.stopped ||
|
||||||
|
state == AudioPlaybackState.completed)) {
|
||||||
|
subscription.cancel();
|
||||||
|
completer.complete();
|
||||||
|
} else if (state == AudioPlaybackState.playing) {
|
||||||
|
startedPlaying = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await _invokeMethod('play');
|
||||||
|
await completer.future;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception(
|
||||||
|
"Cannot call play from connecting/none states ($playbackState)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pauses the currently playing media. It is legal to invoke this method
|
/// Pauses the currently playing media. It is legal to invoke this method
|
||||||
/// only from the [AudioPlaybackState.playing] state.
|
/// only from the [AudioPlaybackState.playing] state.
|
||||||
Future<void> pause() async {
|
Future<void> pause() async {
|
||||||
await _invokeMethod('pause');
|
switch (playbackState) {
|
||||||
|
case AudioPlaybackState.paused:
|
||||||
|
break;
|
||||||
|
case AudioPlaybackState.playing:
|
||||||
|
// Update local state immediately so that queries aren't surprised.
|
||||||
|
_audioPlaybackEvent = _audioPlaybackEvent.copyWith(
|
||||||
|
state: AudioPlaybackState.paused,
|
||||||
|
);
|
||||||
|
// TODO: For pause, perhaps modify platform side to ensure new state
|
||||||
|
// is broadcast before this method returns.
|
||||||
|
await _invokeMethod('pause');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception(
|
||||||
|
"Can call pause only from playing and buffering states ($playbackState)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stops the currently playing media such that the next [play] invocation
|
/// Stops the currently playing media such that the next [play] invocation
|
||||||
|
@ -268,7 +297,24 @@ class AudioPlayer {
|
||||||
/// * [AudioPlaybackState.paused]
|
/// * [AudioPlaybackState.paused]
|
||||||
/// * [AudioPlaybackState.completed]
|
/// * [AudioPlaybackState.completed]
|
||||||
Future<void> stop() async {
|
Future<void> stop() async {
|
||||||
await _invokeMethod('stop');
|
switch (playbackState) {
|
||||||
|
case AudioPlaybackState.stopped:
|
||||||
|
break;
|
||||||
|
case AudioPlaybackState.connecting:
|
||||||
|
case AudioPlaybackState.completed:
|
||||||
|
case AudioPlaybackState.playing:
|
||||||
|
case AudioPlaybackState.paused:
|
||||||
|
// Update local state immediately so that queries aren't surprised.
|
||||||
|
// NOTE: Android implementation already handles this.
|
||||||
|
// TODO: Do the same for iOS so the line below becomes unnecessary.
|
||||||
|
_audioPlaybackEvent = _audioPlaybackEvent.copyWith(
|
||||||
|
state: AudioPlaybackState.paused,
|
||||||
|
);
|
||||||
|
await _invokeMethod('stop');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception("Cannot call stop from none state");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the volume of this player, where 1.0 is normal volume.
|
/// Sets the volume of this player, where 1.0 is normal volume.
|
||||||
|
@ -354,6 +400,25 @@ class AudioPlaybackEvent {
|
||||||
@required this.duration,
|
@required this.duration,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AudioPlaybackEvent copyWith({
|
||||||
|
AudioPlaybackState state,
|
||||||
|
bool buffering,
|
||||||
|
Duration updateTime,
|
||||||
|
Duration updatePosition,
|
||||||
|
Duration bufferedPosition,
|
||||||
|
double speed,
|
||||||
|
Duration duration,
|
||||||
|
}) =>
|
||||||
|
AudioPlaybackEvent(
|
||||||
|
state: state ?? this.state,
|
||||||
|
buffering: buffering ?? this.buffering,
|
||||||
|
updateTime: updateTime ?? this.updateTime,
|
||||||
|
updatePosition: updatePosition ?? this.updatePosition,
|
||||||
|
bufferedPosition: bufferedPosition ?? this.bufferedPosition,
|
||||||
|
speed: speed ?? this.speed,
|
||||||
|
duration: duration ?? this.duration,
|
||||||
|
);
|
||||||
|
|
||||||
/// The current position of the player.
|
/// The current position of the player.
|
||||||
Duration get position {
|
Duration get position {
|
||||||
if (state == AudioPlaybackState.playing && !buffering) {
|
if (state == AudioPlaybackState.playing && !buffering) {
|
||||||
|
|
Loading…
Reference in New Issue