AVQueuePlayer 不会停止播放

Posted

技术标签:

【中文标题】AVQueuePlayer 不会停止播放【英文标题】:AVQueuePlayer won’t stop playing 【发布时间】:2020-06-17 03:59:52 【问题描述】:

如果一个人按下按钮 10 次,那么他们将听到 10 个不同的歌曲列表连续播放。我希望如果一个人按 10 次,他们只会听一个歌曲列表。我基本上是在尝试创建一个重置按钮。

var myQueuePlayer: AVQueuePlayer?
var avItems: [AVPlayerItem] = []


func audio () 

    var items: [String] = ["one", "two", "three", "four", "five"]
    items.shuffle()

    for clip in items 
        guard let url = Bundle.main.url(forResource: clip, withExtension: ".mp3") else 
            // mp3 file not found in bundle - so crash!
            fatalError("Could not load \(clip).mp3")
        
        avItems.append(AVPlayerItem(url: url))
        //button.isHidden = true
        



@IBAction func didTapButton() 

    audio()
    if myQueuePlayer == nil    
        // instantiate the AVQueuePlayer with all avItems
        myQueuePlayer = AVQueuePlayer(items: avItems)

     else 
        // stop the player and remove all avItems
        myQueuePlayer?.removeAllItems()
        // add all avItems back to the player

        avItems.forEach 
                myQueuePlayer?.insert($0, after: nil)
            
    
    // seek to .zero (in case we added items back in)
    myQueuePlayer?.seek(to: .zero)
    // start playing
    myQueuePlayer?.play()    

【问题讨论】:

你停止播放器的部分在哪里? @matt 我试图在任何地方阻止它,但这并不能解决问题。问题似乎是当我重新添加 avItems 时,如果一个人按下按钮 10 次,那么 avItems 将被添加 10 次。我花了一天半的时间试图从不同的角度解决它,但始终无法解决。 @LeoDabus 我已经尝试在外面声明它,但问题仍然存在。 @YumelHernandez 我的错,他们不一样 所以你基本上是说removeAllItems什么都不做? 【参考方案1】:

这是一个非常简单的例子。

这假设您的包中有 5 个 .mp3 文件和 4 个按钮:

播放/重启 暂停 简历 随机播放

连接到@IBAction funcs:

class TestAVQueuViewController: UIViewController 

    var myQueuePlayer: AVQueuePlayer?

    var avItemsArray: [AVPlayerItem] = []

    override func viewDidLoad() 
        super.viewDidLoad()

        // assuming I have 5 .mp3 files in the bundle, named:
        let mySongs: [String] = [
            "clip1", "clip2", "clip3", "clip4", "clip5",
        ]

        // build the array of URLs for the song files
        for clip in mySongs 
            if let url = Bundle.main.url(forResource: clip, withExtension: ".mp3") 
                avItemsArray.append(AVPlayerItem(url: url))
             else 
                print("Could not get URL for \(clip).mp3")
            
        
        if avItemsArray.count == 0 
            fatalError("Failed to get URL for ANY songs!")
        

    

    func playQueue() -> Void 

        // if first time
        if myQueuePlayer == nil 
            // instantiate the AVQueuePlayer
            myQueuePlayer = AVQueuePlayer()
        

        guard let player = myQueuePlayer else 
            // I suppose it's possible that AVQueuePlayer() failed to instantiate
            //  so print a message to debug console and return
            print("AVQueuePlayer failed to instantiate!")
            return
        

        // this will make sure the player is stopped and remove any remaining avItems
        player.removeAllItems()

        // every time this is called,
        //  loop through and reset the time on each avItem
        for item in avItemsArray 
            item.seek(to: .zero, completionHandler: nil)
        

        // add avItems to the player
        avItemsArray.forEach 
            player.insert($0, after: nil)
        

        // start playing
        player.play()
    

    @IBAction func playRestartTapped(_ sender: Any) 
        playQueue()
    

    @IBAction func pauseTapped(_ sender: Any) 
        guard let player = myQueuePlayer, player.items().count > 0 else 
            return
        
        player.pause()
    

    @IBAction func resumeTapped(_ sender: Any) 
        guard let player = myQueuePlayer, player.items().count > 0 else 
            return
        
        player.play()
    

    @IBAction func restartShuffledTapped(_ sender: Any) 
        // shuffle the items
        avItemsArray.shuffle()
        playQueue()
    


【讨论】:

所以我在每个项目之间添加了一个暂停,并希望它在后台播放,但它不允许我这样做。有转机吗?有什么方法可以真正做到这一点? (我问了一个关于这个的问题,但似乎没有人知道)。在此之后,我终于完成了这个应用程序! 我已经测试了很多东西,问题似乎是当我调用此通知以了解音频是否已完成播放时: NotificationCenter.default.addObserver(self, selector: #selector(self .playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: myQueauPlayer) 当这个被调用时,我调度队列几秒钟,这似乎是为什么音频无法运行的问题背景

以上是关于AVQueuePlayer 不会停止播放的主要内容,如果未能解决你的问题,请参考以下文章

AVQueuePlayer 不播放声音

Swift:在avqueueplayer中播放完毕后重播视频

播放/暂停/停止本地存储的多个音频文件

在 AVQueuePlayer 中播放完最后一项后如何显示工作表视图?

当 AVQueuePlayer 完成最后一个播放项时如何做某事

AVQueuePlayer - 在缓存项目时保持活动状态