|
|
|
|
@ -34,12 +34,49 @@ enum SoundPlayerError : Error { |
|
|
|
|
case playReturnedFalse |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@objc class SoundPlayer: NSObject, AVAudioPlayerDelegate { |
|
|
|
|
@objc class SoundPlayer: NSObject, AVAudioPlayerDelegate, ObservableObject { |
|
|
|
|
|
|
|
|
|
fileprivate var _player: AVAudioPlayer? |
|
|
|
|
|
|
|
|
|
fileprivate var _timer: Timer? = nil |
|
|
|
|
|
|
|
|
|
@Published var currentFileName: String? = nil |
|
|
|
|
|
|
|
|
|
func playSound(_ sound: Sound) throws { |
|
|
|
|
try self._playSound(sound) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func playSound(_ sound: Sound, duration: TimeInterval) throws { |
|
|
|
|
try self._playSound(sound, duration: duration) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _playSound(_ sound: Sound, duration: TimeInterval? = nil) throws { |
|
|
|
|
try self.playOrPauseSound(sound.fileName, duration: duration) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func playOrPauseSound(_ file: String, duration: TimeInterval? = nil) throws { |
|
|
|
|
|
|
|
|
|
if file == self.currentFileName { |
|
|
|
|
if self._player?.isPlaying ?? false { |
|
|
|
|
self._player?.stop() |
|
|
|
|
self.currentFileName = nil |
|
|
|
|
} else { |
|
|
|
|
self._player?.play() |
|
|
|
|
self.currentFileName = file |
|
|
|
|
} |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.currentFileName = file |
|
|
|
|
self._player?.stop() |
|
|
|
|
let soundFile = try SoundFile(fullName: file) |
|
|
|
|
if let duration { |
|
|
|
|
try self.play(soundFile: soundFile, for: duration) |
|
|
|
|
} else { |
|
|
|
|
try self.playSound(soundFile: soundFile) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func play(soundFile: SoundFile, for duration: TimeInterval) throws { |
|
|
|
|
try self.playSound(soundFile: soundFile) |
|
|
|
|
self._timer = Timer(timeInterval: duration, repeats: false, block: { _ in |
|
|
|
|
@ -51,10 +88,6 @@ enum SoundPlayerError : Error { |
|
|
|
|
guard let url = soundFile.url else { |
|
|
|
|
throw SoundPlayerError.missingResourceError(file: soundFile) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// let audioSession: AVAudioSession = AVAudioSession.sharedInstance() |
|
|
|
|
// try audioSession.setCategory(.playback) |
|
|
|
|
// try audioSession.setActive(true) |
|
|
|
|
|
|
|
|
|
let player = try AVAudioPlayer(contentsOf: url) |
|
|
|
|
player.prepareToPlay() |
|
|
|
|
@ -63,19 +96,23 @@ enum SoundPlayerError : Error { |
|
|
|
|
|
|
|
|
|
self._player = player |
|
|
|
|
|
|
|
|
|
// Logger.log("Plays \(url) on player: \(String(describing: self._player))") |
|
|
|
|
// Logger.log("SoundPlayer > .deviceCurrentTime = \(player.deviceCurrentTime)") |
|
|
|
|
player.play() |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func stop() { |
|
|
|
|
self._player?.stop() |
|
|
|
|
self.currentFileName = nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// func isSoundPlaying(_ sound: Sound) -> Bool { |
|
|
|
|
// return sound.fileName == self.currentFileName && (self._player?.isPlaying ?? false) |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
// MARK: - Delegate |
|
|
|
|
|
|
|
|
|
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { |
|
|
|
|
self.currentFileName = nil |
|
|
|
|
Conductor.maestro.deactivateAudioSessionIfPossible() |
|
|
|
|
self.stop() |
|
|
|
|
} |
|
|
|
|
|