-
-
Notifications
You must be signed in to change notification settings - Fork 504
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
@ryanheise I'm experiencing an issue with multiple isolates running in version 0.7.2. When I start AudioService, two isolates are created:
- _flutterIsolateEntryPoint
- _backgroundCallbackDispatcher
When I call stop on AudioService, future is completed and isolates should be terminated/killed. But they are still running. Now I call start again and two new isolates are running, see screenshot:
Entrypoint:
static void initBackgroundIsolate() {
AudioServiceBackground.run(() => MediaBackgroundTask());
}
class MediaBackgroundTask extends BackgroundAudioTask {
/// Future completer
final Completer _completer = Completer();
/// Audio player instance
final AudioPlayer _audioPlayer = AudioPlayer();
/// Playable media item
MediaItem _media;
/// Is media playing?
bool _playing = false;
/// Stream subscriptions from audio player
StreamSubscription _maxDurationSub;
StreamSubscription _positionChangedSub;
/// Initializes media playback
@override
Future<void> onStart() async {
log("Starting background isolate...");
/// Broadcast init state with controls
log("Setting state to buffering");
AudioServiceBackground.setState(
controls: [stopControl],
basicState: BasicPlaybackState.buffering,
systemActions: [MediaAction.stop],
);
/// Wait until thread completes
await _completer.future;
log("Isolate lifecycle end!");
/// Cancel all subscriptions
_maxDurationSub?.cancel();
_positionChangedSub?.cancel();
// Release media player
log("Releasing media player resources");
_audioPlayer.release();
}
/// Handler for pause action
@override
void onPause() async {
/// Pause audio playback
log("PAUSE --> pausing playback");
await _audioPlayer.pause();
/// Notify that we are in paused state with controls
log("PAUSE --> Setting state to paused");
await AudioServiceBackground.setState(
controls: [playControl],
basicState: BasicPlaybackState.paused,
systemActions: [MediaAction.play],
);
}
/// Handler for adding queue item
@override
void onAddQueueItem(MediaItem mediaItem) async {
/// Set media item
_media = mediaItem;
await AudioServiceBackground.setMediaItem(mediaItem);
log("ON_ADD_QUEUE_ITEM --> Setting media item to ${mediaItem.title}");
/// Prepare audio player handling
if (!mediaItem.extras["is_stream"]) {
_maxDurationSub = _audioPlayer.onDurationChanged.listen((Duration p) async {
log("ON_ADD_QUEUE_ITEM --> Track duration loaded: $p");
/// Create new media item
_media = _media.copyWith(duration: p.inMilliseconds);
await AudioServiceBackground.setMediaItem(_media);
/// Send message to UI
SendPort sendPort = IsolateNameServer.lookupPortByName("media_background_task:msg_api");
sendPort?.send({
"type": "track_duration_loaded",
"data": {
"duration_milliseconds": p.inMilliseconds,
}
});
});
_positionChangedSub = _audioPlayer.onAudioPositionChanged.listen((Duration p) async {
log("ON_ADD_QUEUE_ITEM --> Audio position changed to $p");
// _position = p;
await AudioServiceBackground.setState(
controls: [],
basicState: AudioServiceBackground.state.basicState,
position: p.inMilliseconds,
systemActions: [
MediaAction.pause,
MediaAction.stop,
]);
});
}
// on playback complete
_audioPlayer.onPlayerCompletion.listen((event) {
log("ON_ADD_QUEUE_ITEM --> Playback is complete, calling onStop()");
onStop();
});
}
/// Handler for play action
@override
void onPlay() async {
/// If media is not playing, play
if (!_playing) {
log("PLAY --> Media is not playing, calling play() {uuid: ${_media.extras["uuid"]}}");
await _audioPlayer.play(_media.id);
_playing = true;
} else {
log("PLAY --> Media is playing, calling resume() {uuid: ${_media.extras["uuid"]}}");
await _audioPlayer.resume();
}
log("PLAY --> Setting state to playing");
await AudioServiceBackground.setState(
controls: [pauseControl],
basicState: BasicPlaybackState.playing,
systemActions: [MediaAction.pause],
);
}
/// Handler for stop action
/// This will end background task isolate.
@override
void onStop() async {
log("STOP --> Stopping playback");
/// Stop audio playback
await _audioPlayer.stop();
/// Broadcast stopped state
log("STOP --> Setting state to stopped");
await AudioServiceBackground.setState(controls: [], basicState: BasicPlaybackState.stopped);
/// End isolate life
log("STOP --> Ending background isolate life!");
_completer.complete();
}
/// Handle for seek action
@override
void onSeekTo(int position) async {
log("SEEK --> Seeking to ${Duration(milliseconds: position).formatForPlayer()}");
/// Pause playback
await _audioPlayer.pause();
/// Seek to position
await _audioPlayer.seek(Duration(milliseconds: position));
/// Resume playback
await _audioPlayer.resume();
}
/// Logging method
void log(String msg) {
debugPrint("[MEDIA_SERVICE_BACKGROUND] ---> $msg");
}
}
Is there something wrong in my code, or it is a bug in this package?
I'm running iOS 13.4, Flutter dev channel, here is output from flutter doctor
:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel dev, v1.18.0, on Mac OS X 10.15.4 19E287, locale cs-CZ)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.6)
[✓] VS Code (version 1.44.2)
[✓] Connected device (3 available)
• No issues found!
Thanks!
sc4v3ng3r
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working