From 76090a46b6723f60f0cfb482caa3b85a004b29ba Mon Sep 17 00:00:00 2001 From: JiWoong Sul Date: Thu, 8 Jan 2026 19:54:43 +0900 Subject: [PATCH] =?UTF-8?q?fix(audio):=20BGM=20=EB=8F=99=EC=8B=9C=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EB=B3=B4=ED=98=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _isBgmBusy 락으로 동시 작업 방지 - 대기열(_queuedBgm)로 마지막 요청만 처리 - Loading interrupted 에러 시 플레이어 재생성 방지 --- lib/src/core/audio/audio_service.dart | 41 ++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/lib/src/core/audio/audio_service.dart b/lib/src/core/audio/audio_service.dart index 2acdb54..dd470e4 100644 --- a/lib/src/core/audio/audio_service.dart +++ b/lib/src/core/audio/audio_service.dart @@ -85,6 +85,12 @@ class AudioService { // 오디오 일시정지 상태 (앱 백그라운드 시) bool _isPaused = false; + // BGM 작업 진행 중 여부 (동시 호출 방지) + bool _isBgmBusy = false; + + // 대기 중인 BGM (작업 중 새 요청이 들어온 경우) + String? _queuedBgm; + // ───────────────────────────────────────────────────────────────────────── // 초기화 // ───────────────────────────────────────────────────────────────────────── @@ -202,16 +208,35 @@ class AudioService { // BGM 재생 // ───────────────────────────────────────────────────────────────────────── - /// BGM 재생 (단순화된 버전) + /// BGM 재생 (동시 호출 보호) /// /// 여러 곳에서 동시에 호출되어도 마지막 요청만 처리합니다. + /// 작업 중 새 요청이 들어오면 대기열에 저장하고 완료 후 재생합니다. Future playBgm(String name) async { if (_isPaused) return; if (!_staticInitialized) await init(); if (_currentBgm == name) return; if (_staticBgmPlayer == null) return; - await _playBgmInternal(name); + // 작업 중이면 대기열에 저장 (마지막 요청만 유지) + if (_isBgmBusy) { + _queuedBgm = name; + debugPrint('[AudioService] BGM $name queued'); + return; + } + + _isBgmBusy = true; + try { + await _playBgmInternal(name); + } finally { + _isBgmBusy = false; + // 대기 중인 BGM이 있으면 재생 + if (_queuedBgm != null && _queuedBgm != _currentBgm) { + final queued = _queuedBgm; + _queuedBgm = null; + await playBgm(queued!); + } + } } /// 내부 BGM 재생 (뮤텍스 내에서 호출) @@ -236,15 +261,23 @@ class AudioService { _userInteracted = true; debugPrint('[AudioService] Playing BGM: $name'); } on PlayerInterruptedException catch (e) { + // 다른 BGM 요청으로 인한 중단 - 정상적인 상황 debugPrint('[AudioService] BGM $name interrupted: ${e.message}'); } catch (e) { final errorStr = e.toString(); + + // "Loading interrupted"는 새 BGM 요청으로 인한 정상 중단 + if (errorStr.contains('Loading interrupted') || + errorStr.contains('abort')) { + debugPrint('[AudioService] BGM $name loading interrupted (new request)'); + return; // 플레이어 재생성 불필요 + } + debugPrint('[AudioService] BGM error: $errorStr'); // macOS Operation Stopped 에러: 플레이어 재생성 후 재시도 if (errorStr.contains('Operation Stopped') || - errorStr.contains('-11849') || - errorStr.contains('abort')) { + errorStr.contains('-11849')) { debugPrint('[AudioService] Recreating BGM player...'); await _recreateBgmPlayer();