我的屏幕上有3个不同的按钮。轻按Button1时,将调用AVQueuePlayer。轻按Button2或Button3时,将调用AVAudioPlayer。

轻按Button1(启动AVQueuePlayer),然后轻按Button2或Button3(启动AVAudioPlayer)时,就会出现问题。结果是,AVQueuePlayer当前正在播放的音频文件和AVAudioPlayer正在正在播放的音频文件同时播放。

我正在寻找一种方法,以防止在AVQueuePlayer处于活动状态时点按Button2或Button3,或者如果用户单击Button2或Button3,则让AVQueuePlayer停止播放。

我发现只使用一个播放器就可以解决这个问题,而不是使用两个播放器,但是我不知道如何解决。

        var queue = AVQueuePlayer()
        var items = [AVPlayerItem]()

        override func viewDidLoad() {
        super.viewDidLoad()

        let asset1 = AVPlayerItem(url: url1)
        let asset2 = AVPlayerItem(url: url2)
        let asset3 = AVPlayerItem(url: url3)


        items = [asset1, asset2, asset3, asset4]

        queue = AVQueuePlayer(items: items)

    for item in queue.items() {
        NotificationCenter.default.addObserver(self, selector:#selector(playerItemDidReachEnd(notification:)),
           name: .AVPlayerItemDidPlayToEndTime, object: item)
    }
}

    @IBAction func pushButton1(_ sender: UIButton) {
        sender.isSelected = true
        queue.play()
    }

    @IBAction func pushButton2(sender: UIButton) {
        if self.lonelyPlayer == nil {

        }else {
            if (self.lonelyPlayer?.isPlaying)! {
                self.lonelyPlayer?.stop()
            }
        }
        audioPlayer(url: url1, buttonId: 1)    }

    @IBAction func pushButton3(sender: UIButton) {
        if self.lonelyPlayer == nil {

        }else {
            if (self.lonelyPlayer?.isPlaying)! {
                self.lonelyPlayer?.stop()
            }
        }
        audioPlayer(url: url2, buttonId: 2)
        }

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if (self.currentPlayer == 1) {
            yourButton2.isSelected = false
        } else if (self.currentPlayer == 2) {
            yourButton3.isSelected = false
        }
}

    func playerItemDidReachEnd(notification: NSNotification) {

        if notification.object as? AVPlayerItem == items[0] {
            yourButton1.isSelected = false
            yourButton2.isSelected = true
        }

        if notification.object as? AVPlayerItem == items[1] {
            yourButton2.isSelected = false
            yourButton3.isSelected = true
        }

    func audioPlayer(url: URL, buttonId: Int) {
        do {
            try lonelyPlayer = AVAudioPlayer(contentsOf:url)
            lonelyPlayer!.play()
            lonelyPlayer!.delegate = self
            yourButton2.isSelected = (buttonId == 1)
            yourButton3.isSelected = (buttonId == 2)
            currentPlayer = buttonId
        } catch {
            print(error)
        }
    }

最佳答案

var queue = AVQueuePlayer()
var items = [AVPlayerItem]()
var currentlyPlaying = 0
var isPlaying = false {
    didSet{
        checkButtons()
    }
}

@IBOutlet weak var button1 : UIButton? //connect to button 1
@IBOutlet weak var button2 : UIButton? //connect to button 2
@IBOutlet weak var button3 : UIButton? //connect to button 3

override func viewDidLoad() {
    super.viewDidLoad()

    let asset1 = AVPlayerItem(url: url1)
    let asset2 = AVPlayerItem(url: url2)
    let asset3 = AVPlayerItem(url: url3)


    items = [asset1, asset2, asset3, asset4]

    queue = AVQueuePlayer(items: items)

    for item in queue.items() {
        NotificationCenter.default.addObserver(self, selector:#selector(playerItemDidReachEnd(notification:)), name: .AVPlayerItemDidPlayToEndTime, object: item)
    }
}

@IBAction func pushButton1(_ sender: UIButton) {
    self.currentlyPlaying = 1
    self.isPlaying = true
    sender.isSelected = true
    queue.play()
}

@IBAction func pushButton2(sender: UIButton) {
    self.currentlyPlaying = 2
    self.isPlaying = true
    if self.lonelyPlayer == nil {

    }else {
        if (self.lonelyPlayer?.isPlaying)! {
            self.lonelyPlayer?.stop()
        }
    }
    audioPlayer(url: url1, buttonId: 1)
}

@IBAction func pushButton3(sender: UIButton) {
    self.currentlyPlaying = 3
    self.isPlaying = true
    if self.lonelyPlayer == nil {

    }else {
        if (self.lonelyPlayer?.isPlaying)! {
            self.lonelyPlayer?.stop()
        }
    }
    audioPlayer(url: url2, buttonId: 2)
}

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    if (self.currentPlayer == 1) {
        yourButton2.isSelected = false
    } else if (self.currentPlayer == 2) {
        yourButton3.isSelected = false
    }
    self.isPlaying = false
}

func playerItemDidReachEnd(notification: NSNotification) {

    if notification.object as? AVPlayerItem == items[0] {
        yourButton1.isSelected = false
        yourButton2.isSelected = true
    }

    if notification.object as? AVPlayerItem == items[1] {
        yourButton2.isSelected = false
        yourButton3.isSelected = true
    }
    self.isPlaying = false
)

func audioPlayer(url: URL, buttonId: Int) {
    do {
        try lonelyPlayer = AVAudioPlayer(contentsOf:url)
        lonelyPlayer!.play()
        lonelyPlayer!.delegate = self
        yourButton2.isSelected = (buttonId == 1)
        yourButton3.isSelected = (buttonId == 2)
        currentPlayer = buttonId
    } catch {
        print(error)
    }
}

func checkButtons() {
    if isPlaying {
        switch currentlyPlaying {
        case 1:
            button2.isEnabled = false
            button3.isEnabled = false
        case 2:
            button1.isEnabled = false
            button3.isEnabled = false
        case 3:
            button1.isEnabled = false
            button2.isEnabled = false
        default:
            print("Something went wrong!")
        }
   } else {
        button1.isEnabled = true
        button2.isEnabled = true
        button3.isEnabled = true
   }
}


播放时禁用按钮。

注意:此代码未经测试,因为我正在总线上编写它

编辑:您可以将queue设置为可选,然后使用queue.pause然后queue = nil停止它。在再次使用之前,请记住重新分配它!

关于ios - 同时调用AVQueuePlayer和AVAudioPlayer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42391938/

10-14 19:55