// // AuditionSoundManager.swift // SodaLive // // Created by klaus on 1/7/25. // import Foundation import AVKit import Combine class AuditionSoundManager: NSObject, ObservableObject { static let shared = AuditionSoundManager() @Published private (set) var isPlaying = false @Published var isLoading = false @Published var errorMessage = "" @Published var isShowPopup = false @Published var currentTime: Double = 0.0 @Published private (set) var duration: Double = 0.0 private var player: AVAudioPlayer! private var timer: Timer? @Published private (set) var applicantId = -1 func resetPlayer() { stop() } func playOrPause(applicantId: Int, url: String) { if applicantId <= 0 { stop() } if self.applicantId != applicantId { stop() setupPlayer(with: url) self.applicantId = applicantId } else { if !isPlaying { player?.play() isPlaying = player?.isPlaying ?? false startTimer() } else { player?.pause() isPlaying = player?.isPlaying ?? false stopTimer() } } } private func stop() { stopTimer() isPlaying = false isLoading = false player?.stop() player?.currentTime = 0 currentTime = 0.0 duration = 0.0 applicantId = -1 } private func setupPlayer(with url: String) { guard let url = URL(string: url) else { self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요." self.isShowPopup = true return } isLoading = true URLSession.shared.dataTask(with: url) { [unowned self] data, response, error in guard let audioData = data else { self.isLoading = false return } do { self.player = try AVAudioPlayer(data: audioData) DispatchQueue.main.async { self.player?.volume = 1 self.player?.delegate = self self.player?.prepareToPlay() self.player?.play() self.duration = self.player?.duration ?? 0.0 self.isPlaying = self.player.isPlaying self.isLoading = false self.startTimer() } } catch { DispatchQueue.main.async { self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요." self.isShowPopup = true self.isLoading = false } } }.resume() } private func startTimer() { stopTimer() // 기존 타이머 제거 timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in self?.updateCurrentTime() } } // 타이머 정지 private func stopTimer() { timer?.invalidate() timer = nil } private func updateCurrentTime() { guard let audioPlayer = player else { return } currentTime = audioPlayer.currentTime } } extension AuditionSoundManager: AVAudioPlayerDelegate { func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { stop() } }