오디션 - 오디오 재생기능 추가
This commit is contained in:
		
							
								
								
									
										126
									
								
								SodaLive/Sources/Audition/Detail/AuditionSoundManager.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								SodaLive/Sources/Audition/Detail/AuditionSoundManager.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
//
 | 
			
		||||
//  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()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user