ios 如何实现AVAudioplayer的delegate方法来自动播放下一首歌曲?

pu3pd22g  于 2023-04-13  发布在  iOS
关注(0)|答案(1)|浏览(112)

我在stackoverflow上看了很多类似的问题,虽然它们很有用,但我仍然不能在当前播放的歌曲结束时自动播放下一首歌曲。因为我从位置0开始播放歌曲数组,当我递增这个位置变量时,所有的歌曲不是应该一首接一首地播放,直到我到达数组中的最后一首歌曲吗?目前,在第一首歌曲结束播放后,第二首歌曲播放,其余的不播放。所以我的代码一次只能播放两首歌曲,一首接一首。我最初在configureUI()方法中设置歌曲,并尝试在底部的AVAudioplayer委托方法中增加歌曲。我感谢任何见解。

//
//  PLayerViewController.swift
//  Maanso
//
//

import UIKit
import AVFoundation

class PLayerViewController: UIViewController, AVAudioPlayerDelegate {
    @IBOutlet var holder: UIView!
    var Git = UILabel()
    var gabayArray = [Gabays]()
    var currentIndex = 0
    var position: Int = 0
    
    var player: AVAudioPlayer?
    
    //user interface elements
    var coverImageView: UIImageView!
    var gabayName: UILabel!
    var gabyaaName: UILabel!
    
