【问题标题】:Updating slider value in real time AVAudioPlayer SwiftUI实时更新滑块值 AVAudioPlayer SwiftUI
【发布时间】:2020-08-09 08:39:03
【问题描述】:

所以我有一个名为音频设置的类,如下所示:

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 的任何想法。

谢谢。

【问题讨论】:

    标签: ios swiftui slider avfoundation avaudioplayer


    【解决方案1】:

    这里是固定代码。使用 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()
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-28
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多