Show volume view when starting a countdown

main
Laurent 3 years ago
parent b99fb2a59a
commit 6d49965b18
  1. 4
      LeCountdown.xcodeproj/project.pbxproj
  2. 20
      LeCountdown/Conductor.swift
  3. 4
      LeCountdown/CountdownScheduler.swift
  4. 25
      LeCountdown/Sound/DelaySoundPlayer.swift
  5. 8
      LeCountdown/Sound/SoundPlayer.swift
  6. 9
      LeCountdown/Views/ContentView.swift
  7. 30
      LeCountdown/Views/Reusable/VolumeView.swift

@ -163,6 +163,7 @@
C4E5D67429B88734008E7465 /* DelaySoundPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D67329B88734008E7465 /* DelaySoundPlayer.swift */; };
C4E5D67729B88BB5008E7465 /* DelaySoundPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D67329B88734008E7465 /* DelaySoundPlayer.swift */; };
C4E5D67829B88BB5008E7465 /* DelaySoundPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D67329B88734008E7465 /* DelaySoundPlayer.swift */; };
C4E5D67A29B8C5A1008E7465 /* VolumeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D67929B8C5A1008E7465 /* VolumeView.swift */; };
C4F8B1532987FE6F005C86A5 /* LaunchWidgetLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7D72981216200BF3EF9 /* LaunchWidgetLiveActivity.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 */; };
@ -375,6 +376,7 @@
C4E5D66E29B753D7008E7465 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AppShortcuts.strings; sourceTree = "<group>"; };
C4E5D67029B753DC008E7465 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AppShortcuts.strings; sourceTree = "<group>"; };
C4E5D67329B88734008E7465 /* DelaySoundPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelaySoundPlayer.swift; sourceTree = "<group>"; };
C4E5D67929B8C5A1008E7465 /* VolumeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeView.swift; sourceTree = "<group>"; };
C4F8B15629891271005C86A5 /* Conductor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conductor.swift; sourceTree = "<group>"; };
C4F8B15829891528005C86A5 /* forest_stream.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = forest_stream.mp3; sourceTree = "<group>"; };
C4F8B15E298961A7005C86A5 /* ReorderableForEach.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReorderableForEach.swift; sourceTree = "<group>"; };
@ -769,6 +771,7 @@
C473C33829ACDBD70056B38A /* TipView.swift */,
C4BA2B2E299E69A000CB4FBA /* View+Extension.swift */,
C4742B5E2984205000D5D950 /* ViewModifiers.swift */,
C4E5D67929B8C5A1008E7465 /* VolumeView.swift */,
);
path = Reusable;
sourceTree = "<group>";
@ -1005,6 +1008,7 @@
C4F8B1BF298ACA0B005C86A5 /* StopwatchDialView.swift in Sources */,
C438C807298195E600BF3EF9 /* Model+Extensions.swift in Sources */,
C4BA2B6829A3C4AC00CB4FBA /* Context+Calculations.swift in Sources */,
C4E5D67A29B8C5A1008E7465 /* VolumeView.swift in Sources */,
C4BA2B04299A42EF00CB4FBA /* NewDataView.swift in Sources */,
C4BA2B4C299FCE0C00CB4FBA /* Stopwatch+CoreDataProperties.swift in Sources */,
C4E5D67429B88734008E7465 /* DelaySoundPlayer.swift in Sources */,

