SodaLive
Preview Content
Resources
Sources
Agora
App
Common
Content
Debug
Dialog
Explorer
Extensions
Follow
Font
IAP
ImagePicker
Keyboard
Live
Main
Message
SelectRecipient
Text
Voice
Write
GetVoiceMessageResponse.swift
SoundManager.swift
VoiceMessageItemView.swift
VoiceMessageView.swift
VoiceMessageViewModel.swift
KeepMessageRequest.swift
MessageApi.swift
MessageFilterTab.swift
MessageFilterTabView.swift
MessageRepository.swift
MessageView.swift
MessageViewModel.swift
SendMessageRequest.swift
MyPage
NavigationBar
Onboarding
Report
Settings
Shape
Splash
User
Utils
ContentView.swift
SodaLive.entitlements
SodaLive.xcworkspace
generated
.gitignore
Podfile
Podfile.lock
SodaLive-dev.entitlements
model-SodaLive-dev.json
model-SodaLive.json
165 lines
4.7 KiB
Swift
165 lines
4.7 KiB
Swift
//
|
|
// 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()
|
|
}
|
|
}
|