I want my App to play music the first time the play Button is played, after that it should swap the Button Image to pause. It doesn't refresh instantly but only after the Song is being played already and I press the play Button again 2 times.
@State var isPlaying: Bool = false
@StateObject var musicPlayerVM: MusicPlayerViewModel
@StateObject var audioManager = AudioManager()
Button() {
if isPlaying == false {
audioManager.startPlayer(track: musicPlayerVM.song.track)
isPlaying = true
} else {
audioManager.playPause()
}
} label: {
Image(systemName: audioManager.isPlaying ? "pause" : "play.fill")
.resizable()
.renderingMode(.template)
.foregroundColor(Color.white)
.frame(width: 19, height: 25)
}
final class AudioManager: ObservableObject {
var player: AVAudioPlayer?
@Published private(set) var isPlaying: Bool = false
func startPlayer(track: String) {
guard let url = Bundle.main.url(forResource: track, withExtension: "mp3") else {return}
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch {
print("Failed to initialize player: ", error)
}
}
func playPause() {
guard let player = player else {
print("Instance of audio player not found")
return
}
if player.isPlaying {
player.pause()
isPlaying = false
} else {
player.play()
isPlaying = true
}
}
}
```
CodePudding user response:
You need to set isPlaying
to true
inside of your AudioManager
class when you first start the player.
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url)
player?.play()
isPlaying = true // here
} catch {
print("Failed to initialize player: ", error)
}
Your isPlaying
in your view has a different purpose than tracking pause status, so I suggest you give it a different name such as playerStarted
to avoid confusion.
A better idea is to use an enum
to give your AudioManager
3 states: .stopped
, .playing
, and .paused
and use it as the single source of truth.