Таймер приостановки и возобновления в Swift - PullRequest
0 голосов
/ 05 мая 2019

Я играю аудио, которое можно приостанавливать, возобновлять и останавливать. У меня также есть ползунок, который можно использовать для изменения воспроизведения текущей звуковой точки, и метка, показывающая продолжительность звука, и я хочу приостановить таймер, когдапользователь приостанавливает звук, и я читаю. Если я хочу, чтобы я мог сделать недействительным и обнулить таймер, затем запустить его снова, но проблема в том, что он будет воспроизводить звук с самого начала, есть способ запустить таймер в последней точкеэто было приостановлено?

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 ]

1 голос
/ 05 мая 2019
  • Когда звук будет приостановлен, сохраните audio.currentTime в переменной и сделайте таймер недействительным.
  • Когда звук возобновится, получите сохраненный currentTime, позвоните play(atTime:), пропустив временной интервал, и перезапустите таймер
0 голосов
/ 05 мая 2019

Вы также можете использовать этот Audio Manager следующим образом:

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: Bool // Если воспроизведение звука закончилось
  • проигрыватель: AVAudioPlayer // проигрыватель
  • currentTimeInSec: Int // Текущее время в секундах воспроизведения звука
  • Остальное ВремяИнсек: 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
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...