在Swift中暂停和恢复计时器

时间:2019-05-05 05:54:00

标签: ios swift timer

我正在播放可能会暂停,恢复和停止的音频,我还有一个滑块可用于更改音频当前点的播放以及显示音频持续时间的标签,我想在以下情况下暂停计时器用户暂停音频,然后我阅读如果我希望我可以使计时器无效并取消计时器,然后再次启动它,但是它会从头开始播放音频的问题是,有办法在最后一点启动计时器它被暂停了吗?

func startTimer() {
        if replayTimer == nil {
            replayTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateSlider), userInfo: nil, repeats: true)
        }
    }

  @objc func updateSlider() {
        progressBar.value = Float(audio.audio!.currentTime)
    }



 @IBAction func playReceiverVoicenote(_ sender: Any) {
        if  replayTimer == nil {
            audioBtn.setImage(#imageLiteral(resourceName: "pause"), for: .normal)
            audio.playAudio(filePath: filePath!)
            startTimer()
            receiverProgressBar.maximumValue = audio.getAudioDuration()
        } else if audio.isAudioPlaying() {
            audioBtn.setImage(#imageLiteral(resourceName: "playAudio"), for: .normal)
            audio.pauseAudio()
            replayTimer?.invalidate()
            replayTimer = nil
        } else {
            audioBtn.setImage(#imageLiteral(resourceName: "pause"), for: .normal)
            audio.replayAudio()
            startTimer()
        }
    }


   func playAudio(filePath:URL){
        do {
            audio = try AVAudioPlayer(contentsOf: filePath)
            audio!.delegate  = self
            audio!.prepareToPlay()
            audio!.volume = 1.0
            audio!.play()
        } catch {
            print(error.localizedDescription)
        }
    }

    func pauseAudio() {
        audio!.pause()
    }

    func replayAudio() {
        audio!.play()
    }

    func stopAudio() {
        audio!.stop()
    }     

2 个答案:

答案 0 :(得分:1)

  • 当音频要暂停时,将audio.currentTime保存在变量中并使计时器无效。
  • 当音频要恢复时,获取保存的currentTime,在时间间隔内致电play(atTime:)并重新启动计时器

答案 1 :(得分:0)

您还可以通过以下方式使用此音频管理器:

let player = AudioPlayer()
player.loadAudio(url: URL(string: "myAudioUrl.mp3")!, name: "", img: "")

按钮的播放和暂停操作:

if player.isPlaying {
    player.pauseAudio()
} else {
    player.playAudio { isFinish, player, currentTimeInSec, remainingTimeInSec in

        if isFinish {
            // Audio finish to play
        }
    }
}

谁在块关闭中返回:

  • isFinish:布尔// //音频播放完毕
  • player:AVAudioPlayer //播放器
  • currentTimeInSec:Int //音频播放的当前时间(以秒为单位)
  • remainingTimeInsec:Int //剩余时间

AudioPlayer:

import Foundation
import AVFoundation
import MediaPlayer

class AudioPlayer {
    var audioPlayer: AVAudioPlayer?
    var hasBeenPaused = false
    var songName = ""
    var songImage = ""
    var timer: Timer?

    var isPlaying: Bool {
        return audioPlayer?.isPlaying ?? false
    }

    public func loadAudio(url: URL, name: String, img: String) {
        songName = name
        songImage = img

        setupRemoteTransportControls()

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.prepareToPlay()

            let audioSession = AVAudioSession.sharedInstance()

            do {
                try audioSession.setCategory(AVAudioSession.Category.playback, mode: .default)
            } catch let sessionError {
                print(sessionError)
            }
        } catch let songPlayerError {
            print(songPlayerError)
        }
    }

    public func playAudio(completion: ((_ isFinish: Bool, _ player: AVAudioPlayer, _ currentTimeInSec: Int, _ restTimeInSec: Int) -> ())? = nil) {
        guard let audioPlayer = audioPlayer else  { return }

        audioPlayer.play()
        setupNowPlaying()

        if timer == nil {
            timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
                let currentTime = Int(audioPlayer.currentTime)
                let remainingTime = Int(audioPlayer.duration) - Int(currentTime)

                if remainingTime == 0 {
                    completion?(true, audioPlayer, currentTime, remainingTime)
                    if self.timer != nil {
                        self.timer!.invalidate()
                        self.timer = nil
                    }
                } else {
                    completion?(false, audioPlayer, currentTime, remainingTime)
                }
            }
        }
    }

    public func pauseAudio() {
        guard let audioPlayer = audioPlayer else  { return }

        if audioPlayer.isPlaying {
            audioPlayer.pause()
            hasBeenPaused = true
        } else {
            hasBeenPaused = false
        }

        setupNowPlaying()

        if timer != nil {
            timer!.invalidate()
            timer = nil
        }
    }

    public func replayAudio() {
        guard let audioPlayer = audioPlayer else  { return }

        if audioPlayer.isPlaying || hasBeenPaused {
            audioPlayer.stop()
            audioPlayer.currentTime = 0
            audioPlayer.play()
        } else {
            audioPlayer.play()
        }

        setupNowPlaying()
    }

    public func stopAudio() {
        guard let audioPlayer = audioPlayer else  { return }

        audioPlayer.stop()
        setupNowPlaying()

        if timer != nil {
            timer!.invalidate()
            timer = nil
        }
    }

    func setupRemoteTransportControls() {
        let commandCenter = MPRemoteCommandCenter.shared()

        commandCenter.previousTrackCommand.isEnabled = false
        commandCenter.nextTrackCommand.isEnabled = false
        commandCenter.skipBackwardCommand.isEnabled = false
        commandCenter.skipForwardCommand.isEnabled = false

        commandCenter.playCommand.isEnabled = true
        commandCenter.playCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            //Update your button here for the play command
            self.playAudio()
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updatedControlCenterAudio"), object: nil)
            return .success
        }

        commandCenter.pauseCommand.isEnabled = true
        commandCenter.pauseCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            //Update your button here for the pause command
            self.pauseAudio()
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updatedControlCenterAudio"), object: nil)
            return .success
        }
    }

    func setupNowPlaying() {
        guard let audioPlayer = audioPlayer else  { return }

        var nowPlayingInfo = [String: Any]()
        nowPlayingInfo[MPMediaItemPropertyTitle] = songName

        if let image = UIImage(named: songImage) {
            nowPlayingInfo[MPMediaItemPropertyArtwork] =
                    MPMediaItemArtwork(boundsSize: image.size) { size in
                        return image
                    }
        }

        nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = audioPlayer.currentTime
        nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = audioPlayer.duration
        nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = audioPlayer.rate

        // Set the metadata
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }

}