You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.5 KiB
85 lines
2.5 KiB
//
|
|
// DelaySoundPlayer.swift
|
|
// LeCountdown
|
|
//
|
|
// Created by Laurent Morvillier on 08/03/2023.
|
|
//
|
|
|
|
import Foundation
|
|
import AVFoundation
|
|
|
|
@objc class DelaySoundPlayer: NSObject, AVAudioPlayerDelegate {
|
|
|
|
fileprivate var _player: AVAudioPlayer
|
|
|
|
// fileprivate var _playerId: String
|
|
|
|
fileprivate var _timer: Timer? = nil
|
|
|
|
init(sound: Sound) throws {
|
|
// self._playerId = playerId
|
|
|
|
let soundFile = try sound.soundFile()
|
|
|
|
guard let url = soundFile.url else {
|
|
throw SoundPlayerError.missingResourceError(file: soundFile)
|
|
}
|
|
|
|
self._player = try AVAudioPlayer(contentsOf: url)
|
|
}
|
|
|
|
func restore(for playDate: Date) throws {
|
|
let timeLeft = playDate.timeIntervalSinceNow
|
|
try self._play(in: timeLeft)
|
|
}
|
|
|
|
func start(in duration: TimeInterval) throws {
|
|
try self._play(in: duration)
|
|
}
|
|
|
|
fileprivate func _play(in duration: TimeInterval) throws {
|
|
|
|
Conductor.maestro.activateAudioSession()
|
|
|
|
self._player.prepareToPlay()
|
|
self._player.volume = 1.0
|
|
self._player.delegate = self
|
|
// self._player.numberOfLoops = repeatCount
|
|
|
|
// Logger.log("self._player.deviceCurrentTime = \(self._player.deviceCurrentTime)")
|
|
let time: TimeInterval = self._player.deviceCurrentTime + duration
|
|
let result = self._player.play(atTime: time)
|
|
FileLogger.log("play \(String(describing: self._player.url)) >atTime: \(time.timeFormatted), result = \(result), isMainThread = \(Thread.isMainThread)")
|
|
|
|
if !result {
|
|
throw SoundPlayerError.playReturnedFalse
|
|
}
|
|
}
|
|
|
|
func stop() {
|
|
self._player.stop()
|
|
FileLogger.log("Player stopped")
|
|
}
|
|
|
|
// MARK: - Delegate
|
|
|
|
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
|
|
FileLogger.log("audioPlayerDidFinishPlaying: successfully = \(flag), player volume = \(player.volume)")
|
|
|
|
Logger.log("audioPlayerDidFinishPlaying: successfully = \(flag)")
|
|
Conductor.maestro.cleanupLiveActivities()
|
|
|
|
self.stop()
|
|
}
|
|
|
|
fileprivate func _activateAudioSession() {
|
|
do {
|
|
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
|
|
try audioSession.setCategory(.playback, options: .duckOthers)
|
|
try audioSession.setActive(true)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
|
|
}
|
|
|