Resume sound playing inside app

release
Laurent 3 years ago
parent 2eb0232bf7
commit 5305066e36
  1. 2
      LeCountdown.xcodeproj/project.pbxproj
  2. 29
      LeCountdown/Conductor.swift
  3. 20
      LeCountdown/LeCountdownApp.swift
  4. 8
      LeCountdown/Sound/Sound.swift
  5. 28
      LeCountdown/Sound/SoundPlayer.swift

@ -66,6 +66,7 @@
C4F8B1552988751B005C86A5 /* DialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8B1542988751B005C86A5 /* DialView.swift */; };
C4F8B15729891271005C86A5 /* Conductor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8B15629891271005C86A5 /* Conductor.swift */; };
C4F8B15929891528005C86A5 /* forest_stream.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C4F8B15829891528005C86A5 /* forest_stream.mp3 */; };
C4F8B15B29892D40005C86A5 /* SoundPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C445FA8E2987B83B0054D761 /* SoundPlayer.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -626,6 +627,7 @@
C438C8162982BE1E00BF3EF9 /* LeCountdown.xcdatamodeld in Sources */,
C438C8152982BD9000BF3EF9 /* IntentDataProvider.swift in Sources */,
C438C7DF2981216300BF3EF9 /* LaunchWidget.intentdefinition in Sources */,
C4F8B15B29892D40005C86A5 /* SoundPlayer.swift in Sources */,
C438C7E82981255D00BF3EF9 /* TimeInterval+Extensions.swift in Sources */,
C438C7D82981216200BF3EF9 /* LaunchWidgetLiveActivity.swift in Sources */,
C438C8192982BFDB00BF3EF9 /* NSManagedContext+Extensions.swift in Sources */,

@ -12,6 +12,8 @@ class Conductor : ObservableObject {
static let maestro: Conductor = Conductor()
var soundPlayer: SoundPlayer? = nil
@UserDefault(Key.dates.rawValue, defaultValue: [:]) static var savedDates: [String : DateInterval]
init() {
@ -38,7 +40,7 @@ class Conductor : ObservableObject {
}
func notifyUser(countdownId: String, cancel: Bool) {
// self._playSound(countdownId: countdownId)
self._playSound(countdownId: countdownId)
endCountdown(countdownId: countdownId, cancel: cancel)
}
@ -49,6 +51,7 @@ class Conductor : ObservableObject {
}
self.notificationDates.removeValue(forKey: countdownId)
// self._updateLiveActivity(countdownId: countdownId, endDate: <#T##Date#>)
self._endLiveActivity(countdownId: countdownId)
}
}
@ -74,7 +77,31 @@ class Conductor : ObservableObject {
}
}
}
// MARK: - Sound
fileprivate func _playSound(countdownId: String) {
let countdown = PersistenceController.shared.container.viewContext.object(stringId: countdownId) as? Countdown
let coolSound = countdown?.coolSound ?? Sound.allCases[0]
do {
let soundFile = try coolSound.soundFile()
let soundPlayer = SoundPlayer()
self.soundPlayer = soundPlayer
try soundPlayer.playSound(soundFile: soundFile, repeats: countdown?.repeats ?? true)
} catch {
print("error = \(error)")
// TODO: manage error
}
}
func stopSoundIfNecessary() {
self.soundPlayer?.stop()
}
// MARK: - Live Activity
fileprivate func _launchLiveActivity(countdown: Countdown, endDate: Date) {

@ -32,16 +32,16 @@ struct LeCountdownApp: App {
}
fileprivate func _onAppear() {
Task {
for s in Sound.allCases {
do {
let d = try await s.duration()
print("\(s) duration = \(d)")
} catch {
print("error = \(error)")
}
}
}
// Task {
// for s in Sound.allCases {
// do {
// let d = try await s.duration()
// print("\(s) duration = \(d)")
// } catch {
// print("error = \(error)")
// }
// }
// }
}
}

@ -49,11 +49,9 @@ enum Sound : Int, CaseIterable, Identifiable {
}
// var soundFile: SoundFile {
// switch self {
// case .trainhorn: return SoundFile(filename: "train_horn", fileExtension: "mp3")
// }
// }
func soundFile() throws -> SoundFile {
return try SoundFile(fullName: self.soundName)
}
func duration() async throws -> TimeInterval {

@ -9,9 +9,20 @@ import Foundation
import AVFoundation
struct SoundFile {
var filename: String
var fileExtension: String
init(fullName: String) throws {
let components = fullName.components(separatedBy: ".")
if components.count == 2 {
self.filename = components[0]
self.fileExtension = components[1]
} else {
throw SoundPlayerError.badFileName(name: fullName)
}
}
var url: URL? {
return Bundle.main.url(forResource: self.filename, withExtension: self.fileExtension)
}
@ -19,6 +30,7 @@ struct SoundFile {
enum SoundPlayerError : Error {
case missingResourceError(file: SoundFile)
case badFileName(name: String)
}
class SoundPlayer {
@ -30,9 +42,9 @@ class SoundPlayer {
throw SoundPlayerError.missingResourceError(file: soundFile)
}
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setActive(true)
// let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
// try audioSession.setCategory(.playback)
// try audioSession.setActive(true)
_player = try AVAudioPlayer(contentsOf: url)
_player?.prepareToPlay()
@ -40,11 +52,11 @@ class SoundPlayer {
_player?.numberOfLoops = loopCount
_player?.volume = 1.0
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.allowBluetooth, .defaultToSpeaker])
} catch {
print("audioSession error = \(error)")
}
// do {
// try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.allowBluetooth, .defaultToSpeaker])
// } catch {
// print("audioSession error = \(error)")
// }
_player?.play()

Loading…
Cancel
Save