1
votes

Adding New Items To AVQueuePlayer Doesn't Play

I have scenarios where I'm streaming HLS audios from server. Initially I make an Array of AVPlayerItem. And initialise the AVQueuePlayer, And on button clicks it plays initial items very fine. But down the road when half of my items finishes playing I am trying to add more items at the end of list which doesn't play.

class ViewController: UIViewController, AVAudioPlayerDelegate{

let baseUrl = "********"

var player: AVQueuePlayer?
var items: [AVPlayerItem] = [];

let controller = AVPlayerViewController()

var counter = 0;

override func viewDidLoad() {
    super.viewDidLoad()
    
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(animationDidFinish(_:)),
                                           name: .AVPlayerItemDidPlayToEndTime,
                                           object: player?.items())
}

override func viewDidAppear(_ animated: Bool) {
    queueMaker()
}

@IBAction func btnTapped(_ sender: UIButton) {

    let player = AVQueuePlayer(items: self.items)
    let playerLayer = AVPlayerLayer(player: player)
    self.view.layer.addSublayer(playerLayer)
    player.play()    
}

@objc func animationDidFinish(_ notification: NSNotification) {
    print("HLS : AVQueuePlayer Item Finished Playing")
    counter += 1
    if ((items.count) - counter) < 4 {
        print("HLS : Adding More Items")
        addMoreItemsToQueue()
    }
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

func queueMaker() {
    
    let listOfAyahs: [String] = ["1/1.m3u8","2/2.m3u8","3/3.m3u8","4/4.m3u8","5/5.m3u8","6/6.m3u8","7/7.m3u8"]
    
    for item in listOfAyahs {
        let stringUrl = "\(self.baseUrl)\(item)"
        let url = URL(string: stringUrl)
        let item = AVPlayerItem(url: url!)
        items.append(item)
    }
}


func addMoreItemsToQueue() {
    
    let listOfAyahs: [String] = ["8/8.m3u8","9/9.m3u8","10/10.m3u8","11/11.m3u8","12/12.m3u8","13/13.m3u8","14/14.m3u8"]

    for item in listOfAyahs {
        let stringUrl = "\(self.baseUrl)\(item)"
        let url = URL(string: stringUrl)
        let item = AVPlayerItem(url: url!)
        items.append(item)
    }
  }
}    
1

1 Answers

2
votes

You are initialising a AVQuePlayer with some items which is the base copy for the AVQuePlayer and later you are appending new AVPlayerItems to your items array, about which the AVQuePlayer is not aware of. So, update the following to function and it should work.

@IBAction func btnTapped(_ sender: UIButton) {
    // UPDATE THE PLAYER's SCOPE TO GLOBAL
    player = AVQueuePlayer(items: self.items)
    let playerLayer = AVPlayerLayer(player: player)
    self.view.layer.addSublayer(playerLayer)
    player?.play()
}

And add replace insert items to the queue like this

func addMoreItemsToQueue() {

  let listOfAyahs: [String] = ["8/8.m3u8","9/9.m3u8","10/10.m3u8","11/11.m3u8","12/12.m3u8","13/13.m3u8","14/14.m3u8"]

  var lastItem = self.player?.items().last
  for item in listOfAyahs {
        let stringUrl = "\(self.baseUrl)\(item)"
        let url = URL(string: stringUrl)
        let item = AVPlayerItem(url: url!)
        self.player?.insert(item, after: lastItem)
        lastItem = item
    }
}

Try and share the results.