    //buttons
    var playPauseButton: UIButton!
    var backButton: UIButton!
    var forwardButton: UIButton!

    
    var timer: Timer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
        player!.delegate = self
        
//        configureUI()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        if let player = player {
//            player.play()
            player.prepareToPlay()
        }
    }
    
    
    override func viewDidLayoutSubviews() {
        if holder.subviews.count == 0 {
            configure()
        }
    }

    
    func configure() {
        //set up player
        
        let gabay = gabayArray[position]
//        let urlString = Bundle.main.path(forResource: gabay.gabayName, ofType: "mp3")
        let urlString = Bundle.main.path(forResource: gabay.gabayName, ofType: "mp3")

        
        do {
            try AVAudioSession.sharedInstance().setMode(.default)
            try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
            
            guard let urlString = urlString else{return}
            
            player = try AVAudioPlayer(contentsOf: URL(string: urlString)!)
            guard let player = player else{return}
            player.volume = 0.5
            player.play()
            
        }
        
        catch{
            print("error is: \(error.localizedDescription)")
        }
       configureUI()

    }
    
    
    //MARK: - actions
    @objc func volumeSliderChanged(_ slider: UISlider) {
        let value = slider.value
        //adjust player volume
        guard let player = player else{return}
        player.volume = value
       
    }
    
    
    @objc func playPauseButtonTapped(_ slider: UISlider) {
       
       
        
        guard let player = player else{return}
        
        if player.isPlaying {
            player.stop()
            playPauseButton.setBackgroundImage(UIImage(systemName: "play.fill"), for: .normal)
           
        }else{
            player.play()
            playPauseButton.setBackgroundImage(UIImage(systemName: "pause.fill"), for: .normal)

           
        }
      
        
        
    }
    
        
            
        @objc func backButtonTapped() {
        if position > 0
        {
            position = position - 1
            player!.stop()
            for subview in holder.subviews {
                subview.removeFromSuperview()
            }
            configure()
//            configureUI()
        }
    }
    
    
    @objc func forwardButtonTapped() {
        if position < gabayArray.count - 1{
            position = position + 1
            player!.stop()
            
            for subview in holder.subviews {
                subview.removeFromSuperview()
            }
            configure()
//            configureUI()
        }
    }
    
    @objc func seekSliderChanged(_ slider: UISlider) {
        let slider = slider
//        let currentTime = player!.currentTime
        let duration = player!.duration
        slider.maximumValue = Float(duration)
        let time = duration/duration
        //seeking through current gabay
        player!.currentTime = TimeInterval(slider.value)
       
//        player!.play()
        Timer.scheduledTimer(withTimeInterval: Double(time), repeats: true, block: {
            _ in
            slider.value = Float(self.player!.currentTime)
            //TRYING TO MAKE THE SLIDER BE IN SYNC WITH song
           
            
        })
        
      
    }
    
    
    
  public  func configureUI() {
        
        //set up user interface
        let gabay = gabayArray[position]

        //set up imagecoverview
        coverImageView = UIImageView()
        coverImageView.contentMode = .scaleAspectFill
        coverImageView.image = UIImage(named: gabay.imageName)
        coverImageView.translatesAutoresizingMaskIntoConstraints = false
        holder.addSubview(coverImageView)

        
        //set up the two labels
        gabayName = UILabel()
        gabayName.textAlignment = .center
        gabayName.numberOfLines = 0
        gabayName.translatesAutoresizingMaskIntoConstraints = false
        gabayName.text = gabay.gabayName
        gabayName.font = UIFont(name: "helvetica", size: 20)
        holder.addSubview(gabayName)
        
        gabyaaName = UILabel()
        gabyaaName.translatesAutoresizingMaskIntoConstraints = false
        gabyaaName.text = gabay.gabyaaName
        gabyaaName.font = UIFont(name: "helvetica", size: 18)
        gabyaaName.textAlignment = .center
        gabyaaName.numberOfLines = 0
        holder.addSubview(gabyaaName)

        
        
        //set up sliders.
        let volumeSlider = UISlider()
        volumeSlider.value = 0.5
        volumeSlider.translatesAutoresizingMaskIntoConstraints = false
        volumeSlider.addTarget(self, action: #selector(volumeSliderChanged), for: .valueChanged)
        volumeSlider.layer.cornerRadius = 8
        volumeSlider.isUserInteractionEnabled = true
        holder.addSubview(volumeSlider)
      
      //seek through sider
      let seekSlider = UISlider()
//      seekSlider.isContinuous = true
      seekSlider.minimumValue = 0
//      seekSlider.maximumValue = Float(player!.duration)
      seekSlider.isUserInteractionEnabled = true
      seekSlider.translatesAutoresizingMaskIntoConstraints = false
//      seekSlider.setThumbImage(UIImage(systemName: "thumbSmall"), for: .normal)
      seekSlider.setThumbImage(UIImage(named: "thumb"), for: .normal)
      seekSlider.addTarget(self, action: #selector(seekSliderChanged), for: .valueChanged)
      holder.addSubview(seekSlider)
        
        
        
        //set up buttons, play button
        playPauseButton = UIButton()
        playPauseButton.tintColor = .black
        playPauseButton.setBackgroundImage(UIImage(systemName: "pause.fill"), for: .normal)
        playPauseButton.translatesAutoresizingMaskIntoConstraints = false
        playPauseButton.addTarget(self, action: #selector(playPauseButtonTapped), for: .touchUpInside)
        holder.addSubview(playPauseButton)
        
        //back button
        backButton = UIButton()
        backButton.tintColor = .black
        backButton.setBackgroundImage(UIImage(systemName: "backward.fill"), for: .normal)
        backButton.translatesAutoresizingMaskIntoConstraints = false
        backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
        holder.addSubview(backButton)
        
        //forward button
         forwardButton = UIButton()
       
        forwardButton.tintColor = .black
        forwardButton.setBackgroundImage(UIImage(systemName: "forward.fill"), for: .normal)
        forwardButton.translatesAutoresizingMaskIntoConstraints = false
        forwardButton.addTarget(self, action: #selector(forwardButtonTapped), for: .touchUpInside)
        holder.addSubview(forwardButton)
      
      //volume buttons
   
      let rightVolButton = UIButton()
      rightVolButton.translatesAutoresizingMaskIntoConstraints = false
      rightVolButton.setBackgroundImage(UIImage(systemName: "volume.3.fill"), for: .normal)
      holder.addSubview(rightVolButton)

        
        

        //set up constraints
        NSLayoutConstraint.activate([
            coverImageView.topAnchor.constraint(equalTo: holder.layoutMarginsGuide.topAnchor, constant: 80),
            coverImageView.leadingAnchor.constraint(equalTo: holder.layoutMarginsGuide.leadingAnchor, constant: 0),
            coverImageView.trailingAnchor.constraint(equalTo: holder.layoutMarginsGuide.trailingAnchor, constant: 0),

            
            gabayName.topAnchor.constraint(equalTo: coverImageView.bottomAnchor, constant: 100),
            gabayName.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
          

            gabyaaName.topAnchor.constraint(equalTo: gabayName.bottomAnchor, constant: 15),
            gabyaaName.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
            
            
            //seek slider
            seekSlider.topAnchor.constraint(equalTo: gabyaaName.topAnchor, constant: 30),
            seekSlider.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
            seekSlider.widthAnchor.constraint(equalTo: holder.widthAnchor, multiplier: 0.8),
            

           
            
            //buttons
            playPauseButton.topAnchor.constraint(equalTo: seekSlider.bottomAnchor, constant: 25),
            playPauseButton.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
            playPauseButton.widthAnchor.constraint(equalToConstant: 70),
            playPauseButton.heightAnchor.constraint(equalToConstant: 70),

            
            backButton.topAnchor.constraint(equalTo: seekSlider.bottomAnchor, constant: 25),
            backButton.leadingAnchor.constraint(equalTo: holder.leadingAnchor, constant: 20),
            backButton.widthAnchor.constraint(equalToConstant: 70),
            backButton.heightAnchor.constraint(equalToConstant: 70),

            
            forwardButton.topAnchor.constraint(equalTo: seekSlider.bottomAnchor, constant: 25),
            forwardButton.trailingAnchor.constraint(equalTo: holder.trailingAnchor, constant: -20),
            forwardButton.widthAnchor.constraint(equalToConstant: 70),
            forwardButton.heightAnchor.constraint(equalToConstant: 70),

            
            
            //volume slider
            volumeSlider.topAnchor.constraint(equalTo: playPauseButton.bottomAnchor, constant: 30),
            volumeSlider.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
            volumeSlider.widthAnchor.constraint(equalTo: holder.widthAnchor, multiplier: 0.8),

            
           
            
            rightVolButton.topAnchor.constraint(equalTo: playPauseButton.bottomAnchor, constant: 35),
            rightVolButton.trailingAnchor.constraint(equalTo: holder.layoutMarginsGuide.trailingAnchor, constant: 0),

            
            
            
            

                
        ])
        
    
    }
    
    
  //MARK: - AVAudioplayer delegate
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if flag, position < gabayArray.count - 1 {
            position = position + 1

            for subview in holder.subviews{
                subview.removeFromSuperview()
            }
            configure()

        }

        }
      
       
    
    
  
   
    override func viewWillDisappear(_ animated: Bool) {
        player?.stop()
    }
    
    
    

   
        
        }
b4lqfgs4

b4lqfgs41#

我能够解决这个问题,只需在最初加载音乐文件后设置播放器的代理。
1.使用AVAudioPlayer委托方法跟踪当前播放的歌曲何时结束。

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {}

1.在该方法中,检查当前播放的歌曲是否不是数组中的最后一首歌曲,如果不是,则递增增量变量。
1.调用初始配置音频的方法。对我来说,它是configure()方法。加载音频文件后,不要忘记在此方法中设置音频的委托。

相关问题