Better handling of sequential platform activations/deactivations.
This commit is contained in:
parent
4cab031d30
commit
9ab7d8b210
|
@ -32,7 +32,7 @@ Please consider reporting any bugs you encounter [here](https://github.com/ryanh
|
||||||
`load()` and `stop()` have new behaviours in 0.6.x documented [here](https://pub.dev/documentation/just_audio/latest/just_audio/AudioPlayer-class.html) that provide greater flexibility in how system resources are acquired and released. For a quick migration that maintains 0.5.x behaviour:
|
`load()` and `stop()` have new behaviours in 0.6.x documented [here](https://pub.dev/documentation/just_audio/latest/just_audio/AudioPlayer-class.html) that provide greater flexibility in how system resources are acquired and released. For a quick migration that maintains 0.5.x behaviour:
|
||||||
|
|
||||||
* Replace `await player.load(source);` by `await player.setAudioSource(source);`
|
* Replace `await player.load(source);` by `await player.setAudioSource(source);`
|
||||||
* Replace `await stop();` by `await player.pause(); await player.seek(Duration.zero);
|
* Replace `await stop();` by `await player.pause(); await player.seek(Duration.zero);`
|
||||||
|
|
||||||
Also beware that `playbackEventStream` will now emit events strictly when the fields in `PlaybackEvent` change. In 0.5.x this often (by chance) coincided with `playing` state changes. Apps that depended on this behaviour will break in 0.6.x and should explicitly listen for `playing` state changes via `playingStream` or `playerStateStream`.
|
Also beware that `playbackEventStream` will now emit events strictly when the fields in `PlaybackEvent` change. In 0.5.x this often (by chance) coincided with `playing` state changes. Apps that depended on this behaviour will break in 0.6.x and should explicitly listen for `playing` state changes via `playingStream` or `playerStateStream`.
|
||||||
|
|
||||||
|
|
|
@ -542,18 +542,14 @@ class AudioPlayer {
|
||||||
_playbackEventSubject.add(_playbackEvent = PlaybackEvent(
|
_playbackEventSubject.add(_playbackEvent = PlaybackEvent(
|
||||||
currentIndex: initialIndex, updatePosition: initialPosition));
|
currentIndex: initialIndex, updatePosition: initialPosition));
|
||||||
_broadcastSequence();
|
_broadcastSequence();
|
||||||
// TODO: If the active platform existed, we should try to retain it.
|
|
||||||
try {
|
|
||||||
await _setPlatformActive(false);
|
|
||||||
} catch (e) {
|
|
||||||
print("Error deactivating previous platform: $e (ignoring)");
|
|
||||||
}
|
|
||||||
_audioSource = source;
|
_audioSource = source;
|
||||||
_broadcastSequence();
|
_broadcastSequence();
|
||||||
Duration duration;
|
Duration duration;
|
||||||
if (playing) preload = true;
|
if (playing) preload = true;
|
||||||
if (preload) {
|
if (preload) {
|
||||||
duration = await load();
|
duration = await load();
|
||||||
|
} else {
|
||||||
|
await _setPlatformActive(false);
|
||||||
}
|
}
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
@ -573,8 +569,14 @@ class AudioPlayer {
|
||||||
if (_audioSource == null) {
|
if (_audioSource == null) {
|
||||||
throw Exception('Must set AudioSource before loading');
|
throw Exception('Must set AudioSource before loading');
|
||||||
}
|
}
|
||||||
|
if (_active) {
|
||||||
|
return await _load(await _platform, _audioSource,
|
||||||
|
initialSeekValues: _initialSeekValues);
|
||||||
|
} else {
|
||||||
|
// This will implicitly load the current audio source.
|
||||||
return await _setPlatformActive(true);
|
return await _setPlatformActive(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _broadcastSequence() {
|
void _broadcastSequence() {
|
||||||
_sequenceSubject.add(_audioSource?.sequence);
|
_sequenceSubject.add(_audioSource?.sequence);
|
||||||
|
@ -601,7 +603,7 @@ class AudioPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Duration> _load(AudioPlayerPlatform platform, AudioSource source,
|
Future<Duration> _load(AudioPlayerPlatform platform, AudioSource source,
|
||||||
{Duration initialPosition, int initialIndex}) async {
|
{_InitialSeekValues initialSeekValues}) async {
|
||||||
try {
|
try {
|
||||||
if (!kIsWeb && source._requiresHeaders) {
|
if (!kIsWeb && source._requiresHeaders) {
|
||||||
if (_proxy == null) {
|
if (_proxy == null) {
|
||||||
|
@ -610,18 +612,21 @@ class AudioPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await source._setup(this);
|
await source._setup(this);
|
||||||
source._shuffle(initialIndex: initialIndex ?? 0);
|
source._shuffle(initialIndex: initialSeekValues?.index ?? 0);
|
||||||
_updateShuffleIndices();
|
_updateShuffleIndices();
|
||||||
platform ??= await _platform;
|
platform ??= await _platform;
|
||||||
_durationFuture = platform
|
_durationFuture = platform
|
||||||
.load(LoadRequest(
|
.load(LoadRequest(
|
||||||
audioSourceMessage: source._toMessage(),
|
audioSourceMessage: source._toMessage(),
|
||||||
initialPosition: initialPosition,
|
initialPosition: initialSeekValues?.position,
|
||||||
initialIndex: initialIndex,
|
initialIndex: initialSeekValues?.index,
|
||||||
))
|
))
|
||||||
.then((response) => response.duration);
|
.then((response) => response.duration);
|
||||||
final duration = await _durationFuture;
|
final duration = await _durationFuture;
|
||||||
_durationSubject.add(duration);
|
_durationSubject.add(duration);
|
||||||
|
// Wait for loading state to pass.
|
||||||
|
await processingStateStream
|
||||||
|
.firstWhere((state) => state != ProcessingState.loading);
|
||||||
return duration;
|
return duration;
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
try {
|
try {
|
||||||
|
@ -653,9 +658,6 @@ class AudioPlayer {
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
));
|
));
|
||||||
// Wait for loading state to pass.
|
|
||||||
await processingStateStream
|
|
||||||
.firstWhere((state) => state != ProcessingState.loading);
|
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,11 +919,6 @@ class AudioPlayer {
|
||||||
final position = this.position;
|
final position = this.position;
|
||||||
final currentIndex = this.currentIndex;
|
final currentIndex = this.currentIndex;
|
||||||
final audioSource = _audioSource;
|
final audioSource = _audioSource;
|
||||||
final newPlatform = active
|
|
||||||
? (_nativePlatform =
|
|
||||||
JustAudioPlatform.instance.init(InitRequest(id: _id)))
|
|
||||||
: Future.value(_idlePlatform);
|
|
||||||
_playbackEventSubscription?.cancel();
|
|
||||||
final durationCompleter = Completer<Duration>();
|
final durationCompleter = Completer<Duration>();
|
||||||
_platform = Future<AudioPlayerPlatform>(() async {
|
_platform = Future<AudioPlayerPlatform>(() async {
|
||||||
if (oldPlatformFuture != null) {
|
if (oldPlatformFuture != null) {
|
||||||
|
@ -932,7 +929,11 @@ class AudioPlayer {
|
||||||
}
|
}
|
||||||
// During initialisation, we must only use this platform reference in case
|
// During initialisation, we must only use this platform reference in case
|
||||||
// _platform is updated again during initialisation.
|
// _platform is updated again during initialisation.
|
||||||
final platform = await newPlatform;
|
final platform = active
|
||||||
|
? await (_nativePlatform =
|
||||||
|
JustAudioPlatform.instance.init(InitRequest(id: _id)))
|
||||||
|
: _idlePlatform;
|
||||||
|
_playbackEventSubscription?.cancel();
|
||||||
_playbackEventSubscription =
|
_playbackEventSubscription =
|
||||||
platform.playbackEventMessageStream.listen((message) {
|
platform.playbackEventMessageStream.listen((message) {
|
||||||
var duration = message.duration;
|
var duration = message.duration;
|
||||||
|
@ -999,20 +1000,9 @@ class AudioPlayer {
|
||||||
}
|
}
|
||||||
if (audioSource != null) {
|
if (audioSource != null) {
|
||||||
try {
|
try {
|
||||||
Duration initialPosition;
|
|
||||||
int initialIndex;
|
|
||||||
if (_initialSeekValues != null) {
|
|
||||||
initialPosition = _initialSeekValues.position;
|
|
||||||
initialIndex = _initialSeekValues.index;
|
|
||||||
} else {
|
|
||||||
initialPosition = position;
|
|
||||||
initialIndex = currentIndex;
|
|
||||||
}
|
|
||||||
final duration = await _load(platform, _audioSource,
|
final duration = await _load(platform, _audioSource,
|
||||||
initialPosition: initialPosition, initialIndex: initialIndex);
|
initialSeekValues: _initialSeekValues ??
|
||||||
// Wait for loading state to pass.
|
_InitialSeekValues(position: position, index: currentIndex));
|
||||||
await processingStateStream
|
|
||||||
.firstWhere((state) => state != ProcessingState.loading);
|
|
||||||
durationCompleter.complete(duration);
|
durationCompleter.complete(duration);
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
_audioSource = null;
|
_audioSource = null;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,12 +15,12 @@ class JustAudioPlugin extends JustAudioPlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AudioPlayerPlatform> init(InitRequest request) async {
|
Future<AudioPlayerPlatform> init(InitRequest request) async {
|
||||||
final player = Html5AudioPlayer(id: request.id);
|
|
||||||
if (players.containsKey(request.id)) {
|
if (players.containsKey(request.id)) {
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: "error",
|
code: "error",
|
||||||
message: "Platform player ${request.id} already exists");
|
message: "Platform player ${request.id} already exists");
|
||||||
}
|
}
|
||||||
|
final player = Html5AudioPlayer(id: request.id);
|
||||||
players[request.id] = player;
|
players[request.id] = player;
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue