@@ -57,6 +57,7 @@ JustAudioPlatform get _pluginPlatform {
57
57
/// player, including any temporary files created to cache assets.
58
58
class AudioPlayer {
59
59
static String _generateId () => _uuid.v4 ();
60
+ final _lock = Lock ();
60
61
61
62
/// The user agent to set on all HTTP requests.
62
63
final String ? _userAgent;
@@ -1373,61 +1374,64 @@ class AudioPlayer {
1373
1374
1374
1375
/// Releases all resources associated with this player. You must invoke this
1375
1376
/// after you are done with the player.
1376
- Future <void > dispose () async {
1377
- if (_disposed) return ;
1378
- _disposed = true ;
1379
- if (_nativePlatform != null ) {
1380
- await _disposePlatform (await _nativePlatform! );
1381
- _nativePlatform = null ;
1382
- }
1383
- if (_idlePlatform != null ) {
1384
- await _disposePlatform (_idlePlatform! );
1385
- _idlePlatform = null ;
1386
- }
1387
- _playlist.children.clear ();
1388
- for (var s in _audioSources.values) {
1389
- s._dispose ();
1390
- }
1391
- _audioSources.clear ();
1392
- _proxy.stop ();
1393
- await _playerDataSubscription? .cancel ();
1394
- await _playbackEventSubscription? .cancel ();
1395
- await _androidAudioAttributesSubscription? .cancel ();
1396
- await _becomingNoisyEventSubscription? .cancel ();
1397
- await _interruptionEventSubscription? .cancel ();
1398
- await _positionDiscontinuitySubscription? .cancel ();
1399
- await _currentIndexSubscription? .cancel ();
1400
- await _errorsSubscription? .cancel ();
1401
- await _errorsResetSubscription? .cancel ();
1402
-
1403
- await _playbackEventSubject.close ();
1404
- await _sequenceStateSubject.close ();
1405
- await _playingSubject.close ();
1406
- await _volumeSubject.close ();
1407
- await _speedSubject.close ();
1408
- await _pitchSubject.close ();
1409
-
1410
- await Future <void >.delayed (Duration .zero);
1411
- await _durationSubject.close ();
1412
- await _processingStateSubject.close ();
1413
- await _bufferedPositionSubject.close ();
1414
- await _icyMetadataSubject.close ();
1415
- await _androidAudioSessionIdSubject.close ();
1416
- await _errorSubject.close ();
1417
- await _playerStateSubject.close ();
1418
- await _skipSilenceEnabledSubject.close ();
1419
- await _positionDiscontinuitySubject.close ();
1420
- await _sequenceSubject.close ();
1421
- await _shuffleIndicesSubject.close ();
1422
- await _currentIndexSubject.close ();
1423
- await _loopModeSubject.close ();
1424
- await _shuffleModeEnabledSubject.close ();
1425
- await _shuffleModeEnabledSubject.close ();
1426
-
1427
- if (playbackEvent.processingState != ProcessingState .idle) {
1428
- _playbackEventSubject
1429
- .add (playbackEvent.copyWith (processingState: ProcessingState .idle));
1430
- }
1377
+ Future <void > dispose () {
1378
+ return _lock.synchronized (() async {
1379
+ if (_disposed) return ;
1380
+ await stop ();
1381
+ _disposed = true ;
1382
+ if (_nativePlatform != null ) {
1383
+ await _disposePlatform (await _nativePlatform! );
1384
+ _nativePlatform = null ;
1385
+ }
1386
+ if (_idlePlatform != null ) {
1387
+ await _disposePlatform (_idlePlatform! );
1388
+ _idlePlatform = null ;
1389
+ }
1390
+ _playlist.children.clear ();
1391
+ for (var s in _audioSources.values) {
1392
+ s._dispose ();
1393
+ }
1394
+ _audioSources.clear ();
1395
+ _proxy.stop ();
1396
+ await _playerDataSubscription? .cancel ();
1397
+ await _playbackEventSubscription? .cancel ();
1398
+ await _androidAudioAttributesSubscription? .cancel ();
1399
+ await _becomingNoisyEventSubscription? .cancel ();
1400
+ await _interruptionEventSubscription? .cancel ();
1401
+ await _positionDiscontinuitySubscription? .cancel ();
1402
+ await _currentIndexSubscription? .cancel ();
1403
+ await _errorsSubscription? .cancel ();
1404
+ await _errorsResetSubscription? .cancel ();
1405
+
1406
+ await _playbackEventSubject.close ();
1407
+ await _sequenceStateSubject.close ();
1408
+ await _playingSubject.close ();
1409
+ await _volumeSubject.close ();
1410
+ await _speedSubject.close ();
1411
+ await _pitchSubject.close ();
1412
+
1413
+ await Future <void >.delayed (Duration .zero);
1414
+ await _durationSubject.close ();
1415
+ await _processingStateSubject.close ();
1416
+ await _bufferedPositionSubject.close ();
1417
+ await _icyMetadataSubject.close ();
1418
+ await _androidAudioSessionIdSubject.close ();
1419
+ await _errorSubject.close ();
1420
+ await _playerStateSubject.close ();
1421
+ await _skipSilenceEnabledSubject.close ();
1422
+ await _positionDiscontinuitySubject.close ();
1423
+ await _sequenceSubject.close ();
1424
+ await _shuffleIndicesSubject.close ();
1425
+ await _currentIndexSubject.close ();
1426
+ await _loopModeSubject.close ();
1427
+ await _shuffleModeEnabledSubject.close ();
1428
+ await _shuffleModeEnabledSubject.close ();
1429
+
1430
+ if (playbackEvent.processingState != ProcessingState .idle) {
1431
+ _playbackEventSubject
1432
+ .add (playbackEvent.copyWith (processingState: ProcessingState .idle));
1433
+ }
1434
+ });
1431
1435
}
1432
1436
1433
1437
/// Switches to using the native platform when [active] is `true` and using the
0 commit comments