메시지 - 리스트, 쓰기, 상세 페이지 추가
This commit is contained in:
164
SodaLive/Sources/Message/Voice/SoundManager.swift
Normal file
164
SodaLive/Sources/Message/Voice/SoundManager.swift
Normal file
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// SoundManager.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/08/10.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AVKit
|
||||
|
||||
class SoundManager: NSObject, ObservableObject {
|
||||
@Published var errorMessage = ""
|
||||
@Published var isShowPopup = false
|
||||
@Published var isLoading = false
|
||||
@Published var onClose = false
|
||||
|
||||
@Published var isPlaying = false
|
||||
@Published var isRecording = false
|
||||
@Published var duration: TimeInterval = 0
|
||||
|
||||
var player: AVAudioPlayer!
|
||||
var audioRecorder: AVAudioRecorder!
|
||||
|
||||
var startTimer: (() -> Void)?
|
||||
var stopTimer: (() -> Void)?
|
||||
|
||||
func prepareRecording() {
|
||||
isLoading = true
|
||||
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try audioSession.setCategory(.playAndRecord, mode: .default)
|
||||
try audioSession.setActive(true)
|
||||
audioSession.requestRecordPermission() { [weak self] allowed in
|
||||
DispatchQueue.main.async {
|
||||
if !allowed {
|
||||
self?.errorMessage = "권한을 허용하지 않으시면 음성메시지 서비스를 이용하실 수 없습니다."
|
||||
self?.isShowPopup = true
|
||||
self?.onClose = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
|
||||
isShowPopup = true
|
||||
onClose = true
|
||||
}
|
||||
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
func startRecording() {
|
||||
let settings = [
|
||||
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
|
||||
AVSampleRateKey: 12000,
|
||||
AVNumberOfChannelsKey: 1,
|
||||
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
|
||||
]
|
||||
|
||||
do {
|
||||
audioRecorder = try AVAudioRecorder(url: getAudioFileURL(), settings: settings)
|
||||
audioRecorder.record()
|
||||
|
||||
if let startTimer = startTimer {
|
||||
startTimer()
|
||||
}
|
||||
isRecording = true
|
||||
} catch {
|
||||
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
|
||||
isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
func stopRecording() {
|
||||
audioRecorder.stop()
|
||||
audioRecorder = nil
|
||||
isRecording = false
|
||||
|
||||
if let stopTimer = stopTimer {
|
||||
stopTimer()
|
||||
}
|
||||
|
||||
prepareForPlay()
|
||||
}
|
||||
|
||||
func getRecorderCurrentTime() -> TimeInterval {
|
||||
return audioRecorder.currentTime
|
||||
}
|
||||
|
||||
func prepareForPlay(_ url: URL? = nil) {
|
||||
isLoading = true
|
||||
|
||||
DispatchQueue.main.async {
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try audioSession.setCategory(.playback, mode: .default)
|
||||
|
||||
if let url = url {
|
||||
self.player = try AVAudioPlayer(data: Data(contentsOf: url))
|
||||
} else {
|
||||
self.player = try AVAudioPlayer(contentsOf: self.getAudioFileURL())
|
||||
}
|
||||
|
||||
self.player?.volume = 1
|
||||
self.player?.delegate = self
|
||||
self.player?.prepareToPlay()
|
||||
|
||||
self.duration = self.player.duration
|
||||
} catch {
|
||||
self.errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
|
||||
self.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
func playAudio() {
|
||||
player?.play()
|
||||
|
||||
isPlaying = player.isPlaying
|
||||
if let startTimer = startTimer {
|
||||
startTimer()
|
||||
}
|
||||
}
|
||||
|
||||
func stopAudio() {
|
||||
player.stop()
|
||||
player.currentTime = 0
|
||||
isPlaying = player.isPlaying
|
||||
if let stopTimer = stopTimer {
|
||||
stopTimer()
|
||||
}
|
||||
}
|
||||
|
||||
func getPlayerCurrentTime() -> TimeInterval {
|
||||
return player.currentTime
|
||||
}
|
||||
|
||||
func deleteAudioFile() {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: getAudioFileURL())
|
||||
duration = 0
|
||||
} catch {
|
||||
errorMessage = "오류가 발생했습니다. 다시 시도해 주세요."
|
||||
isShowPopup = true
|
||||
}
|
||||
}
|
||||
|
||||
func getAudioFileURL() -> URL {
|
||||
return getDocumentsDirectory().appendingPathComponent("recording.m4a")
|
||||
}
|
||||
|
||||
private func getDocumentsDirectory() -> URL {
|
||||
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
|
||||
return paths[0]
|
||||
}
|
||||
}
|
||||
|
||||
extension SoundManager: AVAudioPlayerDelegate {
|
||||
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
|
||||
stopAudio()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user