@ -21,7 +21,8 @@ class Conductor: ObservableObject {
static let maestro: Conductor = Conductor()
@Published var soundPlayer: SoundPlayer? = nil
@Published var delaySoundPlayer: DelaySoundPlayer? = nil
var delaySoundPlayer: DelaySoundPlayer? = nil
@UserDefault(PreferenceKey.countdowns.rawValue, defaultValue: [:]) static var savedCountdowns: [String : DateInterval]
@UserDefault(PreferenceKey.stopwatches.rawValue, defaultValue: [:]) static var savedStopwatches: [String : Date]
@ -38,7 +39,7 @@ class Conductor: ObservableObject {
@Published var currentCountdowns: [String : DateInterval] = [:] {
didSet {
Conductor.savedCountdowns = currentCountdowns
Logger.log("**** currentCountdowns didSet, count = \(currentCountdowns.count)")
// Logger.log("**** currentCountdowns didSet, count = \(currentCountdowns.count)")
withAnimation {
self._buildLiveTimers()
}
@ -92,7 +93,7 @@ class Conductor: ObservableObject {
}
func notifyUser(countdownId: String) {
self._playSound(timerId: countdownId)
// self._playSound(timerId: countdownId)
self._endCountdown(countdownId: countdownId, cancel: false)
}
@ -123,12 +124,12 @@ class Conductor: ObservableObject {
let dateInterval = DateInterval(start: Date(), end: date)
self.currentCountdowns[countdown.stringId] = dateInterval
// self._launchLiveActivity(countdown: countdown, endDate: date)
// self._createTimerIntent(countdown)
Logger.log("countdowns count = \(self.currentCountdowns.count)")
// Logger.log("countdowns count = \(self.currentCountdowns.count)")
// }
}
@ -156,13 +157,18 @@ class Conductor: ObservableObject {
do {
let date = Date(timeIntervalSinceNow: countdown.duration)
let soundFile = try SoundFile(fullName: countdown.soundName)
self.delaySoundPlayer = DelaySoundPlayer(soundFile: soundFile)
try self.delaySoundPlayer?.start(in: countdown.duration,
self.playSound(countdown.someSound)
let soundPlayer = DelaySoundPlayer(soundFile: soundFile)
self.delaySoundPlayer = soundPlayer
try soundPlayer.start(in: countdown.duration,
repeatCount: Int(countdown.repeatCount))
self.startCountdown(date, countdown: countdown)
handler(.success(date))
} catch {
Logger.error(error)
handler(.failure(error))
}
}

@ -41,8 +41,8 @@ class CountdownScheduler {
print("Selected sound = \(sound)")
// content.sound = UNNotificationSound.criticalSoundNamed(UNNotificationSoundName(rawValue: sound), withAudioVolume: 1.0)
// content.interruptionLevel = .critical
// content.relevanceScore = 1.0
content.interruptionLevel = .critical
content.relevanceScore = 1.0
// let notificationCount = 1 + countdown.repeatCount

@ -25,18 +25,20 @@ import AVFoundation
}
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setCategory(.playback, options: .duckOthers)
try audioSession.setActive(true)
let player = try AVAudioPlayer(contentsOf: url)
_player = player
// MPMusicPlayerController.applicationMusicPlayer.volume = 1.0
_player?.prepareToPlay()
_player?.volume = 1.0
_player?.delegate = self
let player = try AVAudioPlayer(contentsOf: url)
player.prepareToPlay()
player.volume = 1.0
player.delegate = self
player.numberOfLoops = repeatCount
self._player = player
_player?.play(atTime: player.deviceCurrentTime + duration)
player.play(atTime: player.deviceCurrentTime + duration)
}
func stop() {
@ -46,6 +48,15 @@ import AVFoundation
// MARK: - Delegate
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
do {
self.stop()
try audioSession.setActive(false)
} catch {
Logger.error(error)
}
Logger.log("audioPlayerDidFinishPlaying: successfully = \(flag)")
}

@ -53,15 +53,9 @@ enum SoundPlayerError : Error {
_player?.volume = 1.0
_player?.delegate = self
// do {
// try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.allowBluetooth, .defaultToSpeaker])
// } catch {
// print("audioSession error = \(error)")
// }
Logger.log("Plays \(url) on player: \(String(describing: self._player))")
_player?.play()
}
func stop() {

@ -99,10 +99,19 @@ struct ContentView<T : AbstractTimer>: View {
// }.padding()
// }
Spacer()
SiriTipView(intent: StartTimerIntent(), isVisible: self.$siriTipShown)
.siriTipViewStyle(SiriTipViewStyle.dark).padding()
if !conductor.liveTimers.isEmpty {
HStack(alignment: .center) {
VolumeView().padding(12.0)
}.frame(width: 300.0, height: 40.0)
.background(Color(white: 0.9))
.cornerRadius(16.0)
LiveTimerListView()
.environment(\.managedObjectContext, viewContext)
.environmentObject(conductor)

@ -0,0 +1,30 @@
//
// VolumeView.swift
// LeCountdown
//
// Created by Laurent Morvillier on 08/03/2023.
//
import SwiftUI
import MediaPlayer
import UIKit
struct VolumeView: UIViewRepresentable {
func makeUIView(context: Context) -> MPVolumeView {
let volumeView = MPVolumeView(frame: .zero)
volumeView.showsLargeContentViewer = false
return volumeView
}
func updateUIView(_ view: MPVolumeView, context: Context) {
Logger.log("update volume view")
}
}
struct VolumeView_Previews: PreviewProvider {
static var previews: some View {
VolumeView()
}
}
Loading…
Cancel
Save