UISlider to control AVAudioPlayer

后端 未结 4 1146
执笔经年
执笔经年 2020-12-01 03:40

I\'m trying to implement a little function in my app. I am currently playing sounds as AVAudioPlayers and that works fine. What I would like to add is to control the sound\'

4条回答
  •  余生分开走
    2020-12-01 04:25

    Problems that I've faced during playing an audio file and show start/end time and controlling the song with the UISlider.

    1. Not playing audio directly without downloading it in temp folder.
    2. UISlider got crashed on main thread in lower iOS version i.e 12.4/13.1
    3. Smooth Scrolling of UISlider.
    4. Calculating and updating the start/end time of the song.

    This answer needs some editing, but it will work without any doubt.

      //UISlider init
      lazy var slider: UISlider = {
        let progress = UISlider()
        progress.minimumValue = 0.0
        progress.maximumValue = 100.0
        progress.tintColor = UIColor.init(named: "ApplicationColor")
        return progress
    
    }()
    
     var audioPlayer : AVAudioPlayer?
       //First I've downloaded the audio and then playing it.
      override func viewWillAppear(_ animated: Bool) {
    
        super.viewWillAppear(animated)
    
    
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(trackAudio), userInfo: nil, repeats: true)
    
        if let audioURLString = audioURL{
            let urlstring = URL(string: audioURLString)!
            downloadFromURL(url: urlstring) { (localURL, response, error) in
                if let localURL = localURL{
                    self.playAudioFile(url: localURL)
                }
    
            }
        }
    }
    
     override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        stopTimer()
    }
    
    
    // Stop TimeInterval After View disappear
    func stopTimer() {
        if timer != nil {
            timer?.invalidate()
            audioPlayer?.stop()
            audioPlayer = nil
            timer = nil
        }
    }
    @objc func sliderSelected(_ sender : UISlider){
    
        if audioPlayer != nil{
            if !isPlaying{
                self.audioPlayer?.play()
                playButton.setImage(UIImage.init(named: "AudioPause"), for: .normal)
                isPlaying = true
            }else{
                self.audioPlayer?.currentTime = TimeInterval(Float(sender.value) * Float(self.audioPlayer!.duration) / 100.0)
                if (sender.value / 100.0 == 1.0){
    
                    //Do something if audio ends while dragging the UISlider.
    
                }
            }
    
    
        }
    
    }
     func downloadFromURL(url:URL,completion: @escaping((_ downladedURL: URL?,_ response :URLResponse?,_ error: Error?) -> Void)){
        var downloadTask:URLSessionDownloadTask
        downloadTask = URLSession.shared.downloadTask(with: url) {(URL, response, error) in
            if let url = URL{
                completion(url,nil,nil)
            }else if let response = response{
                completion(nil,response,nil)
            }
            if let error = error{
                completion(nil,nil,error)
            }
    
    
        }
    
        downloadTask.resume()
    }
    
    
    func playAudioFile(url:URL){
        do{
    
            self.audioPlayer = try AVAudioPlayer(contentsOf: url)
            self.audioPlayer?.prepareToPlay()
            self.audioPlayer?.delegate = self
            self.audioPlayer?.play()
    
       let audioDuration = audioPlayer?.duration
            let audioDurationSeconds = audioDuration
            minutes = Int(audioDurationSeconds!/60);
            seconds =  Int(audioDurationSeconds!.truncatingRemainder(dividingBy: 60))
        } catch{
            print("AVAudioPlayer init failed")
        }
    }
    
    @objc func trackAudio() {
    
        if audioPlayer != nil{
            DispatchQueue.main.async {
                print("HI")
                let normalizedTime = Float(self.audioPlayer!.currentTime * 100.0 / self.audioPlayer!.duration)
                self.slider.setValue(normalizedTime, animated: true)
                let currentTime = self.audioPlayer?.currentTime
                self.currentMinutes = Int(currentTime!/60);
                self.currentSeconds =  Int(currentTime!.truncatingRemainder(dividingBy: 60))
                self.startTimeLabel.text =  String(format: "%02i:%02i", self.currentMinutes, self.currentSeconds)
                self.endTimeLabel.text = String(format: "%02i:%02i", self.minutes, self.seconds)
            }
        }
    
    
    
    
    
    }
    

提交回复
热议问题