因此,我有一个名为“音频设置”的类,如下所示:
class audioSettings: ObservableObject {
var audioPlayer: AVAudioPlayer?
var playing = false
var playValue: TimeInterval = 0.0
var playerDuration: TimeInterval = 146
var timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
func playSound(sound: String, type: String) {
if let path = Bundle.main.path(forResource: sound, ofType: type) {
do {
if playing == false {
if (audioPlayer == nil) {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.prepareToPlay()
audioPlayer?.play()
playing = true
}
}
if playing == false {
audioPlayer?.play()
playing = true
}
} catch {
print("Could not find and play the sound file.")
}
}
}
func stopSound() {
// if playing == true {
audioPlayer?.stop()
audioPlayer = nil
playing = false
playValue = 0.0
// }
}
func pauseSound() {
if playing == true {
audioPlayer?.pause()
playing = false
}
}
func changeSliderValue() {
if playing == true {
pauseSound()
audioPlayer?.currentTime = playValue
}
if playing == false {
audioPlayer?.play()
playing = true
}
}
}
当我在视图中实现代码时,播放文件就成功了。我成功停止了它,并且成功移动了滑块并在音频中获得了新的位置。我正在努力的工作是使滑块在音频播放时实时更新。如果我点击播放,则在我暂停之前,滑块将不起作用。此时它将移动到正确的位置。
这是视图代码:
struct myExperienceFearChunk: View {
@ObservedObject var audiosettings = audioSettings()
var body: some View {
HStack {
Button(action: {
if (self.playButton == Image(systemName: "play.circle")) {
print("All Done")
self.audiosettings.playSound(sound: "audio file", type: "mp3")
self.audiosettings.timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
self.playButton = Image(systemName: "pause.circle")
} else {
self.audiosettings.pauseSound()
self.playButton = Image(systemName: "play.circle")
}
}) {
self.playButton
.foregroundColor(Color.white)
.font(.system(size: 44))
}
Button(action: {
print("All Done")
self.audiosettings.stopSound()
self.playButton = Image(systemName: "play.circle")
self.audiosettings.playValue = 0.0
}) {
self.stopButton
.foregroundColor(Color.white)
.font(.system(size: 44))
}
}
Slider(value: $audiosettings.playValue, in: TimeInterval(0.0)...audiosettings.playerDuration, onEditingChanged: { _ in
self.audiosettings.changeSliderValue()
})
.onReceive(audiosettings.timer) { _ in
if self.audiosettings.playing {
if let currentTime = self.audiosettings.audioPlayer?.currentTime {
self.audiosettings.playValue = currentTime
if currentTime == TimeInterval(0.0) {
self.audiosettings.playing = false
}
}
}
else {
self.audiosettings.playing = false
self.audiosettings.timer.upstream.connect().cancel()
}
}
}
}
}
我知道.onReceive是从我按下暂停时开始更新滑块的位置,因为没有它,除非拖动它,否则滑块不会更新。关于如何在音频播放时更新滑块的任何想法,请设置playValue。
谢谢。
最佳答案
这是固定代码。经过Xcode 11.4 / iOS 13.4测试
修复的主要内容是发布@Published var playValue
,以便在观察到对象时有机会通知audioSettings
的变化,从而更新Slider
…其他是次要的。
class audioSettings: ObservableObject {
var audioPlayer: AVAudioPlayer?
var playing = false
@Published var playValue: TimeInterval = 0.0
var playerDuration: TimeInterval = 146
var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
func playSound(sound: String, type: String) {
if let path = Bundle.main.path(forResource: sound, ofType: type) {
do {
if playing == false {
if (audioPlayer == nil) {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.prepareToPlay()
audioPlayer?.play()
playing = true
}
}
if playing == false {
audioPlayer?.play()
playing = true
}
} catch {
print("Could not find and play the sound file.")
}
}
}
func stopSound() {
// if playing == true {
audioPlayer?.stop()
audioPlayer = nil
playing = false
playValue = 0.0
// }
}
func pauseSound() {
if playing == true {
audioPlayer?.pause()
playing = false
}
}
func changeSliderValue() {
if playing == true {
pauseSound()
audioPlayer?.currentTime = playValue
}
if playing == false {
audioPlayer?.play()
playing = true
}
}
}
struct myExperienceFearChunk: View {
@ObservedObject var audiosettings = audioSettings()
@State private var playButton: Image = Image(systemName: "play.circle")
var body: some View {
VStack {
HStack {
Button(action: {
if (self.playButton == Image(systemName: "play.circle")) {
print("All Done")
self.audiosettings.playSound(sound: "filename", type: "wav")
self.audiosettings.timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
self.playButton = Image(systemName: "pause.circle")
} else {
self.audiosettings.pauseSound()
self.playButton = Image(systemName: "play.circle")
}
}) {
self.playButton
.foregroundColor(Color.white)
.font(.system(size: 44))
}
Button(action: {
print("All Done")
self.audiosettings.stopSound()
self.playButton = Image(systemName: "play.circle")
self.audiosettings.playValue = 0.0
}) {
Image(systemName: "stop.circle")
.foregroundColor(Color.white)
.font(.system(size: 44))
}
}
Slider(value: $audiosettings.playValue, in: TimeInterval(0.0)...audiosettings.playerDuration, onEditingChanged: { _ in
self.audiosettings.changeSliderValue()
})
.onReceive(audiosettings.timer) { _ in
if self.audiosettings.playing {
if let currentTime = self.audiosettings.audioPlayer?.currentTime {
self.audiosettings.playValue = currentTime
if currentTime == TimeInterval(0.0) {
self.audiosettings.playing = false
}
}
}
else {
self.audiosettings.playing = false
self.audiosettings.timer.upstream.connect().cancel()
}
}
}
}
}
关于ios - 实时更新滑块值AVAudioPlayer SwiftUI,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63324235/