127 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
//
 | 
						|
//  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()
 | 
						|
    }
 | 
						|
}
 |