在后台播放音频时,在iOS中使Avplayer产生噪音

时间:2020-07-06 07:15:59

标签: ios swift xcode background avplayer

我从服务器获取多个mp3网址,并在tableview中显示它们。并使用AVPlayer播放它们,效果很好。

但是在进入背景时,音频会中断并产生巨大的噪音。 同样,在向前/向后拖动滑块时,它会跳动。

我的代码是

  override func viewDidLoad() {
        super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil)

  let session:AVAudioSession = AVAudioSession.sharedInstance()
        do {
            try session.setCategory(AVAudioSession.Category.playback)
        }
        catch {
            print("Background Play Error")
        }
        UIApplication.shared.beginReceivingRemoteControlEvents()
}

@objc func didEnterBackgroundNotification(){
            self.playAudio()
    }

 // Player
    func playerSetup(url:String) {
        do {
            let audioURL = url
            avPlayerItem = AVPlayerItem( url:NSURL( string:audioURL )! as URL )
            avPlayer = AVPlayer(playerItem:avPlayerItem)
            avPlayer?.rate = 1.0
            avPlayer?.play()
            self.showProgressHub()
            self.sliderSetup()
            self.timeObserverSetup()
        }
    }
    
    /* ----------------------------------------------------
     Avplayer Observer timer setup
     ------------------------------------------------------ */
    func timeObserverSetup() {
        let interval = CMTime(seconds: 0.05, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        timeObserver = avPlayer!.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { [weak self] elapsedTime in
            print("observer running")
            self!.updateSlider(elapsedTime: elapsedTime)
        })
    }

 /* ----------------------------------------------------
     update slider with avplayer duration
     ------------------------------------------------------ */
    func updateSlider(elapsedTime: CMTime) {
        let playerDuration = playerItemDuration()
        if CMTIME_IS_INVALID(playerDuration) {
            slider.minimumValue = 0.0
            return
        }
        let duration = Float(CMTimeGetSeconds(playerDuration))
        if duration.isFinite && duration > 0 {
            slider.minimumValue = 0.0
            slider.maximumValue = duration
            let time = Float(CMTimeGetSeconds(elapsedTime))
            slider.setValue(time, animated: true)
        }
    }
    
    /* ----------------------------------------------------
     avplayeritem duration
     ------------------------------------------------------ */
    private func playerItemDuration() -> CMTime {
        let thePlayerItem = avPlayer?.currentItem
        if thePlayerItem?.status == .readyToPlay {
            return thePlayerItem!.duration
        }
        return CMTime.invalid
    }
    
    
    /* ----------------------------------------------------
     Slider setup
     ------------------------------------------------------ */
    func sliderSetup() {
        DispatchQueue.global(qos: .background).async {
            let duration : CMTime = self.avPlayerItem!.asset.duration
            let seconds : Float64 = CMTimeGetSeconds(duration)
            DispatchQueue.main.async {
                self.slider!.maximumValue = Float(seconds)
            }
        }
        slider.isContinuous = false
        slider!.minimumValue = 0
        slider.addTarget(self, action: #selector(PodcastsViewController.playbackSliderValueChanged(_:event:)), for: .valueChanged)
    }
    
    /* ----------------------------------------------------
     Slider Action
     ------------------------------------------------------ */
    @objc func playbackSliderValueChanged(_ playbackSlider:UISlider, event: UIEvent) {
        let seconds : Int64 = Int64(self.slider.value)
        let targetTime:CMTime = CMTimeMake(value: seconds, timescale: 1)
        self.avPlayer!.seek(to: targetTime)
        
        if let touchEvent = event.allTouches?.first {
            switch touchEvent.phase {
            case .began:
                self.avPlayer?.removeTimeObserver(self.timeObserver as Any)
                self.pauseAudio()
                break
                
            case .moved:
                break
                
            case .ended:
                self.timeObserverSetup()
                self.playAudio()
                break
                
            default:
                break
            }
        }
        
    }

而且我已经在plist中启用了音频的背景模式

我正在使用当前的iOS 13.3模拟器

该如何解决?

enter image description here

0 个答案:

没有答案